Last active
December 14, 2016 13:25
-
-
Save HogJonnyMaxPlay/f9a4f5f9e57042271add to your computer and use it in GitHub Desktop.
This is a typical game shader snippet for lighting/specular. It doesn't conserve energy, so I don't think it's proper PBR. It can probably use a few tweaks.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// shadertype=hlsl | |
float G1V(float NdotV, float k) | |
{ | |
return 1.0f / (NdotV * (1.0f - k) + k); | |
} | |
float SchlickFresnel(float u) | |
{ | |
float m = clamp(1 - u, 0, 1); | |
float m2 = m*m; | |
return m2*m2*m; // pow(m,5) | |
} | |
struct lightOut | |
{ | |
float Specular; | |
float3 Color; | |
}; | |
lightOut smlBRDF(float3 L, float3 V, float3 N, float3 Albedo) | |
{ | |
lightOut OUT = (lightOut)0; | |
OUT.Color = float3(0.0f, 0.0f, 0.0f); | |
OUT.Specular = 0.0f; | |
float alpha = roughness * roughness; | |
float3 H = normalize( L + V ); | |
float NdotL = saturate( dot( N, L ) ); | |
float NdotV = saturate( dot( N, V ) ); | |
float NdotH = saturate( dot( N, H ) ); | |
float LdotH = saturate( dot( L, H ) ); | |
float F, D, vis; | |
// V ... calc visability term | |
float k = alpha / 2.0f; | |
vis = G1V(NdotL, k) * G1V(NdotV, k); | |
float3 Cdlin = Albedo.rgb; // pass in color already converted to linear | |
float Cdlum = 0.3f * Cdlin[0] + 0.6f * Cdlin[1] + 0.1f * Cdlin[2]; // luminance approx. | |
float3 Ctint = Cdlum > 0.0f ? Cdlin/Cdlum : 1.0f.xxx; // normalize lum. to isolate hue+sat | |
float3 Cspec0 = lerp(specular * 0.08f * lerp(1.0f.xxx, Ctint, specularTint), Cdlin, metalness); | |
float3 Csheen = lerp(1.0f.xxx, Ctint, sheenTint); | |
// D | |
float alphaSqr = alpha*alpha; | |
float denom = NdotH * NdotH * (alphaSqr-1.0f) + 1.0f; | |
D = alphaSqr / (PI * denom * denom); | |
// F | |
float LdotH5 = pow(1.0f-LdotH, 5.0f); | |
float F0 = SchlickFresnel(LdotH); | |
F = F0 + (1.0f-F0) * (LdotH5); | |
float3 Fs = lerp(Cspec0, 1.0f.xxx, F); | |
float specularBRDF = D * Fs * vis * NdotL; | |
OUT.Specular = specularBRDF * Cspec0; | |
OUT.Color = INV_PI * ( 1.0 - metalness ) * Cdlin; | |
OUT.Color *= NdotL; | |
return OUT; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment