diff options
| author | yum <yum.food.vr@gmail.com> | 2026-03-16 16:22:45 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2026-03-16 16:22:45 -0700 |
| commit | 0b42d463db23d2c6eb0b6651486912ffed2f8857 (patch) | |
| tree | 20fc0398a794429146b7875ae6f655b01ab414de /pbr.cginc | |
| parent | 1a35d85c623569dd2e61b821bfe3a7f03f99343f (diff) | |
Fix normal filtering, which fixes both IBL and direct lighting flashing
Diffstat (limited to 'pbr.cginc')
| -rwxr-xr-x | pbr.cginc | 28 |
1 files changed, 13 insertions, 15 deletions
@@ -94,31 +94,28 @@ float2 parallax_offset(float2 uv, float3 view_dir_world, float3x3 tbn) { } #endif // _PARALLAX_HEIGHTMAP -// Tokuyashi and Kaplanyan 2019 "Improved Geometric Specular Antialiasing" -float normalFiltering(float3 normal, float perceptual_roughness) { - float3 du = ddx(normal); - float3 dv = ddy(normal); +// Tokuyoshi and Kaplanyan 2019 "Improved Geometric Specular Antialiasing" +float normalFiltering(float3 geometric_normal, float perceptual_roughness) { + float3 du = ddx(geometric_normal); + float3 dv = ddy(geometric_normal); - // Boxed equation in section 3.2 "Proposed Error Reduction." - float variance = dot(du, du) + dot(dv, dv); - float sigma = 0.5f; // standard deviation of pixel filter kernel in image space - float Sigma = sigma * sigma * variance; - - // Equation 1 in section 4.2 "Constraint for Conservative Isotropic Filtering" + float variance = _Specular_AA_Variance * (dot(du, du) + dot(dv, dv)); float roughness = perceptual_roughness * perceptual_roughness; - float kappa = 0.18; - roughness = roughness + min(2 * Sigma, kappa); + float kernel_roughness = min(2.0f * variance, _Specular_AA_Threshold); + float square_roughness = saturate(roughness * roughness + kernel_roughness); - return saturate(sqrt(roughness)); + return saturate(sqrt(sqrt(square_roughness))); } void propagateSmoothness(inout Pbr pbr) { - pbr.smoothness = 1.0f - normalFiltering(pbr.normal, 1.0f - pbr.smoothness); + pbr.smoothness = 1.0f - normalFiltering(pbr.geometric_normal, 1.0f - pbr.smoothness); pbr.roughness_perceptual = clamp(1.0f - pbr.smoothness, MIN_PERCEPTUAL_ROUGHNESS, 1); pbr.roughness = clamp(pbr.roughness_perceptual * pbr.roughness_perceptual, MIN_ROUGHNESS, 1); #if defined(_CLEARCOAT) - pbr.cc_roughness = max(MIN_ROUGHNESS, pbr.cc_roughness * pbr.cc_roughness); + pbr.cc_roughness_perceptual = clamp(pbr.cc_roughness_perceptual, MIN_PERCEPTUAL_ROUGHNESS, 1); + pbr.cc_roughness_perceptual = normalFiltering(pbr.geometric_normal, pbr.cc_roughness_perceptual); + pbr.cc_roughness = max(MIN_ROUGHNESS, pbr.cc_roughness_perceptual * pbr.cc_roughness_perceptual); #endif } @@ -181,6 +178,7 @@ Pbr getPbr(v2f i) { Pbr pbr = (Pbr) 0; float3 n = i.normal; + pbr.geometric_normal = n; float3 t = i.tangent.xyz; t = normalize(t - n * dot(n, t)); // Gram-Schmidt to avoid skew float3 b = normalize(cross(n, t)) * i.tangent.w; |
