Anyone?

a | x |

Please log in or register to post a reply.

If someone could tell me if I’m barking up the wrong tree completely with this one (ie is this particular method workable when using noise3()), I’d be really grateful.

Thanks in advance,

a | x |

I just looked over it again, and noticed tonfilm mentions that this only works with a 2D input mesh to be offset by the noise, like a flat terrain.@tonfilm

Assuming the input mesh is a grid in the xy-plane

Also, you seem to be multiplying the resulting normal twice with gl_NormalMatrix.

Hi Kenneth Gorking!

Thanks very much for getting back to me.

Doh! I’ve been very silly… of course, this only works with parametric
surfaces, where, as you say, the input is a flat mesh…

The offsets I used to calculate ‘neighbours’ were on the X and Y axis, which of course failed to take into account the fact the original mesh is a sphere.

Soo… since the mesh is spherical, maybe if I calculate spherical coordinates for the vertices, then base the noise on rho, theta and phi values, rather than X, Y and Z coordinates, and calculate neighbours using offsets to two of the spherical coordinates, it may just work…

Thanks for the pointer!

I’ll let you know how it goes.

a | x |

Another way to do it, is to pass along the original normal of the mesh, and then create a new modified normal from the direction between the old and new vertex. Something like:

newNormal = normalize(orgNormal + normalize(newVertex - orgVertex));

Hi again.

@Kenneth Gorking

Ah, great suggestion! So simple, too…

Unfortunately, it doesn’t seem to work for me. I get the same jagged dark areas, and when I rotate the mesh relative to the light-source, the lighting behaves strangely- the light-source appears also to be moving, which is not the case if I use the original normal (though of course this is inaccurate after mesh distortion).

The screenshots below show the mesh rotated on the X axis, with the light-source in a constant position:

I’m sure there’s something basic I’m missing here.

Can you think of anything else I could try?

a | x |

@Kenneth Gorking

Yep, I removed the extra matrix-multiplication.

Swapping the order of the normal-calculation, as you suggested did make
a difference, but didn’t solve the problem, sadly.

Here is the Vertex Shader as it currently stands:

```
//
// vertexnoise.vert: Vertex shader for warping the geometry with noise.
//
// author: Philip Rideout
//
// Copyright (c) 2005-2006: 3Dlabs, Inc.
//
//
// See 3Dlabs-License.txt for license information
//
// Lighting + surface controls
uniform vec4 AmbientColor, DiffuseColor;
uniform vec3 LightPosition;
uniform vec4 SurfaceColor;
///////////////////////////
// Functions //
///////////////////////////
// Varying-type variable for lighting color, sent to Fragment Shader.
// Varyings are interpolated across polygons to give a smooth result in the FS.
varying vec4 outColor;
// Environment-Map function
void envMapVS(in vec4 vert, in vec3 norm)
{
vec4 vWorld = gl_ModelViewMatrix * vert;
vec3 nWorld = gl_NormalMatrix * norm;
// Diffuse light
vec3 vertToLight = normalize(LightPosition - vWorld.xyz);
float diffuseLight = max(dot(vertToLight, nWorld), 0.0);
// This varying variable is passed to the Fragment Shader
outColor = AmbientColor + vec4(diffuseLight * DiffuseColor.xyz, DiffuseColor.w);
// Environment mapping texture coordinates
vec3 vWorldUnit = normalize(vWorld.xyz);
vec3 f = reflect(vWorldUnit, nWorld);
float m = 2.0 * sqrt(f.x * f.x + f.y * f.y + (f.z + 1.0) * (f.z + 1.0));
// Texture coordinates set
// (determines which part of envMap to lookup in FS).
// Also automatically interpolated between VS and FS.
gl_TexCoord[0].xy = vec2(f.x / m + 0.5, -f.y / m + 0.5);
}
// 3D Noise controls
uniform vec3 Offset;
uniform float ScaleIn;
uniform float ScaleOut;
// 3D Noise function
vec4 noise3D(in vec4 vert, in vec3 gridOffset)
{
vert.xyz += noise3(gridOffset + Offset + vert.xyz * ScaleIn) * ScaleOut;
return vert;
}
// Structure to hold vertex position and normal
struct posNorm {vec4 pos;vec3 norm;};
// Calculate and return vertex position and normal
posNorm vNoise3D(in vec4 vert)
{
// Init output variable of custom type posNorm (defined above)
posNorm result;
// Calculate new vertex position using function defined above
result.pos = noise3D(vert, vec3(0.0));
// Calculate normals
result.norm = normalize(gl_Normal + normalize(vert.xyz - result.pos.xyz));
return result;
}
///////////////////////////
// Main Loop //
///////////////////////////
void main(void)
{
// Initial vertex position
vec4 vertex = gl_Vertex;
// get final vertex position and normals
posNorm outPut = vNoise3D(vertex);
// Call envMapVS function, passing it vertex position and normal
vec3 normal = gl_NormalMatrix * outPut.norm;
// Apply environment-map lighting function
envMapVS(vertex, normal);
gl_Position = gl_ModelViewProjectionMatrix * outPut.pos;
}
```

a | x |

Ah…

in that case, I think I’ll have to go back to the ‘neighbours’ method, but working in a Spherical coordinate system, as I mentioned above. Unfortunately, a GLSL compiler bug on my laptop prevents me from trying it at the moment, but I don’t see why it wouldn’t work, in theory…

I’ll keep you posted.

Thanks for all your help,

a | x |

- Upcoming Multiplatform Game Program...
- Our first game - looking for feedbacks
- Network Emulation Tool
- Trouble with accessing GLSL array
- Fiction
- Game Programming Patterns: Bytecode
- Interactive WebGL Water Demo
- Skeletal Animation Tutorial with GP...
- Unreal Engine 4
- Microsoft xbox one selling poorly

Hi,

I’m just trying to generate working normals in my simple Vertex Noise shader, and haven’t been having much success.

I’ve been using GLSLs builtin noise3() function, and the simple ‘neighbours’ technique outlined by tonfilm on his blog

http://tonfilm.blogspot.com/2007/01/calculate-normals-in-shader.html for normal-estimation.

Just wondering if anyone can offer any advice on where I might be going wrong, or tell me whether or not this technique is suitable for use in this particular case.

Here is my vertex shader, which applies noise to the vertex position using noise3(), calculates a normal (wrongly), changes the texture coords for a simple Envmap lookup in the Fragment Shader, and sets a varying variable for basic diffuse lighting:

I don’t think I need to post the Fragment Shader, as it’s very simple, and I think it’s the normal-estimation in the VS that’s the problem here.

The screenshots below show the result I’m getting (with the envmap effect turned off):

As you can see, some of the Normals are clearly ‘flipped’

Any advice on how I might solve this annoying issue much appreciated!

Thanks in advance,

http://machinesdontcare.wordpress.com