Jump to content
  • Advertisement
Sign in to follow this  
Aqua Costa

Specular Power = 0

This topic is 2198 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

Today I found a new bug in my engine, after some debugging I found that it happened because I added a new material that had a specular power = 0, so when the HdV = 0 it caused an exception 0^0, and the luminance calculated at those pixels was a NaN and the average luminance of the scene was also NaN so the tonemapped scene resulted in black screen.

I fixed it by adding a small value (0.0001) to the specular power stored in the gbuffer before doing HdV^power, but I was wondering if this is usual or I'm doing something else wrong...

Share this post


Link to post
Share on other sites
Advertisement
ya i had the same problem and stuck an if (isnan(blabla)) in my pixel shader as a temporary fix, I am interested to hear better ways to solve this.

Share this post


Link to post
Share on other sites
Yeah that will happen because of the way GPU's typically approximate the pow() function. A lot of renderers I know of won't actually work with specular power for the most part, and will instead work with some [0, 1] value that they call "glossiness" or "shininess". This is usually more intuitive for artists, and is also more conducive to storing the value in a G-Buffer or a specular map. Then as a final step you just convert it to a specular power if you're doing Blinn-Phong, and as part of that you can make sure that your power never goes below 1.0. So for instance you might do something simple like "specPower = 1.0f + glossiness * 4095.0f", or something a little more complicated like "specPower = exp2(glossiness * 12.0f)".

Share this post


Link to post
Share on other sites
Exactly, I ran into this a dozen times. But not only with specular shaders, also everywhere else, where you call the pow() function. Just be sure NOT to call it with a negative number as the first parameter. Clamp. It's similar as with not dividing by zero :-)

Share this post


Link to post
Share on other sites
zero bases break pow as well on GPUs since the pow is basically:

float pow(float base, float exponent)
{
return exp2(log2(v), exponent);
}

The fix is to either call max(v, very_small_number ) or something like


float mypow(float base, float exponent)
{
return base > very_small_number ? exp2(log2(v), exponent) : 0;
}


And you get to sit down and tune your own very_small_number for whatever you are working on.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!