Problem with lighting in back faces

Started by
10 comments, last by IrYoKu 18 years, 11 months ago
Hi, I am representing a surface using triangle strips, and I am having troubles with lighting. I am calculating the normal for every vertex in the surface (to do smooth shading), and I think I am doing it well. In the top side (where the normal points outside) of the surface, lighting looks OK. AFAIK in the bottom side of the surface there should be only one color (the ambient color), because opengl by default uses one-side lighting, but there are faces that are highlighted in the bottom, thus or the normals are bad, or there is something I don't understand. Here you will find a pair of snapshots of the top/bottom of the surface. http://www.paintimpact.com/iryoku/top.jpg http://www.paintimpact.com/iryoku/bottom.jpg If someone can explain me this, I will appreciate it a lot. Thanks a lot :)
Advertisement
seems ok to me, hard to tell with such a model anyway, use a better model
One-sided lighting simply means that lighting is calculated depending on the normal. This means that frontside and backside will have the same colour. If the frontside is lit, then so is the backside. Two-sided lighting means that the light is calculated differently for frontside and backside. If the frontside is lit, the backside will most likely be dark (but also: if the frontside is dark, the backside will most likely be lit).

Either way, unless you're also doing shadowing in addition to lighting, there will be lit faces "inside" your model.
Kippesoep
Exactly because GL uses one-side lighting by default, vertices get the same lighting regardless if you're looking at the front or the back face. The all count as "front". You need two-sided lighting to achieve the effect you want.

-EDIT: Kippesoep beat me to it.
It's not really that the faces are lit "inside" the model, but the back of the faces being lit.

I will try to explain why this shouldn't be possible:

To put it simply let's consider flat shading with only one light. The illumination of a face is calculated as the dot product of the normal of the face and the vector that goes from the face to the light source.

Then when the light is in front of the face, the angle is 0º, so that the dot product is 1.0, and the illumination factor is 1.0 too, thus the color of that face is the ambient light plus the rgb value of that face multiplied by the illumination factor.

When the light is in the side, the angle is 90º, the dot product is 0.0, so the color of the face is the ambient light plus zero.

When the angle is greater than 90º (when the light is at the back of the face), the dot product is negative, and because this result doesn't have sense, the color of the face should be the minimum, the ambient color. For this reason I cannot understand why some faces are being lit in the bottom of the surface, having in mind that all normals are pointing to the other side of the surface.

Maybe I am missing something, I have spent many hours but I am not able to find the reason of this.
Quote:
When the angle is greater than 90º (when the light is at the back of the face), the dot product is negative, and because this result doesn't have sense, the color of the face should be the minimum, the ambient color. For this reason I cannot understand why some faces are being lit in the bottom of the surface, having in mind that all normals are pointing to the other side of the surface.


I think you're confusing the light position with the camera position. In your case(if I understand correctly), the light position stays the same. (Same normals) + (same light position) = same lighting. It's the camera that moves. When you're "below" the mesh, the normals have an angle greater than 90 in respect to the camera. They still face the light as always.
My mistake, I forgot to say that in my program the light moves with the camera. It is behind the camera.
I will try to explain it in other way:

If you have this:

light-> camera-> |face|--normal-->

Then that face shouldn't be lit, right? This is the same situation I have in my program, and there are some faces that are lit.
Ok, just because the normal points to one side of the plane, and the light vector to the opposite, doesn't mean that the angle between them is greater then 90. I think this image will help understanding it:



As you can see, it is possible for the light to be "below" the plane and still light that point. Of course, in reality it wouldn't be possible because as you can see the light vector is "blocked" by the mesh, but GL lighting doesn't take that into account. Kippesoep is right, unless you're implement shadows as well, you will get that.
Ok, but the problem is that the light moves along with the camera, so it's always behind the camera.

So in my case it's like that:



The faces that have an angle < 90º are not visible from that view point. And please have in mind that the surface I am representing is like a grid, so that the x and y distance beetween adjacent vertices is constant.

Maybe I am just retarded and cannot find a situation where a face can be lit, taking into account that the light is always behind the camera.

Thanks for spending time in drawing the image :)

This topic is closed to new replies.

Advertisement