Lighting + Materials in OpenGL

Hello,

Im kinda confused and banging my head against a brick wall while working with lighting and materials in OpenGL…

I have a single light that may have an ambient/diffuse color, the material may also have an ambient/diffuse color. For some reason when i try to enable my light and model using the code below:


  if(Mat.hasAmbient())
                {
                    BaseColour bcAmbient = Mat.getAmbient();
                    float[] fColours = {bcAmbient.fR, bcAmbient.fG, bcAmbient.fB};
                    gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT, fColours, 0);
                }
                
                if(Mat.hasDiffuse())
                {
                    BaseColour bcDiffuse = Mat.getDiffuse();
                    float[] fColours = {bcDiffuse.fR, bcDiffuse.fG, bcDiffuse.fB};
                    gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE, fColours, 0);
                 }

the light is setup shown below:



  float TempAmbient[] = {bcAmbient.fR, bcAmbient.fG, bcAmbient.fB, bcAmbient.fA}; 
        gl.glLightfv(intLightID, GL.GL_AMBIENT, TempAmbient, 0);
        
        float TempDiffuse[] = {bcDiffuse.fR, bcDiffuse.fG, bcDiffuse.fB, bcDiffuse.fA}; 
        gl.glLightfv(intLightID, GL.GL_DIFFUSE, TempDiffuse, 0);
        
        float TempSpecular[] = {bcSpecular.fR, bcSpecular.fG, bcSpecular.fB, bcSpecular.fA}; 
        gl.glLightfv(intLightID, GL.GL_SPECULAR, TempSpecular, 0);
        
        float TempPosition[] = {vPosition.fX, vPosition.fY, vPosition.fZ};
        gl.glLightfv(intLightID, GL.GL_POSITION, TempPosition, 0);


The light setup is called during the init phase, then when i render i enable lighting and the given light, then i call the material code shown above. However i just get a model with no shading on, i have enabled gl.glShadeModel(GL.GL_SMOOTH); and im baffled…

Are you supposed to use EITHER the light or the material colors rather than using them both, if you cna use them both i thought the diffuse was the shading you have on the model and the ambient was like the base color, however when i enable diffuse color its like the ambient color vanishes and i just get a model in 1 color with no shading…

Any advice related to lighting and materials would be GREAT!

Are you supplying normal vectors with your model? I’ve had no trouble with getting lighting or materials to work, even when both types of colors are specified. You might also want to show the enabling of the light code, since that could be important. Usually if you’ve enabled lighting (ie gl.glEnable(GL.GL_LIGHTING)) but the lights or mats are improper, you get a black object. Is that the color you’re getting, or are you seeing what would be expected based on the last glColor…() call?

maybe your light is pointing in the wrong direction : to the back of your model, this will explain what there is no shade and you only see ambient light, try to change your light direction, also take care about the alpha value of your diffuse color.

Hey sorry ive been away so not been checking here,

Its just white, im doing the glEnable(GL_LIGHTING); im also doing glEnable(GL_NORMALIZE); for test purposes with getting the correct normals.

if i add these light parameters in then the light kinda does what its meant to:


        ((JOGLRenderer)bwWindow).getGL().glLightf(GL.GL_LIGHT0,GL.GL_CONSTANT_ATTENUATION, 1.0f);
        ((JOGLRenderer)bwWindow).getGL().glLightf(GL.GL_LIGHT0,GL.GL_LINEAR_ATTENUATION, 0.1f);
        ((JOGLRenderer)bwWindow).getGL().glLightf(GL.GL_LIGHT0,GL.GL_QUADRATIC_ATTENUATION, 0.05f);

Although i have to get REALLY close to the model or i cant see the shading, if im far away it goes all ambient colour and cant see the shading. If i change the QUADRATIC_ATT down quite a bit to like 0.0001f it lets me be further back while viewing the shading but most tutorials dont use this method when doing lighting…

with materials can you do:

glBegin(GL_TRIANGLES);

glMaterialfv(…Ambient…);
glMaterialfv(…Diffuse…);
glVertex3f(…);

glEnd();

Just like glColor3f(…); or do you have to define these calls outside of the glBegin() field?

So yes, you can use glMaterial* in a glBegin/end block.

Try adjusting the shininess parameter for the material, this could also have an effect on how much shading it appears to have. A value of around 90 works for me (if I’m remembering correctly, I’m at work and can’t actually check).

will give it a try, thanks guys!

Tried messing around with it and still not getting desired results…

one thing that does confuse me is when i move my camera round the model the light changes… its like if i turn left the light fades if i turn right it gets brighter, until a certain point…

Here are 2 shots i took, from me just moving the camera SLIGHTLY and the difference it makes…

http://macro.macnjode.com/stuff/random/ogl_light1.JPG

http://macro.macnjode.com/stuff/random/ogl_light2.JPG

The top image shows the main problem im facing, where it just looks like the object is saturated with colour or something. I cant see any shading in there even though shading is enabled as is lighting/normals etc… The bottom image shows the weird results im getting when moving around my scene. Just a small change can make the model white out…

OH the teapot is the main model im trying to light, the other 2 boxes with lines are a debug camera i put in so you can see the light, the direction i set up, so you can at least see where my light should be produced from…

