Specular and pow

Hi all,

I am playing around with a simple phong shader and found that the results for a specular exponent (shininess) of zero look very ugly.
This is my code for the specular term:


vec4 Ispec = gl_FrontLightProduct[0].specular
            *pow(max(dot(R,E),0.0),gl_FrontMaterial.shininess);

Obviously the problem is that pow(0.0, 0.0) is undefined. Now I can workaround this by using max(dot(R,E),epsilon) with a very small non zero epsilon value or use an IF statement. As conditional branching is expensive I like to use the epsilon idea, which looks ok to me. But I am not sure if there are any issues with this approach, meaning that it fails in some cases I did not think of.
Thanks in advance for any input.

http://en.wikipedia.org/wiki/Phong_shading

It is said that the “usual” value is 50 for the power exponent.
Indeed, Blender defaults to 50, letting the user enter only integer values between 1 and 511.

Anyway very low exponent values make strongly aliased artifacts near the terminator, so it is not really useful.

The Blinn-Phong specular is better in this area, much less artifacts. And the results feel less artificial to the eye.

Thanks for the info. As OpenGL accepts values between 0 and 128 I wanted my shader to do the same. Perhaps I should rethink this, but values near zero look ok and may be usable for special cases.
I also tried Blinn-Phong but it had a lot of trouble with large triangles. I first thought that it was my fault, but after checking everything I found the information that this is a known problem with Blinn-Phong. If this is indeed correct, then it does not fit my needs.

But the fixed path lighting does use the blinn half vector method :slight_smile:
Anyway, using a small epsilon should be safe enough.

Didn’t you see the heavily aliased terminator whith a very low exponent, for example when the light is mostly behind the object (in a moon crescent configuration) ?

At least this I knew. :slight_smile:

Here I cannot follow you. Can you elaborate?

I hope I can be more explicit with the help of an image :
http://www.highend3d.com/maya/tutorials/…lg_blinn_hi.jpg
In this setup, I will ignore the whiteish light, and only consider the blueish one, shading the top left part of the sphere.
With a classic phong specular with a very low exponent (3 or less), the specular will appear to bleed through the sphere. It will feel strange, but it will be even worse with shadow casting.

Just a small correction, pow(0,0) is defined and equals to one 1.
:wink:

In maths, conventionally, pow(0,0) is defined and equals to 1.

It is also true for the C function pow():

http://www.hmug.org/man/3/POW.php
“pow(x, ±0) returns 1 for any x, even a NaN.”

But for GLSL, the result is undefined. See the GLSL spec 1.20.8, page 57, section “8.2 Exponential Functions”

“Results are undefined if x=0 and y<=0”

Ref: http://www.opengl.org/registry/doc/GLSLangSpec.Full.1.20.8.pdf

Now I get it and it really is a problem. Testing showed that even exponents of 40 or 50 show this bleeding. So I think that you were right from the beginning and I have to use blinn-phong and better tesselated geometry.
Thanks for the input.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.