PDA

View Full Version : Problems with understanding how to work with positional light



stavbodik
09-25-2016, 03:33 PM
Hello , I am trying to create room where outside light wont effect the light inside the room .
So my first thing to do was to get this result (the light is enabled only when walls are drawing):

http://s21.postimg.org/50dm1cspj/image.png

When drawing the walls I ensure that the normal vectors are pointing to room center.
To avoid light effect outside side of meshes I am using :


glLightModelf(GL_LIGHT_MODEL_TWO_SIDE ,GL_TRUE);


GL_LIGHT_MODEL_TWO_SIDE should enable light on both sides of mesh , why its acting as inverse effect ?


If I disable this effect , note using GL_LIGHT_MODEL_TWO_SIDE true I get this :

http://s18.postimg.org/tulkxi8rt/image.png



Then I want to try add another light which is located outside of center of room roof,But wait ... the outside light wont effect the meshes outside the room because all the normal's are pointing to center of room .
So I must disable GL_LIGHT_MODEL_TWO_SIDE ... because I need light on both sides of mesh .

But the thing is that now the outside light effect the inside light :

http://s18.postimg.org/f7k432zk9/image.png


How do I achieve the goal I need ? How to configure lights and normal's on meshes so they will be on both sides of polygon and react to the light which is closer to them , because now as you can see the light goes trough walls :dejection:?

I am also using GL_FRONT_AND_BACK

Here is the configurations before painting :


void display()
{
// clears the buffers with color set in initGraphics with glClearColor
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(LEFT,RIGHT,BOTTOM,TOP,NEAR,FAR);

gluLookAt(eyeX,eyeY,eyeZ,eyeLookAtX,eyeLookAtY,eye LookAtZ,headX,headY,headZ);


drawFloor();
drawGrid();
drawAxis();

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_AMBIENT_AND_DIFFUSE);
//glLightModelf(GL_LIGHT_MODEL_TWO_SIDE ,GL_TRUE);
//glEnable(GL_NORMALIZE);


glLightfv(GL_LIGHT0,GL_AMBIENT,l0amb);
glLightfv(GL_LIGHT0,GL_DIFFUSE,l0diff);
glLightfv(GL_LIGHT0,GL_SPECULAR,l0spec);
glLightfv(GL_LIGHT0,GL_POSITION,l0pos);


glLightfv(GL_LIGHT1,GL_AMBIENT,l1amb);
glLightfv(GL_LIGHT1,GL_DIFFUSE,l1diff);
glLightfv(GL_LIGHT1,GL_SPECULAR,l1spec);
glLightfv(GL_LIGHT1,GL_POSITION,l1pos);

glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,m0amb);
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,m0diff);
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,m0spec) ;
glMaterialf (GL_FRONT_AND_BACK,GL_SHININESS,30);



drawRoom....
}

GClements
09-25-2016, 04:17 PM
room .
How do I achieve the goal I need ? How to configure lights and normal's on meshes so they will be on both sides of polygon and react to the light which is closer to them , because now as you can see the light goes trough walls
Each primitive is (potentially) affected by all of the lights which are enabled at the time that it is rendered. If you want specific primitives to be affected by specific lights, you need to enable and disable lights appropriately.

If you know that the face normals will be facing away from the light (and you're using one-sided lighting), you can assume that the diffuse reflection will be zero, but there's still ambient and specular illumination to consider. Similarly, spot cut-off can be used to prevent some lights from illuminating some primitives.

Note that OpenGL's fixed-function lighting model (glLight, glMaterial, etc) tends not to be used where any significant level of realism is desired. Programs using earlier versions of OpenGL used light maps, modern programs use shader-based techniques (either instead of light maps or in addition to them).

Carmine
09-25-2016, 09:09 PM
Here's a suggestion (without looking too closely at your code).

Do not enable light0 or light1 until you are inside the 'drawRoom' routine.
Then do something like this -



glEnable (GL_LIGHT0);
glDisable (GL_LIGHT1);
Draw_Inner_Walls ();

glDisable (GL_LIGHT0);
glEnable (GL_LIGHT1);
Draw_Outer_Walls ();


This assumes that you want to use LIGHT0 on the inner walls and LIGHT1 on the outer walls.
Good luck.

stavbodik
09-26-2016, 07:18 AM
Here's a suggestion (without looking too closely at your code).

Do not enable light0 or light1 until you are inside the 'drawRoom' routine.
Then do something like this -



glEnable (GL_LIGHT0);
glDisable (GL_LIGHT1);
Draw_Inner_Walls ();

glDisable (GL_LIGHT0);
glEnable (GL_LIGHT1);
Draw_Outer_Walls ();


This assumes that you want to use LIGHT0 on the inner walls and LIGHT1 on the outer walls.
Good luck.


Amazing thanks , so this is how its done ^^ everything manually :)

stavbodik
09-26-2016, 07:58 AM
So here is final result :

http://sendvid.com/1g3lf5gd

Steps I have done if anyone will need it in the future :

When drawing inside meshes(south) normal's are pointing to center of room and only room light0 is ON + next configurations :


// draw south and north meshes
glLightModelf(GL_LIGHT_MODEL_TWO_SIDE ,GL_TRUE);
glEnable(GL_LIGHT0);
drawMesh(southMeshCoordinates,wallColor,wallWidth, wallHigh,wallAngel,INSIDE_DIRECTION);
glDisable(GL_LIGHT0);
glLightModelf(GL_LIGHT_MODEL_TWO_SIDE ,GL_FALSE);



When drawing outside meshes invert normal's to point outside room and disabled GL_LIGHT_MODEL_TWO_SIDE :



glEnable(GL_LIGHT1);
drawMesh(northMeshCoordinates,wallColor,wallWidth, wallHigh,wallAngel,OUTSIDE_DIRECTION);


Thanks you GClements , Carmine !