diff options
| author | yum <yum.food.vr@gmail.com> | 2025-11-11 17:26:35 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2025-11-11 17:26:35 -0800 |
| commit | cb101b9bd1f0e9dbfcfe45d114d1a63af3e85d82 (patch) | |
| tree | 117733c30b5888ad24143e09cd0afa3510048cc3 /brdf.cginc | |
| parent | b11eecd7e4bf9cd5d1cdf95a5e995a39c59ca4bf (diff) | |
fix energy conservation issues; notably smooth=0 metallic=1 matches filamented now
Diffstat (limited to 'brdf.cginc')
| -rw-r--r-- | brdf.cginc | 22 |
1 files changed, 10 insertions, 12 deletions
@@ -136,7 +136,7 @@ float4 brdf(Pbr pbr, LightData data) { data.direct.LoH = 1; #endif - float2 dfg_uv = float2(pbr.roughness, data.common.NoV); + float2 dfg_uv = float2(data.common.NoV, pbr.roughness_perceptual); float3 dfg; [branch] if (textureExists(_DFG_LUT)) { @@ -147,7 +147,8 @@ float4 brdf(Pbr pbr, LightData data) { #if defined(_CLEARCOAT) const float cc_f0 = 0.04f; - float2 cc_dfg_uv = float2(pbr.cc_roughness, data.common.NoV_cc); + float cc_perceptual_roughness = saturate(sqrt(pbr.cc_roughness)); + float2 cc_dfg_uv = float2(data.common.NoV_cc, cc_perceptual_roughness); float3 cc_dfg; [branch] if (textureExists(_DFG_LUT)) { @@ -159,7 +160,9 @@ float4 brdf(Pbr pbr, LightData data) { float cc_energy_comp = 1.0f + cc_f0 * (rcp(cc_Ess) - 1.0f); #endif - float3 F0_color = lerp(float3(f0, f0, f0), pbr.albedo.xyz, pbr.metallic); + float3 f0_color = lerp(f0, pbr.albedo.xyz, pbr.metallic); + float Ess = max(dfg.y, 1e-4f); + float3 energy_comp = 1.0f + f0_color * (rcp(Ess) - 1.0f); // Direct { @@ -197,9 +200,6 @@ float4 brdf(Pbr pbr, LightData data) { FDG = FDG * dfg.x + dfg.y; float3 direct_specular = FDG * remainder * data.direct.color * data.direct.NoL * lerp(1.0f, pbr.albedo.xyz, pbr.metallic); - float Ess = max(dfg.y, 1e-4f); - float invEss = rcp(Ess); - float3 energy_comp = 1.0f + F0_color * (invEss - 1.0f); direct_specular *= energy_comp; direct_specular = max(0, direct_specular); specular += direct_specular; @@ -237,13 +237,11 @@ float4 brdf(Pbr pbr, LightData data) { // Standard PBR IBL using split-sum approximation // Specular lobe float3 f0_spec = lerp(f0, pbr.albedo.xyz, pbr.metallic); - float3 ibl_specular_reflectance = f0_spec * dfg.x + dfg.y; - float3 indirect_specular = data.indirect.specular * ibl_specular_reflectance; - // surface reduction term lifted from here: - // UnityStandardBRDF.cginc :: BRDF1_Unity_PBS - float surface_reduction = 1.0f / (pbr.roughness * pbr.roughness + 1.0f); + float3 ibl_specular_reflectance = lerp(dfg.xxx, dfg.yyy, f0_spec); + float3 indirect_specular = data.indirect.specular * ibl_specular_reflectance * energy_comp; const float F = F_Schlick(data.indirect.NoL, f0_spec, f90); - const float3 is_conserved = surface_reduction * indirect_specular * F; + const float3 is_conserved = indirect_specular * F; + specular += is_conserved; remainder = saturate(remainder - is_conserved); |
