Skip to content

Commit

Permalink
Visibility functions with different levels of exactness. (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
roeas authored Apr 2, 2024
1 parent 2d6e17c commit a0eef0f
Showing 1 changed file with 31 additions and 12 deletions.
43 changes: 31 additions & 12 deletions Engine/BuiltInShaders/common/BRDF.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,36 @@ float DistributionGGX(float NdotH, float rough) {
return a2 * CD_PI_INV * denom_inv * denom_inv;
}

// Geometry
float Visibility(float NdotV, float NdotL, float rough) {
// Specular BRDF = (F * D * G) / (4 * NdotV * NdotL)
// = (F * D * (NdotV / (NdotV * (1 - K) + K)) * (NdotL / (NdotL * (1 - K) + K))) / (4 * NdotV * NdotL)
// = (F * D * (1 / (NdotV * (1 - K) + K)) * (1 / (NdotL * (1 - K) + K))) / 4
// = F * D * Vis
// Vis = 1 / (NdotV * (1 - K) + K) / (NdotL * (1 - K) + K) / 4
float Visibility_HighQuality(float NdotV, float NdotL, float rough) {
// BRDF = (F * D * G) / (4 * NdotV * NdotL) = F * D * V
// V = G / (4 * NdotV * NdotL)
// = 0.5 / (NdotL * sqrt(a2 + (1 - a2) * NdotV^2) + NdotV * sqrt(a2 + (1 - a2) * NdotL^2))

// rough = (rough + 1) / 2, by Disney
// a = rough^2
float a2 = pow((rough + 1.0) * 0.5, 4);
float lambda_v = NdotL * sqrt(a2 + (1.0 - a2) * NdotV * NdotV);
float lambda_l = NdotV * sqrt(a2 + (1.0 - a2) * NdotL * NdotL);
return 0.5 / (lambda_v + lambda_l);
}
float Visibility_LowQuality(float NdotV, float NdotL, float rough) {
// BRDF = (F * D * G) / (4 * NdotV * NdotL) = F * D * V
// V = G / (4 * NdotV * NdotL)
// = 1 / ((NdotV * (2 - a) + a) * (NdotL * (2 - a) + a))

// rough = (rough + 1) / 2, by Disney
// a = rough^2
float a = (rough + 1.0) * (rough + 1.0) * 0.25;
float g1_v_inv = NdotV * (2.0 - a) + a;
float g1_l_inv = NdotL * (2.0 - a) + a;

float f = rough + 1.0;
float k = f * f * 0.125;
float ggxV = 1.0 / (NdotV * (1.0 - k) + k);
float ggxL = 1.0 / (NdotL * (1.0 - k) + k);
return ggxV * ggxL * 0.25;
return 1.0 / (g1_v_inv * g1_l_inv);
}

// Geometry
float Visibility(float NdotV, float NdotL, float rough) {
// TODO : Wrap them in macros after we've collected enough approximate / exact formulas.
return Visibility_LowQuality(NdotV, NdotL, rough);
}

0 comments on commit a0eef0f

Please sign in to comment.