I've read some tutorials about Phong and Blinn lighting models and tried to implement a rendered myself. To my knowledge, the basic approach consists of the following steps:

  • calculate the vector from the current fragment to the light rayToLight (and normalize it)
  • calculate the diffuse color intensity using diffuseIntensity = max(dot(rayToLight, normal))
  • calculate the vector from the current fragment and the camera rayToCamera (and normalize it)
  • reflect rayToLight: reflected = reflect(-rayToLight, normal)
  • calculate the specularIntensity = pow(max(dot(reflected, rayToCamera), 0.0), shininess).

The problem is that specularIntensity ( dot(reflected, rayToCamera) to be precise), can be non-zero even if the light and the camera are on the opposite sides of a surface. Take the following example enter image description here It is possible that the angle between reflected and rayToCamera is less than 90 deg even if the camera and the light are on the opposite sides of a surface. This means that despite the surface is not lit by the diffuse light, it can show specular reflections which is, of course, not wanted. I wasn't aware of this problem until it occurred when I was trying to implement a simple phong lighting model.

Have I done something wrong or is it just the way it should work? Thanks

  • $\begingroup$ yes it's necessary to check whether dot(light_dir, norm) is positive or not. If negative we don't need to include specular component. $\endgroup$ Jun 12, 2019 at 14:48
  • $\begingroup$ I see, I wonder why the majority of tutorials don't bring up this caveat. Thank you very much @gallickgunner . Feel free to add your comment as an answer as it is exactly what I was looking for. $\endgroup$ Jun 12, 2019 at 15:01


Your Answer

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

Browse other questions tagged or ask your own question.