I was expecting light to illuminate the faces on the front where the light is, and the back to be dark as no light is reaching it, however its like the whole model just gets all or nothing… Anyone got any ideas?

Try reading the redbook and doing a quick port of the redbook lighting examples. If they don’t work, then there’s something wrong with your drivers or card. Also in their lighting section, they explain in detail how you have to give the lighting position to get proper and expected results. That should fix your positioning problem for when the shading moves when the camera moves (if you don’t set it up correctly, the light stays relative to the camera).

Aint got the redbook, im guessing its not a free to download document?

From what ive seen you only need to set the position when you create the camera, all the tutorials covering this seem to do that… is there any online resources you would recommend viewing? Ive got the OpenGL superbible 2nd edition but it doesnt seem to go any more indepth than most tutorials on the net…

For 1.1 it is: http://www.opengl.org/documentation/red_book/ which covers most of the core OpenGL API.

And IIRC you should set your light’s positions every frame, just before you start setting up transformation matrices for world objects. But any time after you’ve positioned your camera should be ok.

cheers matey!

will give this a read through and post back if im still being an idiot…

Ok got a much better understanding now, i thought that the light was set in stone until you called another GL_LIGHT_POSITION i didnt know it took on the matrix TRS factors.

Anyway got it all lit and things, but for some reason the its like the light is passing through my model…

Im using a teapot as you can see in the screenshots and its like the light hits the front section and illunminates roughly 40 faces, then when i rotate the model its like the back has 100 faces lit. Surely the back end would be blacked out as no light can reach the back of the model…

I havent set any transparency, face cullings on (CCW), only the GL_FRONT are being assigned with materials… there is no alpha being assigned anywhere so im a tad baffled as to why the light passes through the object opposed to hitting the front faces then not going anywhere. Oh im also using a spotlight about 50.0f away from the model facing it…

I am not an expert in opengl so i may say something complelty wrong but i remenber having problem with lighting and have to set matrix to GL_LOCAL_VIEWER to correct the problem ? maybe…

tried enabling LOCAL_VIEWER in the lightmode but didnt change anything… I think its only usefull for specular lighting, and in this case i dont think its specular thats the issue… thanks for the info though…

GL_LOCAL_VIEWER is for specular lighting, it gives a more accurate specular highlight, however it is more expensive to calculate. Just to check, you set the position after the camera transform, right? Also, if you were expecting it to be dark because of shadowing, opengl doesn’t automatically calculate that. If it’s to be dark because the faces are pointing away from the light, but it’s still in shadow, then something is wrong.

Yep the way im setting things is when the update functions called it updates the camera, then pushes, sets the light then pops, then renders everything else. There are dark parts of the model, to the left and right where i think it falls out of the spotlights main beam.

However where the beam hits the model, its like it keeps on going and lights the models faces on the other side of the model, im generating the normals correctly to my knowledge as the lighting looks how it should, its just the face that it seems to go through the model rather than hitting it and bouncing off.

If you imagine holding a torch right in front of a teapot you would only see light on the front of the teapot, not the front and the back, as no light will get round to the back of it… thats the simplest way of describing it…

Ive been messing around a bit more and i thought i would post up a screenshot of the problem im having…

http://macro.macnjode.com/stuff/random/ogl_light3.JPG

Ive put debug lights in so you can see the light positions in the scene. Only the red light is on (the left one) and you can see the line pointing out of it showing the direction of the light as well as its colour (red/orange)… I would expect this to hit the model on the left hand side, however i dont know why the right hand side is being lit too… Also if you notice the spot is only small on the left side but rather large on the right side, just like a cone light would do…

Im thinking its possibly because the light is basically infinate in a given direction, so i can understand if every front_face in X direction will get lit. However im unsure of how to stop this effect, would light attenuation help cause the light to fade from areas that are not in the lights initial path?

Any advice would be great, and if anyones confused only the yellow boxes in that screenshot are active lights, the red ones are not active…

Light Details:


setAmbient(0.8f,0.0f,0.0f,1.0f);
setDiffuse(0.8f,0.5f,0.3f,1.0f);
setSpecular(1.0f,1.0f,1.0f,1.0f);
setPosition(0.0f,0.0f,30.0f);
setSpotlightDirection(0.0f,0.0f,-1.0f);
setCutoff(15.0f);
setExponent(10.0f);

Teapot Material Details:


float[] fColours1 = {1.0f, 1.0f, 1.0f, 1.0f};
gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, fColours1, 0);
gl.glMateriali(GL.GL_FRONT, GL.GL_SHININESS, 90);
        
float[] fColours2 = {1.0f, 1.0f, 1.0f, 1.0f};
gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, fColours2, 0);
       
float[] fColours3 = {1.0f, 1.0f, 1.0f, 1.0f};
gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, fColours3, 0);

Also the screenshot is looking ALONG the X axis, as i had to move the camera round so you could see both sides that the light passes through!

Try not using a spotlight, it looks to me that the parts that are lit (even the incorrect back side), correctly fall within the spotlight, so it could be part of the implementation of spotlights that’s causing the error. Try and get a normal directional or plain point light working before going on. Also, you could reduce your exponent factor when setting it.