Skip to content

Instantly share code, notes, and snippets.

@FeodorVolguine
Last active March 25, 2024 14:30
Show Gist options
  • Save FeodorVolguine/3e09c3207339cf297f8cff205bbb1d4c to your computer and use it in GitHub Desktop.
Save FeodorVolguine/3e09c3207339cf297f8cff205bbb1d4c to your computer and use it in GitHub Desktop.
Physically Based Shading
//Normal distribution function (Trowbridge-Reitz GGX)
float DistributionGGX(float NdotH, float alpha2)
{
float f = (NdotH * alpha2 - NdotH) * NdotH + 1.0f;
return alpha2 / (f * f * PI);
}
//Height-correlated Smith-GGX visibility function
float VisibilitySmithGGX(float NdotL, float NdotV, float alpha2)
{
float SchlickGGX_V = NdotL * sqrt((-NdotV * alpha2 + NdotV) * NdotV + alpha2);
float SchlickGGX_L = NdotV * sqrt((-NdotL * alpha2 + NdotL) * NdotL + alpha2);
return 0.5f / (SchlickGGX_V + SchlickGGX_L);
}
//Approximated height-correlated Smith-GGX visibility function
float FastVisibilitySmithGGX(float NdotL, float NdotV, float alpha)
{
return 0.5f / mix(2.0f * NdotL * NdotV, NdotL + NdotV, alpha);
}
//Schlick Fresnel function
vec3 FresnelSchlick(float cosTheta, vec3 f0, float f90)
{
//float factor = pow(1.0f - cosTheta, 5);
float factor = 1.0f - cosTheta;
float factor2 = factor * factor;
factor = factor2 * factor2 * factor;
return f0 + (vec3(f90) - f0) * factor;
}
//Schlick Fresnel function with f90 = 1
vec3 FresnelSchlick(float cosTheta, vec3 f0)
{
//float factor = pow(1.0f - cosTheta, 5);
float factor = 1.0f - cosTheta;
float factor2 = factor * factor;
factor = factor2 * factor2 * factor;
return factor + f0 * (1.0f - factor);
}
//https://seblagarde.wordpress.com/2011/08/17/hello-world/
//Schlick Fresnel function with injected roughness term
vec3 FresnelSchlickRoughness(float cosTheta, vec3 f0, float alpha)
{
//float factor = pow(1.0f - cosTheta, 5);
float factor = 1.0f - cosTheta;
float factor2 = factor * factor;
factor = factor2 * factor2 * factor;
return f0 + (max(vec3(1.0f - alpha), f0) - f0) * factor;
}
//Burley, Brent, "Physically-Based Shading at Disney",
//part of "Practical Physically Based Shading in Film and Game Production",
//SIGGRAPH 2012 Course Notes. http://blog.selfshadow.com/publications/s2012-shading-course/
//Energy-renormalized Disney diffuse BRDF
float DiffuseBurley(float NdotV, float NdotL, float LdotH, float linearRoughness)
{
float energyBias = mix(0.0f, 0.5f, linearRoughness);
float energyFactor = mix(1.0f, 1.0f / 1.51f, linearRoughness);
float f90 = energyBias + 2.0f * LdotH * LdotH * linearRoughness;
float lightScatter = FresnelSchlick(NdotL, vec3(1.0f), f90).x;
float viewScatter = FresnelSchlick(NdotV, vec3(1.0f), f90).x;
return lightScatter * viewScatter * energyFactor / PI;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment