Sign in to follow this  

Frustrated... can't get lighting and proper normals :(

This topic is 3632 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

After working all night, I can't get the normals to render the lights properly on my terrain. I've based my code on Farenheit451 user solution to average vertex. I'm taking a height-map with -1..1 values which I scale by a float factor, e.g: 10.0f, 20.0f, 80.0f... This is the terrain rendering code (brute force for now).
void CTerrain::Render()
{
	// renders terrain from height map

	float v_height;	// vertex height
	GLfloat scaledHeight;
	static float eye;

	eye = eye + 0.1f;

	GLfloat lightpos[4] = { 128.0f, 200.0f, 128.0f, 0.0f };
	GLfloat mat_spec[4] = { 1.0f, 1.0f, 1.0f, 0.0f };

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45.0f, 1.0f, 1.0f, 1200.0f);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt (0.0f, 200.0f, eye, 128.0f, 0.0f, 128.0f, 0.0f, 1.0f, 0.0f);

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glEnable(GL_LIGHTING);	
	glLightfv(0, GL_POSITION, lightpos);
	glEnable(GL_LIGHT0);
	
	// render (this is BRUTE FORCE)
	
	for (int z = 0; z < tsize-1; z++)
	{
		glBegin(GL_TRIANGLE_STRIP);

		for (int x=0; x < tsize-1; x++)
		{
			v_height = hmap.GetValue(x,z);	
			scaledHeight = v_height * h_scale;

			glNormal3fv (normals[x*tsize+z]);			
			glVertex3f ((GLfloat) x,  scaledHeight, (GLfloat) z);

			v_height = hmap.GetValue(x,z+1);		
			scaledHeight = v_height * h_scale; 
			
			glNormal3fv (normals[(x*tsize)+z+1]);
			glVertex3f ((GLfloat)x, scaledHeight, (GLfloat)z+1);
		}
		glEnd();
	}
	

