Question about per pixel lighting equation

I’m implementing light per pixel equations (phong/blinn shading), however there are some cases where lighting appears wrong… however, the math behind the problem seems to be logical, so i’m now in doubt wether i’m implementing the light model properly.

Basically, Let’s say i have a box. Light is directional and orthogonal to one of the faces (should fully illuminate only one ). In this same case, light is pointing towards the viewer like in this case:

Now, I have a phong equation for specular lighting… where the light is reflected by the normal of the fragment, then a dot product is computed with the (negated) eye vector (alpha) and clamped to positive. However, in this example, alpha is positive and with low specular exponent (say, 2) you can see light reflected on the side of the box (as in, is this supposed to be ok?). Code is like this:


// specular only //

float NdotL = max(dot(normal, -light_direction), 0.0);

if (NdotL > 0) {
    vec3 light_ref = reflect( light_direction, normal );
    float eye_light = max( dot( light_ref, -eye_vector),0.0 );
    color += specular.rgb * light_specular.rgb * pow( eye_light, specular_exp);			
}

Now, where is the problem:

  1. Given the phong equation, it seems like something possible that the side of the face can reflect light like in the case example (being light orthogonal)
  2. Given 1) because of floating point precision, NdotL > 0 sometimes holds true and sometimes holds (light and normal completely orthogonal) false so i can see flickering (intermitent) lighting on the side of the box while rotating it.

So, I feel i may be ignoring somthing or not getting the point on something, so this post is for asking to someone who understands this problem better to explain me what is the right way to do this!

  1. yes it is possible. Why ? Because phong/blinn/etc are all local illumination models. So the only truly real case is exponent = +infinity. All others are approximations of more realistic global illumitation models.
    Very low exponent are used for very rough surface, such as dust, fur, etc, to approximate specular light reflecting from each of the micro facets of the material.
    But with a local model, you only take in account 1 direction toward the light. To the contray, with a global illumintation (GI) model, each fragment will re-trace rays in all directions and sum all indirect received lighting. Of course this is extremely costly performance wise.

In practice, cast shadows allow to cut the “bleeding” of low exponents, but may increase the problem on 2) …

  1. instead of a test, try to smoothstep the transition.
    http://www.opengl.org/discussion_boards/…8824#Post248824
    http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=239398#Post239398