Skip to main content
gamedev.net
🔒 Locked

Odd Lighting Issue

Started by Blips Aug 2, 2011 at 8:56 PM 7 replies 1.4k views
Original Post
Blips
Blips
Small disclaimer: new to openGL and am working from Xcode on my iPod touch in openGL ES.

I've been diving into openGL head first on the iOS over the past week and have just finished writing a file parser for loading in models. I'm currently just working with triangles and normals and lighting - I'm not attempting textures at the moment and am simply organizing the data internally in an array of triangles before I attempt to do triangle strips.

The model I've loaded is concave and looks correct unless at certain angles (I don't have a depth buffer in yet). I'm currently just rotating the model about it's x-axis and have one light in the scene. The issue is, even with culling on, the model is appearing completely white when turned 180 degrees and completely black while turned 0 degrees.

It's more than possible I'm just making a stupid beginners mistake. The light position should be well outside the geometry of the object and I've tried both back and front culling so I'm not sure what else could be the issue.

Here is some code:



//creating openGL lighting
GLfloat lightAmbient[] = {0.2f, 0.2f, 0.2f, 0.0f};
GLfloat lightDiffuse[] = {1.0f, 1.0f, 1.0f, 0.0f};
GLfloat lightSpecular[] = {1.0f, 1.0f, 1.0f, 0.0f};

glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular);

glShadeModel(GL_SMOOTH);

GLfloat lightPosition[] = {0.0f, 0.0f, 10.0f, 1.0f};
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

//face culling
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);



[(EAGLView *)self.view setFramebuffer];

MeshInstance *tempMesh = [MeshLibrary createMeshInstance:MESH_RED_BLOOD_CELL];

glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(0.5, 0.5, 0.5);
glTranslatef(0, 0, 0);
rotX += 0.5f;
glRotatef(rotX, 1.0, 0, 0);
transY += 0.075f;

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, tempMesh.meshPtr.vertices);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, tempMesh.meshPtr.normals);

glDrawArrays(GL_TRIANGLES, 0, tempMesh.meshPtr.vertexCount);
[tempMesh dealloc];

[(EAGLView *)self.view presentFramebuffer];


And here are some screenshots demonstrating the issue:
img0004j.png img0005h.png

img0006r.png img0008c.png

Any help would be greatly appreciated!
capricorn
capricorn
Assuming your light source is set up exactly once before rendering starts, I'd suggest your model has incorrect normals. Or do you set up light source every frame? If so, you should be aware that light position is affected by current modelview matrix.
WBW, capricorn
Blips
Blips

Assuming your light source is set up exactly once before rendering starts, I'd suggest your model has incorrect normals. Or do you set up light source every frame? If so, you should be aware that light position is affected by current modelview matrix.


The light source is setup only once. I'll look into seeing the normals are indeed correct. I know that the normals are being loaded correctly, but it's possible I've made a mistake after that somewhere.
Blips
Blips

It may be due to the fact that you haven't set a shininess factor. Try something like this:

glLightf(GL_LIGHT0,GL_SHININESS,32.0f);


This didn't fix the issue but it make the lighting look a bit better.

I tried commenting out the glNormalPointer line, and rendered the object based just on the vertex data. As you'd expect, the object loses all depth but, the issue of one side being completely black and the opposing side being lit is still occurring. Which makes me wonder if perhaps there some sort of clipping issue.
Blips
Blips

Just checking, have you actually enabled depth testing?


No I don't have depth testing enabled but I think I figured out the issue. The issue stems from me not being 100% sure how or when matrices are applied in OpenGL. I think what was happening was that the light in the scene was simply orbiting the origin while the model rotated which ensured that only one side would ever be lit.

I understand how matrices (the actual mathematical concept) work, and I understand what the matrix stack is - what I'm not sure of is when the matrices are used by OpenGL. When in the ModelView mode, is data transformed when it is passed using functions such as glVertexPointer() by the current matrix, or does passed data get transformed by the current matrix when it is rendered or is passed data transformed when new matrices are pushed onto stack and manipulated? Right now I'm having to reset the light's position each frame to stop it from moving, but it would be nice to know just when OpenGL is moving it in the first place.
Blips
Blips
I think I may have spoken too soon of having fixed the issue of only one side being lit.
I've made the light directional as it was supposed to be, and after quite a bit of tinkering had thought I had fixed the issue by resetting the position of the light each frame. But then I read (and maybe OpenGL ES is different?) that the light position only changes when being set, and is transformed by the current modelview matrix. My original idea was that the light was orbiting the origin as the model rotated which prevented one side from ever being lit - but now this explination doesn't make sense.

I'm pretty sure the normals are correct (I've double confirmed they're being loaded properly) and am going to investigate them more fully today. After a lot of head ache, I've finally managed to get depth buffering working - I had a problem where I was passing a positive value into glOrthof for zNear, and a negative value for zFar. I'm still not sure why switching the values makes sense since objects with a negative z value are further away, but swapping the values got the depth buffering working.

I've also got colors and materials in now. Not a huge accomplishment I know, but when coupled with depth buffering helps more clearly illustrate the issue where one side isn't being lit. I've taken new screenshots of the model being rotated about the x axis:

seq0.png

seq1.png

Blips
Blips
Mystery solved:
It turns out the normal data in the file was incorrect. I don't know if that is a result of it having been converted from an FBX to a Wavefront Obj file, or if the normals were never good to begin with for some reason.

At any rate, I calculated my own normals as I loaded in the vertex data and got a result that looks correct. I'm guessing I'll have to average the normals of each vertex to help smooth the lighting. Here's what it looks like now (along with me rendering lines representing normals for each face):

img0016b.png

Thanks for all the help!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.