As you see I work the heightmap as a xz plane. The normal generating code:
/* generate normals */

	CVector3 vp1,vp2,vp3,vp4,vp5,vp6,vp;

	for (int z = 0; z < tsize; z++)
		for (int x = 0; x < tsize; x++)
		{		
			CVector3 v(x, hmap.GetValue(x,z)*h_scale, z);

			if (z == 0 && x == 0) // bottom-left corner pixel
			{				
				CVector3 n2(x+1, hmap.GetValue(x+1,z)*h_scale, z); // neighbor at x+1,z
				CVector3 n3(x, hmap.GetValue(x,z+1)*h_scale, z+1); // neighbor at x,z+1
				CVector3 v1 = n2 - v;
				CVector3 v2 = n3 - v;				
				vp.crossprod(v1,v2);
				vp.normalize();
			}
			else
				if ( x == 0 && ( z > 0 && z < tsize - 1) ) // left edge pixels
				{
					CVector3 n2(x+1,hmap.GetValue(x+1,z)*h_scale, z); // neighbor at x+1,z
					CVector3 n3(x,	hmap.GetValue(x,z+1)*h_scale, z+1); // neighbor at x,z+1
					CVector3 n4(x+1,hmap.GetValue(x+1,z-1)*h_scale,z-1); // neighbor at x+1,z-1
					CVector3 n5(x,  hmap.GetValue(x,z-1)*h_scale,z-1);	 // neighbor at x, z-1
					CVector3 v1 = n2 - v;
					CVector3 v2 = n3 - v;
					CVector3 v3 = n4 - v;
					CVector3 v4 = n5 - v;
					vp1.crossprod (v1,v2);
					vp2.crossprod (v2,v3);
					vp3.crossprod (v3,v4);
					vp=(vp1+vp2+vp3)/3.0f;
					vp.normalize();
				}
				else
					if ( (z == tsize - 1) && ( x > 0 && x < tsize - 1) ) // top edge pixels
					{
						CVector3 n2(x+1,hmap.GetValue(x+1,z)*h_scale, z); // neighbor at x+1,z
						CVector3 n3(x-1,hmap.GetValue(x-1,z)*h_scale, z); // neighbor at x-1,z
						CVector3 n4(x  ,hmap.GetValue(x,z-1)*h_scale, z-1); // neighbor at x,z-1
						CVector3 n5(x-1,hmap.GetValue(x-1,z-1)*h_scale, z-1); // neighbor at x-1,z-1
						CVector3 v1 = n2 - v;
						CVector3 v2 = n3 - v;
						CVector3 v3 = n4 - v;
						CVector3 v4 = n5 - v;
						vp1.crossprod (v1,v2);
						vp2.crossprod (v2,v3);
						vp3.crossprod (v3,v4);
						vp=(vp1+vp2+vp3)/3.0f;
						vp.normalize();
					}
					else
						if ( (x == tsize - 1) && (z > 0 && z < tsize - 1) ) // right edge pixels
						{
							CVector3 n2(x-1,hmap.GetValue(x-1,z)*h_scale, z); 
							CVector3 n3(x-1,hmap.GetValue(x-1,z+1)*h_scale, z+1); 
							CVector3 n4(x  ,hmap.GetValue(x,z-1)*h_scale, z-1); 
							CVector3 n5(x  ,hmap.GetValue(x-1,z)*h_scale, z); 
							CVector3 v1 = n2 - v;
							CVector3 v2 = n3 - v;
							CVector3 v3 = n4 - v;
							CVector3 v4 = n5 - v;
							vp1.crossprod (v1,v2);
							vp2.crossprod (v2,v3);
							vp3.crossprod (v3,v4);
							vp=(vp1+vp2+vp3)/3.0f;
							vp.normalize();
						}
						else
							if ( (z == 0) && (x > 0 && x < tsize - 1) ) // bottom edge pixels
							{
								CVector3 n2(x-1,hmap.GetValue(x-1,z)*h_scale, z); 
								CVector3 n3(x+1,hmap.GetValue(x-1,z)*h_scale, z); 
								CVector3 n4(x  ,hmap.GetValue(x,z+1)*h_scale, z+1); 
								CVector3 n5(x-1,hmap.GetValue(x-1,z+1)*h_scale, z+1); 
								CVector3 v1 = n2 - v;
								CVector3 v2 = n3 - v;
								CVector3 v3 = n4 - v;
								CVector3 v4 = n5 - v;
								vp1.crossprod (v1,v2);
								vp2.crossprod (v2,v3);
								vp3.crossprod (v3,v4);
								vp=(vp1+vp2+vp3)/3.0f;
								vp.normalize();
							}
							else
								if ( z == 0 && (x == tsize - 1) ) // bottom right
								{
									CVector3 n2(x-1, hmap.GetValue(x+1,z)*h_scale, z); // neighbor at x-1,z
									CVector3 n3(x, hmap.GetValue(x,z+1)*h_scale, z+1); // neighbor at x,z+1
									CVector3 v1 = n2 - v;
									CVector3 v2 = n3 - v;				
									vp.crossprod(v1,v2);
									vp.normalize();
								}
								else
									if ( z == tsize - 1 && (x == 0) ) // top left
									{
										CVector3 n2(x+1, hmap.GetValue(x+1,z)*h_scale, z); // neighbor at x+1,z
										CVector3 n3(x, hmap.GetValue(x,z-1)*h_scale, z-1); // neighbor at x,z-1
										CVector3 v1 = n2 - v;
										CVector3 v2 = n3 - v;				
										vp.crossprod(v1,v2);
										vp.normalize();
									}
									else
										if ( z == tsize - 1 && (x == tsize - 1) ) // top right
										{
											CVector3 n2(x-1, hmap.GetValue(x-1,z)*h_scale, z); // neighbor at x-1,z
											CVector3 n3(x, hmap.GetValue(x,z-1)*h_scale, z-1); // neighbor at x,z-1
											CVector3 v1 = n2 - v;
											CVector3 v2 = n3 - v;				
											vp.crossprod(v1,v2);
											vp.normalize();
										}	
										else
										{ // average with 6 pixels
											CVector3 n2(x-1,hmap.GetValue(x-1,z+1)*h_scale, z+1); 
											CVector3 n3(x+1,hmap.GetValue(x+1,z)*h_scale, z); 
											CVector3 n4(x-1,hmap.GetValue(x-1,z)*h_scale, z); 
											CVector3 n5(x+1,hmap.GetValue(x+1,z-1)*h_scale, z-1); 
											CVector3 n6(x  ,hmap.GetValue(x ,z+1)*h_scale, z+1); 
											CVector3 n7(x  ,hmap.GetValue(x ,z-1)*h_scale, z-1); 
											CVector3 v1 = n2 - v;
											CVector3 v2 = n3 - v;
											CVector3 v3 = n4 - v;
											CVector3 v4 = n5 - v;
											CVector3 v5 = n6 - v;
											CVector3 v6 = n7 - v;

											vp1.crossprod (v1,v2);
											vp2.crossprod (v2,v3);
											vp3.crossprod (v3,v4);
											vp4.crossprod (v4,v5);
											vp5.crossprod (v5,v6);
											vp6.crossprod (v6,v1);

											vp=(vp1+vp2+vp3+vp4+vp5+vp6)/6.0f;
											vp.normalize();
										}

										normals[x*tsize+z][0]=vp.x;
										normals[x*tsize+z][1]=vp.y;
										normals[x*tsize+z][2]=vp.z;			
		}


To guide, here's some images... Free Image Hosting at www.ImageShack.us Free Image Hosting at www.ImageShack.us Thank you very much!

Share this post


Link to post
Share on other sites
ha i did exactly the same today :p
I was wondering do you display your terrain in some display list or vertex/normal/texture array or do you just display it?

Share this post


Link to post
Share on other sites

This topic is 3632 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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