• ### Announcements

#### Archived

This topic is now archived and is closed to further replies.

# Pixelated lighting on heightmapped terrain

## Recommended Posts

JonW    173
Hi, I have some randomly generated islands and I would like to use OpenGL's lighting to give shape to the hills. It turned out as I planned, but the tiles become severely "pixelated": Screenshot - 72kb Here is the code for terrain rendering:


for ( X = 0; X < NUM_TILES; X++ )
{
for ( Y = 0; Y < NUM_TILES; Y++ )
{
// Get the (X, Y, Z) value for the bottom left vertex

// Get the (X, Y, Z) value for the top right vertex

vQuad[1].y = GetVertex(X + 1, Y + 1)->nHeight;

// Get the (X, Y, Z) value for the top left vertex

vQuad[2].y = GetVertex(X, Y + 1)->nHeight;

// Get the (X, Y, Z) value for the bottom right vertex

vQuad[3].y = GetVertex(X + 1, Y)->nHeight;

// Set the normal for this quad

glNormal3f(vNormal.x, vNormal.y, vNormal.z);

// Render the vertices

}
}

glEnd();

// Reset the color

glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

The light setup:

float ambience[4] = {0.3f, 0.3f, 0.3f, 1.0};		// The color of the default light in the world

float diffuse[4] = {0.5f, 0.5f, 0.5f, 1.0};			// The color of the positioned light

glLightfv( GL_LIGHT0, GL_AMBIENT,  ambience );
glLightfv( GL_LIGHT0, GL_DIFFUSE,  diffuse );
glLightfv( GL_LIGHT0, GL_POSITION, g_LightPosition );

glEnable(  GL_LIGHT0   );								// Turn this light on

glEnable(  GL_LIGHTING );								// This turns on lighting

// Allow us to use colors on our polygons during lighting

glEnable(GL_COLOR_MATERIAL);

And finally the normal function:

CVector3 Normal(CVector3 vTriangle[])
{
CVector3 vVector1 = Vector(vTriangle[2], vTriangle[0]);
CVector3 vVector2 = Vector(vTriangle[1], vTriangle[0]);

// Calculate normal

CVector3 vNormal = Cross(vVector1, vVector2);

// Normalize it to 1

vNormal = Normalize(vNormal);

return vNormal;
}

I think this is because each 16x16 quad has its own normal, so each one has slightly different lighting. Any suggestions on how I can correct it? The quads are not textured, just colored. Would texturing them help? Thanks in advance! [edited by - JonWoyame on May 28, 2003 3:42:10 PM]

##### Share on other sites
stu_pb    138
Looks like you need to specify a different normal for each vertex in each quad. This can be done by inserting glNormal calls before each vertex in the rendering loop. These normals need to be calculated as an average between adjacent quads to get a smoothing effect.

I should probably be working now...

##### Share on other sites
JonW    173
I never thought about using a different normal for each vert, but that probably would work! I''ll try that out tomarrow and share the results.

Thanks!

##### Share on other sites
Guest Anonymous Poster
You might try looking up the command glShadeModel(). Using
glShadeModel(GL_SMOOTH) in your display function will cause the lighting to determine the normal for a particular spot on a surface by interpolating the normals at each vertex.

Consequently, you must calculate the normal at each vertex (this doesn''t make sense, formally), but it is what is needed.
The vertex normal is the weighted average of polygon normals that share the vertex.

n = n1 + n2 + n3 + n4 / | n1 + n2 + n3 + n4 |

(if there were 4 polys at the vertex)