terrain normals

Started by
9 comments, last by kod 16 years ago
Hi, long time since I programmed game related stuff. Anyway I had some spare time and wrote up a heightmapping demo that uses glsl, splatting and per-pixel lighting. It works pretty good already but i have a VERY small problem with the normal calculation: The terrain is split up in triangles. Each iteration of the grid has 2 triangles. Now I go and calculate the normal like this:

  for(int c=0;c<m_totalTriangles;c++) {
	   CVector3 Triangle[3];

	   Triangle[0].x = m_vertex[i++];
	   Triangle[0].y = m_vertex[i++];
	   Triangle[0].z = m_vertex[i++];

	   Triangle[1].x = m_vertex[i++];
	   Triangle[1].y = m_vertex[i++];
	   Triangle[1].z = m_vertex[i++];

	   Triangle[2].x = m_vertex[i++];
	   Triangle[2].y = m_vertex[i++];
	   Triangle[2].z = m_vertex[i++];

	   CVector3 Normals[c] = Normal(Triangle);
   }

Each Triangle has a calculated normal, the face normal of this triangle is calulcated so:

CVector3 Normal(CVector3 vTriangle[])
{
	CVector3 vVector1 = Vector(vTriangle[2], vTriangle[0]);
	CVector3 vVector2 = Vector(vTriangle[1], vTriangle[0]);
	CVector3 vNormal = Cross(vVector1, vVector2);
	vNormal = Normalize(vNormal);
	return vNormal;	
}

Now to the problem: When I draw the normals using lines from the center of each triangle you already see something is wrong. In some Triangles the line goes up as it should and it others it faces downwards. I know its a problem coming from the cross product (right hand rule). But how do I fix it? My lighting calculation in the shader is right, but as you can see in this image, its just the same as above. Would be cool if anyone has an idea about how I can fix this :).
Advertisement
r u sure its the normals?
put the light under the ground, see if the other triangles get lit then

try a different winding order for the black triangles ie
instead of indice 0,1,2 use 0,2,1

also make sure u have
glEnable( GL_CULL_FACE );

thanks for your reply. I got it working! I had to invert the normal on odd triangle indexes. It was pretty simple. Just a check if the current index is odd or even, then invert the normal (*-1).

looks pretty cool now :). Its only face normals though, blocky on edges but hell, its fast at least. I have not figured out how to generate vertex normals for so many triangles/vertices. It will take ages :/.



:)
Hi,

"I have not figured out how to generate vertex normals for so many triangles/vertices. It will take ages :/."

You have to use some sort of spatial sorting. Sort all vertices by their distances from an arbitrary plane and use a fast lookup. This will result in an O(n * log n) algorithm (otherwise it would be O(n^2)).

BTW: Looks great your terrain ;)

Best regards,
Porthos
i guess that will produce a very good-looking result. Still im really interested in loading normal maps from a bitmap and mapping it on the terrain as normals. Im kind of curious how good that looks. It would at least be extremly fast.
I decided to get my hands dirty with normalmaps: Pro, its DAMN fast, looks almost as good as the surface normals (even better on edges). Artists can retouch it. Con: Most graphics cards only have 4 texture units, uploading the normalmap into the ps makes me loose one unit for splatting. But thats the only bad thing right now. I COULD load the image as pixels and upload each color of a pixel as a vertex normal, that already works but i have to tweak it.

some images:






This is a calculated normalmap, im not really sure if its 100% correct but i dont care as the result is pretty cool already.
The 4 texture unit limit you refer to are for the fixed functionality pipeline. In shaders we can access many more (32 AFAIR on NV8800).
>>I decided to get my hands dirty with normalmaps: Pro, its DAMN fast, looks almost as good as the surface normals

a normalmap should look much better.
eg with a 1024x1024 sized texture youre supplying >1million normals to do the shading, to get the same quality with a pervertex normal (like you were originally doing) u will need to tesselate the terrain so its >1 million vertices
Quote:Original post by ndhb
The 4 texture unit limit you refer to are for the fixed functionality pipeline. In shaders we can access many more (32 AFAIR on NV8800).


hmmmm one thing I didnt know! I'm working with a NV7600 at the moment. How do I access texture units >GL_TEXTURE3_ARB. Do I simply call GL_TEXTURE4_ARB? I have some experience with shaders but sometimes I'm really stuck with my old opengl wisdom ;).
nv7600 only has 16texture units (+ 8 texturecoord units)
just use
GL_TEXTURE6 (no need for the _ARB)

in the shader u have

uniform sampler2D tex6; // you will need to set this uniform to 6
vec4 color = texture2D( tex6, tc );

This topic is closed to new replies.

Advertisement