I’m having a lighting problem and I was hoping some of you kind souls could help me diagnose it.
Here are some shots:
(EDIT: problem determined, pictures removed. They looked like vertex lighting, so just imagine that)
Ok first let me say to ignore the horizontal and vertical line artifacts. Those are a product of my chunking system not having enough data to calculate the normals at the chunk boundries. I know how to solve this problem and I am not concerned right now.
I am using register combiners on a GeForce2 to calculate diffuse light per-pixel, and my concern is that this looks like vertex lighting.
The light source is supposed to be the sun, so I am treating it as a directional light at infinity. Therefore I don’t calculate the light->vertex vector for each vertex, I simply use the same light direction vector for all vertices.
To calculate the terrain normals I am using finite differences as explained here: http://www.flipcode.com/cgi-bin/msg.cgi?showThread=Tip-VertexNormalsHeightMaps& forum=totd&id=-1
The normals are set up properly for the combiners, that is to say mapped from [-1.0, 1.0] to [0.0, 1.0].
My register combiner setup is as follows:
// VERTEX NORMAL in PRIMARY_COLOR
// LIGHT VECTOR in CONSTANT_COLOR0
// LIGHT COLOR in CONSTANT_COLOR1
// TEXTURE0 is decal texture
glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, 1);
glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, GL_CONSTANT_COLOR0_NV, GL_EXPAND_NORMAL_NV, GL_RGB);
glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, GL_PRIMARY_COLOR_NV, GL_EXPAND_NORMAL_NV, GL_RGB);
glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_C_NV, GL_TEXTURE0_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_D_NV, GL_CONSTANT_COLOR1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glCombinerOutputNV(GL_COMBINER0_NV, GL_RGB, GL_SPARE0_NV, GL_SPARE1_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE);
glFinalCombinerInputNV(GL_VARIABLE_A_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_C_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
My theories for what is wrong:
- I need to renormalize the vertex normal per pixel.
- I really do need to calculate the light->vertex vector instead of using the same light vector for all vertices.
- Bad terrain data or precision issue.
Also, I should mention that the light vector and vertex normals are in world-space.
I believe the most probable cause of this is that I am not renormalizing the vertex normal per-pixel. I am thinking about switching over to a normal-map if it will solve my problem. If I used a normal map, how big should it be? One normal per vertex would yield the same result I am getting now, correct? I suppose I should interpolate the normals and renormalize them at each normal-map texel, but is there a rule-of-thumb for the normal-map resolution?
I’d also like to keep the lighting calculations in world-space. I don’t fully understand tangent-space, and I don’t believe it is necessary for this. Also not having to touch the vertex data is nice.
Thanks for your ideas.
[This message has been edited by dismal (edited 02-05-2003).]
[This message has been edited by dismal (edited 02-05-2003).]