PDA

View Full Version : Specular Highlights and Directional lights



doc_colgate
09-03-2002, 04:57 PM
I've got a directional light working to light my solar system correctly (note, this is not just a bunch of spheres I placed randomly... all of the distances are correct down to the meter, etc. I have to scale and translate the rendered objects to keep them inside of the z-buffer each frame. This is done _outside_ of GL, before passing any objects to the renderer.

Earlier I had a problem getting directional light to work. It turned out this was because I was using the transformed positions of the rendered objects. If two objects were both outside of the z-range they could be "moved" inside of the z-range and their relative positions were incorrect (or even on top of one another). I fixed this by using the pre-transformed positions to calculate the light direction for the infinite lights.

However, I now cannot get a specular highlights to show up.

It doesn't matter if I have textures turned on or off.

I am 99.9% positive I have all of the lighting parameters set up correctly.

I set up the material properties so:

// initial lighting values
static flt g_fAmbient [4] =
{
0.1f, 0.1f, 0.1f, 1.0f
};

static flt g_fDiffuse [4] =
{
0.9f, 0.9f, 0.9f, 0.9f
};

static flt g_fSpecular [4] =
{
1.0f, 1.0f, 1.0f, 1.0f
};

static flt g_fGlobalAmbient [4] =
{
0.0f, 0.0f, 0.0f, 1.0f
};

static flt g_fEmission [4] =
{
0.0f, 0.0f, 0.0f, 1.0f
};

glDisable (GL_LIGHTING);
glDisable (GL_COLOR_MATERIAL);

glMaterialfv (GL_FRONT, GL_EMISSION, (GLfloat*)&g_fEmission);

glMaterialfv (GL_FRONT, GL_AMBIENT, (GLfloat*)&g_fAmbient);

glMaterialfv (GL_FRONT, GL_DIFFUSE, (GLfloat*)&g_fDiffuse);

glMaterialfv (GL_FRONT, GL_SPECULAR, (GLfloat*)&g_fSpecular);

glMaterialf (GL_FRONT, GL_SHININESS, 128.0f);

glLightModelf (GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
glLightModelf (GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
glLightModelfv (GL_LIGHT_MODEL_AMBIENT, g_fGlobalAmbient);
glLightModelf (GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);

The light is set up like this:

int nID = g_nLightID [m_nNumVisibleLights];

glLightfv (nID, GL_AMBIENT, (GLfloat*)g_fAmbient);

CColor Color;
pLight->GetColor (Color);

flt fDiffuse [4];
fDiffuse [0] = (Color.m_nRed * ONE_OVER_255) * g_fDiffuse [0];
fDiffuse [1] = (Color.m_nGreen * ONE_OVER_255) * g_fDiffuse [1];
fDiffuse [2] = (Color.m_nBlue * ONE_OVER_255) * g_fDiffuse [2];

glLightfv (nID, GL_DIFFUSE, (GLfloat*)fDiffuse);

glLightfv (nID, GL_SPECULAR, (GLfloat*)&g_fSpecular);

// no falloff
glLightf (nID, GL_CONSTANT_ATTENUATION, 1.0f);
glLightf (nID, GL_LINEAR_ATTENUATION, 0.0f);
glLightf (nID, GL_QUADRATIC_ATTENUATION, 0.0f);

vec vDir;
pLight->GetDirToObject (pObj, vDir);

g_fLightPos [0] = vDir.x;
g_fLightPos [1] = vDir.y;
g_fLightPos [2] = vDir.z;
g_fLightPos [3] = 0.0f;

glLightfv (g_nLightID [i], GL_POSITION, (GLfloat*)g_fLightPos);

My question is... do directional (infinite) lights not provide specular highlights, or am I doing something wrong? I'm using an infinite light because I need the rays to be parallel (otherwise the sphere is not lit correctly because the light inside of the z-range, i.e. relatively close compared to the size of the sphere). I could use a positional light and move it away from the sphere until the rays are almost parallel, but do I need to do that?

[This message has been edited by doc_colgate (edited 09-03-2002).]

[This message has been edited by doc_colgate (edited 09-03-2002).]

witcomb
09-04-2002, 06:30 AM
I'm not really sure if OpenGL does perform any specular highlight with directional lights. However, have you tessalated your sphere suffieciently. If you have not done this then you may just not see the highlight since it could just be blended to well.

After reading the following url, I would be inclined to say that yes directional lights do perform specular lighting. There is a link to similar equations for the opengl spec, I just don't have the time to look it up.
http://www.cs.unc.edu/~andrewz/comp236/hw5b/

Neil Witcomb

Morglum
09-06-2002, 12:04 AM
Of course OpenGL does specular highlights with directional lights.

The point is that, to actually see the highlight, you have to be at the right viewpoint. The higher the GL_SHININESS, the narrower the place from where you can see the highlight.
To see the highlight:
1) disable texturing (to see highlights w/textures requires an extension state to be enabled : GL_SEPARATE_SPECULAR_COLOR)
2) set the GL_SHININESS to a very low value, say, 2.0
3) <most important> try different viewpoints. Ideally, you would let the user change the viewpoint with the mouse/the keyboard.

By the way, if you turn texturing off, change the diffuse to a lower value, say, 0.5,0.5,0.5. Or else, if your monitor isn't gamma -corrected, you'll find it hard to tell the difference between 0.9 and 1.0.

Morglum