I implemented the Lafortune shader in WebGL, and my biggest concern is about this formula:

enter image description here


Kd/Ks is the material diffuse/specular color, ρd/ρs is the light diffuse/specular component, m is the number of lobes (in my shader I always use a single lobe), 𝜔o is the viewer direction (from the surface point), 𝜔i is the light direction, Oj is the lobe and ej is the shininess factor.
Full reference is here: A survey of shading models for real-time rendering, at page 28.


The problem comes with the Oj lobe. I realized that as I change the value of Oj, the light gets displaced from it's original position, for example that's what I get with Oj= (-1,-1,1):

enter image description here

And that's what I get with Oj=(0,0,1):

enter image description here

Is that behavior normal? Should the light get displaced according to the value of Oj?

  • \$\begingroup\$ Lafortune's BRDF model is described in detail (including example source code) in this GPU Gems article. \$\endgroup\$
    – MooseBoys
    Jan 16 '14 at 23:35
  • \$\begingroup\$ I also added my reference editing the question. \$\endgroup\$ Jan 16 '14 at 23:55

Yes, absolutely, it is expected that somehow the light appears to be at a different place if you change the main lobe’s properties without considering what it means physically.

The lobes describe, for a given incident light direction, in which directions light is going to be re-emitted. Here are a few examples of possible lobes: a perfect specular reflection lobe (for the Phong model), an off-specular lobe, and a retroreflection lobe (as is the case for catadioptric surfaces).


You are probably familiar with the specular highlight. When the surface is very shiny, it is the area around which the most re-emitted light reaches the viewer’s eye. This happens where the light direction and the viewer direction are exactly reflected (i.e. the view vector is close to the R vector above).

In the case of retroreflection there is a highlight, too, but that highlight is located where the light and viewer direction are close to each other (i.e. the view vector is close to the L vector).

Here is an example of highlighted areas in those two different cases:


As you can see, depending on the lobe, and even if the light does not move, the highlights can be at very different locations.

In your specific case, you chose Oj = [0,0,1]. It means that whatever the direction of the incident light, the most light will always be re-emitted along the surface’s normal. In other words, the highlight will be located where the view vector is facing the surface normal. And this is precisely what your second screenshot shows.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.