Skip to content

Commit 8d792db

Browse files
Add GLSL functions for PDFs (#2779)
This changelist adds explicit GLSL functions for PDFs (probability density functions) to MaterialX, making its physically based shading code clearer and more self-documenting, and providing a stepping stone towards future use of generated GLSL/ESSL/MSL in path tracers as well as rasterization renderers.
1 parent 71ae1fc commit 8d792db

5 files changed

Lines changed: 23 additions & 6 deletions

File tree

libraries/pbrlib/genglsl/lib/mx_environment_fis.glsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distributio
3333

3434
// Sample the environment light from the given direction.
3535
vec3 Lw = mx_matrix_mul(tangentToWorld, L);
36-
float pdf = mx_ggx_NDF(H, alpha) * G1V / (4.0 * NdotV);
36+
float pdf = mx_ggx_VNDF_reflection_PDF(H, alpha, G1V, NdotV);
3737
float lod = mx_latlong_compute_lod(Lw, pdf, float($envRadianceMips - 1), envRadianceSamples);
3838
vec3 sampleColor = mx_latlong_map_lookup(Lw, $envMatrix, lod, $envRadiance);
3939

libraries/pbrlib/genglsl/lib/mx_generate_prefilter_env.glsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ vec3 mx_generate_prefilter_env()
5353

5454
// Sample the environment light from the given direction.
5555
vec3 Lw = mx_matrix_mul(tangentToWorld, L);
56-
float pdf = mx_ggx_NDF(H, vec2(alpha)) * G1V / (4.0 * NdotV);
56+
float pdf = mx_ggx_VNDF_reflection_PDF(H, vec2(alpha), G1V, NdotV);
5757
float lod = mx_latlong_compute_lod(Lw, pdf, float($envRadianceMips - 1), envRadianceSamples);
5858
vec3 sampleColor = mx_latlong_map_lookup(Lw, $envMatrix, lod, $envRadiance);
5959

libraries/pbrlib/genglsl/lib/mx_microfacet.glsl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,18 @@ vec3 mx_cosine_sample_hemisphere(vec2 Xi)
9393
cosTheta);
9494
}
9595

96+
// PDF of a cosine-weighted hemisphere sample.
97+
float mx_cosine_hemisphere_PDF(float cosTheta)
98+
{
99+
return max(cosTheta, 0.0) * M_PI_INV;
100+
}
101+
102+
// PDF of a uniform hemisphere sample.
103+
float mx_uniform_hemisphere_PDF()
104+
{
105+
return 0.5 * M_PI_INV;
106+
}
107+
96108
// Construct an orthonormal basis from a unit vector.
97109
// https://graphics.pixar.com/library/OrthonormalB/paper.pdf
98110
mat3 mx_orthonormal_basis(vec3 N)

libraries/pbrlib/genglsl/lib/mx_microfacet_sheen.glsl

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,8 @@ float mx_imageworks_sheen_dir_albedo_monte_carlo(float NdotV, float roughness)
7070
float reflectance = mx_imageworks_sheen_brdf(NdotL, NdotV, NdotH, roughness);
7171

7272
// Add the radiance contribution of this sample.
73-
// uniform_pdf = 1 / (2 * PI)
7473
// radiance = reflectance * NdotL / uniform_pdf;
75-
radiance += reflectance * NdotL * 2.0 * M_PI;
74+
radiance += reflectance * NdotL / mx_uniform_hemisphere_PDF();
7675
}
7776

7877
// Return the final directional albedo.
@@ -153,7 +152,7 @@ float mx_zeltner_sheen_brdf(vec3 L, vec3 V, vec3 N, float NdotV, float roughness
153152
// = Do(wo) . |M^-1| / dot(wo, wo)^2
154153
// = Do(wo) . aInv^2 / dot(wo, wo)^2
155154
// = Do(wo) . (aInv / dot(wo, wo))^2
156-
return max(wo.z, 0.0) * M_PI_INV * mx_square(aInv / lenSqr);
155+
return mx_cosine_hemisphere_PDF(wo.z) * mx_square(aInv / lenSqr);
157156
}
158157

159158
vec3 mx_zeltner_sheen_importance_sample(vec2 Xi, vec3 V, vec3 N, float roughness, out float pdf)
@@ -180,7 +179,7 @@ vec3 mx_zeltner_sheen_importance_sample(vec2 Xi, vec3 V, vec3 N, float roughness
180179
// = Do(w) . ||M.wo||^4 / |M| (possible because M doesn't change z component)
181180
// = Do(w) . dot(w, w)^2 * aInv^2
182181
// = Do(w) . (aInv * dot(w, w))^2
183-
pdf = max(w.z, 0.0) * M_PI_INV * mx_square(aInv * lenSqr);
182+
pdf = mx_cosine_hemisphere_PDF(w.z) * mx_square(aInv * lenSqr);
184183

185184
mat3 fromLTC = mx_orthonormal_basis_ltc(V, N, NdotV);
186185
w = mx_matrix_mul(fromLTC, w);

libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ vec3 mx_ggx_importance_sample_VNDF(vec2 Xi, vec3 V, vec2 alpha)
6161
return H;
6262
}
6363

64+
// PDF of a reflection direction sampled from the GGX VNDF.
65+
float mx_ggx_VNDF_reflection_PDF(vec3 H, vec2 alpha, float G1V, float NdotV)
66+
{
67+
return mx_ggx_NDF(H, alpha) * G1V / (4.0 * NdotV);
68+
}
69+
6470
// https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf
6571
// Equation 34
6672
float mx_ggx_smith_G1(float cosTheta, float alpha)

0 commit comments

Comments
 (0)