PDA

View Full Version : Light perpendicular to a normal?



DalTXColtsFan
02-20-2004, 10:46 AM
Anyone ever experienced unpredictable results when using an OpenGL light that's perfectly perpendicular to a normal?

I'm rendering several rectangular prisms, and I have a light that I'm trying to simulate the sun and moon with like this:


float afAmbientLight[4];

if (m_fFactor >= 0.0f && m_fFactor <= 0.5f) {
//sun's out

afAmbientLight[0] = 0.1f + 0.9f * sin(3.14159 * m_fFactor * 2.0f);
afAmbientLight[1] = 0.1f + 0.9f * sin(3.14159 * m_fFactor * 2.0f);
afAmbientLight[2] = 0.1f + 0.9f * sin(3.14159 * m_fFactor * 2.0f);
afAmbientLight[3] = 1.0f; }
else {
//moon's out
afAmbientLight[0] = 0.1f + 0.1f * sin(3.14159 * (m_fFactor - 0.5f) * 2.0f);
afAmbientLight[1] = 0.1f + 0.1f * sin(3.14159 * (m_fFactor - 0.5f) * 2.0f);
afAmbientLight[2] = 0.1f + 0.1f * sin(3.14159 * (m_fFactor - 0.5f) * 2.0f);
afAmbientLight[3] = 1.0f;
} glLightModelfv(GL_LIGHT_MODEL_AMBIENT, afAmbientLight);

glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 1.0f);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 90.0f);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0f);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0f);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.0f);
//I don't know why this works, but I have better luck
//getting the sun or moon effect I want if I let the
//global ambient take care of ambient and let the
//directional light take care of diffuse and specular

float fAmbient[4] = {0.0f, 0.0f, 0.0f, 0.0f};
glLightfv(GL_LIGHT0, GL_AMBIENT, fAmbient);
float fDifSpec[4];
if (m_fFactor >= 0.0f && m_fFactor <= 0.5f) {
fDifSpec[0] = 1.0f;
fDifSpec[1] = 1.0f;
fDifSpec[2] = 0.0f;
fDifSpec[3] = 1.0f;
}
else
{
fDifSpec[0] = 1.0f;
fDifSpec[1] = 1.0f;
fDifSpec[2] = 1.0f;
fDifSpec[3] = 1.0f;
}

glLightfv(GL_LIGHT0, GL_DIFFUSE, fDifSpec);

glLightfv(GL_LIGHT0, GL_SPECULAR, fDifSpec);
//for all practical purposes, a directional light
//shines in the direction opposite its position
//and spot direction is ignored float
fPosition[4];

if (m_fFactor >= 0.0f && m_fFactor <= 0.5f) {
fPosition[0] = (float)cos(m_fFactor * 2 * 3.14159);
fPosition[1] = (float)sin(m_fFactor * 2 * 3.14159);
fPosition[2] = 0.0f;
fPosition[3] = 0.0f; }
else
{

fPosition[0] = (float)cos((m_fFactor - 0.5f) * 2 * 3.14159);
fPosition[1] = (float)sin((m_fFactor - 0.5f) * 2 * 3.14159);
fPosition[2] = 0.0f;
fPosition[3] = 0.0f; }

glLightfv(GL_LIGHT0, GL_POSITION, fPosition);


The normals on the prism sides facing front and back are (0, 0, 1) and (0, 0, -1).

What I'm seeing is these two sides "flicker" - and they flicker at exactly the same time each "cycle". Are there certain angles that light up the surface?



[This message has been edited by DalTXColtsFan (edited 02-20-2004).]

DalTXColtsFan
02-20-2004, 11:00 AM
Let me explain a little better what I'm seeing. What I'm expecting is, the surfaces parallel to the XY plane should only be lit by the ambient components of the light, and should be gradual throughout the rise and fall of the sun and rise and fall of the moon.

At all but like 4 points in the up-down cycle, it does what I expect. In these 4 instances, the surfaces are very bright, it's like at 4 times during the cycle the ambient light on those surfaces is 1.

Any idea why?

dphil
11-27-2010, 08:56 PM
Hate to revive an ancient thread, but it's been almost impossible to find anything about my problem. DalTXColtsFan's issue is exactly the problem I'm having.... but I see he didn't get an answer (here, anyway) either. Sigh..figures.

So in my case, when the light direction is perpendicular to a quad's (my "ground", in this case) normal, I get erratic flickering of the specular light as I move my camera around such that it is on the opposite side of the ground from the light direction (ie when the camera is close more or less looking in the direction the light is coming from).

Any help is much appreciated. I've tried to whittle my code down to the basics and am still having the problem. I find it odd that I've found so little about this. Seems like something that would come of commonly enough...

Marsh Ray
11-28-2010, 01:43 AM
Divide-by-zero?

ZbuffeR
11-28-2010, 08:45 AM
Specular can not be nicely color-interpolated like diffuse.
Quick hack : soften the specular by using a lower exponent, like 10 or less
Old school fix : reduce the error by using more tesselated geometry, like explained here on point 2 :
http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/
Much better : do per pixel lighting with a basic shader :
http://www.swiftless.com/tutorials/glsl/5_lighting_perpixel.html