Creating a Spot Light

Started by
10 comments, last by csuguy 15 years, 5 months ago
Hey all, So I've just started messing with lighting. I've got a simple scene with a couple pool tables, some billiard balls, and a flat floor (which I actually made invisible so I could better get this lighting down). I'm using Light1 and I've disable Light0. I set the global ambient light to (0,0,0,0) and the Light1's ambient is set to (.1,.1,.1,1.0). I also set Light1's diffuse light to (.8,.8,.8,1.0). I also have set Light1's position to (0,30,0,1). Now - this looks awesome! Other than where the diffused light hits - it's super dark like I want. The only trouble I am having is getting the light to rotate so that instead of facing down the Z axis - it aims directly down the Y axis. While I have no trouble moving the light - I can't figure out how to get it to aim down. I'm calling a function every frame called positionLight() - and this is called after I do the camera transformations but before my objects are placed.Here is the function: GLfloat lightPosition[] = { 0.0f, 30.0f, 0.0f, 1.0f }; ... void positionLight() { glPushMatrix(); glRotatef(90.0f,0.0f,1.0f,0.0f); glLightfv(GL_LIGHT1,GL_POSITION,lightPosition); glDisable (GL_LIGHTING); glColor3f(1.0f,1.0f,0.0f); glutSolidCone(4.0f,5.0f,15,15); glEnable (GL_LIGHTING); glPopMatrix(); } I've also tried values other than 90 for the rotation - but they don't seem to make any difference to the light (though the solid cone does rotate properly). Any and all help is greatly appreciated! Ryan
Advertisement
In OpenGL lights are relative to the current modelview matrix, i.e. if you set the position it will be multiplied with the current matrix.

So set your lights before setting the camera in order to make them keep their position/orientation (and don't forget to call either glLoadIdentity() or glLoadMatrix() at the beginning of each new frame).
If I was helpful, feel free to rate me up ;)If I wasn't and you feel to rate me down, please let me know why!
Quote:Original post by Lord_Evil
In OpenGL lights are relative to the current modelview matrix, i.e. if you set the position it will be multiplied with the current matrix.

So set your lights before setting the camera in order to make them keep their position/orientation (and don't forget to call either glLoadIdentity() or glLoadMatrix() at the beginning of each new frame).


Thank you for the information! Here's my modified function (now called before camera placement):

void positionLight()
{
//Light Position: 0,75,0
glLightfv(GL_LIGHT1,GL_POSITION,light1Position);
//Spot Direction: 0,-1,0
glLightfv(GL_LIGHT1,GL_SPOT_DIRECTION, spot1Direction);
//Spot CutOff: 90.0f
glLightfv(GL_LIGHT1,GL_SPOT_CUTOFF,&spotCutOff);
//Spot Exponent: 0.0f
glLightf(GL_LIGHT1, GL_SPOT_EXPONENT,spotExponent);
}

It kinda of works now. I have a really annoying problem where when I look at it from the -Z axis it gets really bright, and it dims when I look from the +Z axis... It should light both sides equally, shouldn't it? It's directly above the middle of the table! wdf...
Ok - so I've been messing with it some more to try to solve the problem. First, I switched it back to being positioned after the camera view was set - because it was not being placed in the scene properly until i did so. Second - in order to test it out and make sure it was working I set it up to rotate around the x and z axis. the xRot and zRot variables are mapped to the directional keys.

It works perectly in that regard - it is definitely IN the scene as a spot light should be and everything's lighting changes as expected when I rotate it around.

I guess my problem, then, is the spot_direction setting. Right now I have it set to (0,-1,0). I thought this would make it point directly downard along the Y axis from the spot lights position (0,75,0) and light up the table directly underneath. However, it still lights up the front half (the half that runs along the positive Z) much more than the back half. Please help! Here's my current code:

void positionLight()
{
glPushMatrix();
glRotatef(xRot,1.0f,0.0f,0.0f);
glRotatef(zRot,0.0f,0.0f,1.0f);

glLightfv(GL_LIGHT1,GL_POSITION,light1Position);
glLightfv(GL_LIGHT1,GL_SPOT_DIRECTION, spot1Direction);
glLightfv(GL_LIGHT1,GL_SPOT_CUTOFF,&spotCutOff);
glLightf(GL_LIGHT1, GL_SPOT_EXPONENT,spotExponent);

glTranslatef(light1Position[0],light1Position[1],light1Position[2]);
glPushAttrib(GL_LIGHTING_BIT);
glDisable(GL_LIGHTING);
glColor3f(1.0f,1.0f,0.0f);
glutSolidCone(4.0f,5.0f,15,15);
glPopAttrib();
glPopMatrix();
}
Anyone? :(
Quote:Original post by csuguy
Anyone? :(



im not an expert but :

1) it has been answered before but id like to reminder. Light position are in eye-coord. That mean its relative to ur camera. 0, 75, 0 mean the light is 75 units over the camera.

2) Spot direction is the coord where it point relative to the light.
if you put the light a 0, 75, 0 and you want it to point at 0, 0, 0 then the spot direction will be 0, -75, 0

3) Light is calculated for each vertex of a surface. You will get a better result with a plane made of a lot of small polygon than a simple big quad.

