Jump to content
  • Advertisement
Sign in to follow this  

DX11 Specular normalization (blinn phong)

Recommended Posts

Hi all,

I've been puzzling with my specular highlights, trying to add specular normalization.
Basically applying the theory from this article: https://seblagarde.wordpress.com/tag/specular/

float normFactor = (power + 2.0f) / ( 4.0f * PI * ( 2.0f - (2.0f * (-power / 2.0f) ) ) );

When I apply this in my shader like this, I get basically no more specular at all:

// specular Blinn-phong
float power = pLightSetup.mat.SpecPower;
float normFactor = (power + 2.0f) / ( 4.0f * PI * ( 2.0f - (2.0f * (-power / 2.0f) ) ) );

float tIntensity = pLightSetup.mat.SpecIntensity;

// Blinn-phong specular
float3 HalfWay = normalize(toEye + -dirLight.Direction);
NdotH = saturate(dot(HalfWay, pLightSetup.Normal));
specular = dirLight.ColorIntensity.rgb * pow(NdotH, power) * tIntensity;
specular *= normFactor;



And this is the result if I just comment out the *= normFactor:


I also played around increasing the specular intensity + using normalization, this is with intensity 40.0 and normalization:


Top row = specular power 16, left to right: intensity 0.1, 0.2, 0.4, 0.7, 1.0
Bottom row = intensity 1.0, left to right: power 10, 25, 50, 100, 300.
(in the last screenshot the intensities are multiplied by 40.0f).

The goal of the normalization is to make the sharper (higher power) highlights appear sharp/ strong, and the lower power highlights, be more 'vague'/ rough.

Any thoughts on what I might be doing wrong?
All input is appreciated.

Share this post

Link to post
Share on other sites
2 hours ago, cozzie said:

float normFactor = (power + 2.0f) / ( 4.0f * PI * ( 2.0f - (2.0f * (-power / 2.0f) ) ) );

Shouldn't this be:

(power + 2.0f)/(4.0f*PI*( 2.0f-exp2(-power / 2.0f)))

These equations mention exp2 while you just multiply there, which has quite different effect...

Share this post

Link to post
Share on other sites
Posted (edited)

@noizex you're a life saver, that was it! It works now, screenshot below.
I misread the formula, that few pixels that this part of the formula was 'higher' 😎


I did it by breaking up the formula into pieces, works best for me (I can now combine them again).
Also since this is material dependent and not dependent on the lightsource are resulting light, it's something I can calculate offline to save quite some cycles.

float power = pLightSetup.mat.SpecPower;

float a = power + 2.0f;
float b1 = 4.0f * PI;
float b2 = -power / 2.0f;
float b3 = exp2(b2);

float b = b1 * (2.0f - b3);
float normFactor = a / b;


Edited by cozzie

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Advertisement

Important Information

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

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!