Jump to content
  • Advertisement
Sign in to follow this  
SourceDude22

Blinn Phong Normalization

This topic is 938 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

Hello, 

 

Im working with the Source engine, and im wondering about the correct and best way of implementation of normalizing blinn phong

 

 

Here is the default implementation of the basic brdf in source.

 

All this code is publicly available on their source 2013 github page.

 

 

 

/////diffuse term is;
 


float3 DiffuseTerm(const bool bHalfLambert, const float3 worldNormal, const float3 lightDir,
  const bool bDoLightingWarp, in sampler lightWarpSampler )
{
float fResult;

float NDotL = dot( worldNormal, lightDir ); // Unsaturated dot (-1 to 1 range)

fResult = saturate( NDotL ); // Saturate pure Lambertian term

float3 fOut = float3( fResult, fResult, fResult );


return fOut;
}
 

and main implementation is

diffuseLighting = vColor * fAtten * DiffuseTerm( bHalfLambert, worldNormal, lightDir, bDoLightingWarp, lightWarpSampler );


float3 vHalfAngle = normalize( vEyeDir.xyz + vLightDir.xyz );
float flNDotH = saturate( dot( vWorldNormal.xyz, vHalfAngle.xyz ) );


specularLighting = SourceBlinn(vWorldNormal,vEyeDir, vLightDir, fSpecularExponent); 
specularLighting *= pow( saturate( dot( vWorldNormal, vLightDir ) ), 0.5 ); // Mask with N.L raised to a power
specularLighting *= color;

float3 diffuseComponent = albedo * diffuseLighting;

final =  diffuseComponent + specularLighting

This is the default implementation of BlinnPhong ;

half SourceBlinn(half3 vWorldNormal, half3 vEyeDir, half3 vLightDir, half Expo)
{
 
  float3 vHalfAngle = normalize( vEyeDir.xyz + vLightDir.xyz );
  return  pow( saturate(dot(vWorldNormal, vHalfAngle)),    Expo);
    
}

and then Cryengine's Normalized.

#define ONE_OVER_PI 0.31831h
#define ONE_OVER_TWO_PI 0.159155h

half SourceBlinnCE(half3 vWorldNormal, half3 vEyeDir, half3 vLightDir, half Expo)
{
  half fNormFactor = Expo * ONE_OVER_TWO_PI + ONE_OVER_PI;	

  float3 vHalfAngle = normalize( vEyeDir.xyz + vLightDir.xyz );
  return fNormFactor * pow( saturate(dot(vWorldNormal, vHalfAngle)),    Expo+1e-6); <-- cryengine also adds this modification
    
}

Would this be the correct way of doing it?

Similar to how its done in Cryengine I think.

Every engine that I have looked at so far has implemented it different.

 

 

Marmoset does;


half Marmo(half3 N, half3 V, half3 L, half Expo)
{
	
  half3 H = normalize(V + L);

  half fNormFactor = (Expo + 4.0)/(8.0*3.141592);	

  return fNormFactor *  pow(saturate(dot(N, H)), Expo);
 }

But I have also seen;

 half fNormFactor = (Expo + 2.0) / 8.0; ... with seemingly no adjustment to the diffuse portion of the brdf.

Also  half fNormFactor =  (Expo+8.0) / 8.0;


Edited by SourceDude22

Share this post


Link to post
Share on other sites
Advertisement

The right way to do it depends on the rest of the BRDF. You're not just normalizing the Blinn Phong function -- you're normalizing the whole BRDF.

 

The most common one I've seen would be fNormFactor = (Expo + 1) * ONE_OVER_TWO_PI;

Share this post


Link to post
Share on other sites

Thanks Hodgman, ive updated my first post with the rest of the brdf. 

 

Ive seen so manyyyyy different implementations.

Edited by SourceDude22

Share this post


Link to post
Share on other sites

Another form of the normal distribution func for binn-phong is 1/(pi*a^2)*(n.m)^(2/a^2-2), according to ue4 implementations, assume a=roughness^2.

Edited by neoragex

Share this post


Link to post
Share on other sites
^^ that previous post is relating to physically based shading, and isn't applicable to normalisation of your brdf in this case. Hopefully someone with more knowledge can drop by and explain the correct way to normalise sources shading. Sorry I can't be much help.

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.

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!