# 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;

Result:

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).

Question:
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 on other sites
2 hours ago, cozzie said:

floa﻿t 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 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

## 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

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 18
• 13
• 14
• 44
• 63