Sign in to follow this  
kod

terrain normals

Recommended Posts

kod    126
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 :).

Share this post


Link to post
Share on other sites
zedz    291
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 );

Share this post


Link to post
Share on other sites
kod    126
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 :/.



:)

Share this post


Link to post
Share on other sites
Porthos    210
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

Share this post


Link to post
Share on other sites
kod    126
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.

Share this post


Link to post
Share on other sites
kod    126
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.

Share this post


Link to post
Share on other sites
ndhb    246
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).

Share this post


Link to post
Share on other sites
zedz    291
>>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

Share this post


Link to post
Share on other sites
kod    126
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 ;).

Share this post


Link to post
Share on other sites
zedz    291
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 );

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this