4) I always have problem using translate when it also involve light. Like if i draw a gluSphere and then translate it, the light will be shown on the sphere like if it still was at 0,0,0.

hope it helps.

EDIT : make sure your normals are properly calculated
Thank you for your reply. But you are incorrect - you can insert a light into a scene as if it were an object (positionally speaking). It will stay in the same place in your scene and not move around with the eye coordinates.

This is done with the GL_POSITION param. As you probably know it takes an array of 4 floats. The first three are the x,y,z coords. The last one - an optional one - is w. If w = 0.0 then the first three values represent a vector - meaning the light will come from that direction! However, if you set w to 1.0 (or any value above 0 i think) then the three values serve as an actual position!

I've experimented and confirmed this, I can place the light in the scene and it will stay in the same spot. I can even map the light to the keyboard to move it around. I can also kind of rotate it, but that's where I am having trouble. I can't seem to get it to rotate how I want it to :/.
Quote:Original post by csuguy
Thank you for your reply. But you are incorrect - you can insert a light into a scene as if it were an object (positionally speaking). It will stay in the same place in your scene and not move around with the eye coordinates.

This is done with the GL_POSITION param. As you probably know it takes an array of 4 floats. The first three are the x,y,z coords. The last one - an optional one - is w. If w = 0.0 then the first three values represent a vector - meaning the light will come from that direction! However, if you set w to 1.0 (or any value above 0 i think) then the three values serve as an actual position!

I've experimented and confirmed this, I can place the light in the scene and it will stay in the same spot. I can even map the light to the keyboard to move it around. I can also kind of rotate it, but that's where I am having trouble. I can't seem to get it to rotate how I want it to :/.


nice find i always wondered what was that w value.

to rotate it ull have to do just like a fps camera. Act like if there was a sphere around ur light and make ur light point on a coord on that sphere.

Do u even get it to move or it act like a directionnal ?

here the lil part you may need from a FPSCamera class i made
Quote:
if(buttonViewUp)
{
if (zAngle < (Math.PI/2.0) - 0.1)
zAngle += sensibility * 10.0;
}
if(buttonViewDown)
{
if (zAngle > -(Math.PI/2.0) + 0.1)
zAngle -= sensibility * 10.0 ;
}
if(buttonViewLeft)
yAngle += sensibility * 10.0;
if(buttonViewRight)
yAngle -= sensibility * 10.0;


.....................

public void update()
{
double zVirtual = z - (Math.cos(yAngle) * (Math.cos(zAngle) * 1000.0));
double xVirtual = x - (Math.sin(yAngle) * (Math.cos(zAngle) * 1000.0));
double yVirtual = y + (Math.sin(zAngle) * 1000.0);
glu.gluLookAt(x, y, z, xVirtual, yVirtual, zVirtual, 0, 1, 0);
}
I think it's my rotation math that's screwed up... I'm gonna try plugging yours in real fast and see if that works.
hm... I can't seem to get the glRotatef to work correctly on it, but the glTranslatef works perfectly, I can make it zip all around my scene... wdf...

This topic is closed to new replies.

Advertisement