From b11eecd7e4bf9cd5d1cdf95a5e995a39c59ca4bf Mon Sep 17 00:00:00 2001 From: yum Date: Tue, 11 Nov 2025 17:04:08 -0800 Subject: cc energy compensation --- brdf.cginc | 22 ++++++++++++++++++---- lighting.cginc | 3 +-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/brdf.cginc b/brdf.cginc index 46b28e8..3a0db4c 100644 --- a/brdf.cginc +++ b/brdf.cginc @@ -145,6 +145,20 @@ float4 brdf(Pbr pbr, LightData data) { dfg = float3(1, 1, 1); } +#if defined(_CLEARCOAT) + const float cc_f0 = 0.04f; + float2 cc_dfg_uv = float2(pbr.cc_roughness, data.common.NoV_cc); + float3 cc_dfg; + [branch] + if (textureExists(_DFG_LUT)) { + cc_dfg = _DFG_LUT.SampleLevel(bilinear_clamp_s, cc_dfg_uv, 0).rgb; + } else { + cc_dfg = float3(1, 1, 1); + } + float cc_Ess = max(cc_dfg.y, 1e-4f); + 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); // Direct @@ -152,12 +166,12 @@ float4 brdf(Pbr pbr, LightData data) { float3 remainder = 1.0f; #if defined(_CLEARCOAT) - float cc_f0 = 0.04f; float Fcc = F_Schlick(data.direct.LoH, cc_f0, f90); float Dcc = D_GGX(pbr.cc_roughness, data.direct.NoH_cc); float Gcc = G_GGXSmith(pbr.cc_roughness, data.direct.NoL_cc, data.common.NoV_cc); float DFGcc = Fcc * Dcc * Gcc; float3 direct_specular_cc = DFGcc * data.direct.color * data.direct.NoL_cc * pbr.cc_strength; + direct_specular_cc *= cc_energy_comp; direct_specular_cc = max(0, direct_specular_cc); specular += direct_specular_cc; remainder = saturate(remainder - direct_specular_cc); @@ -203,9 +217,9 @@ float4 brdf(Pbr pbr, LightData data) { float3 remainder = 1.0f; #if defined(_CLEARCOAT) - float cc_f0 = 0.04f; - float Fcc = F_Schlick(data.common.NoV, cc_f0, 1.0f); - float3 indirect_specular_cc = Fcc * data.indirect.specular_cc * pbr.cc_strength; + float cc_single_scatter = cc_f0 * cc_dfg.x + cc_dfg.y; + float3 indirect_specular_cc = data.indirect.specular_cc * (cc_single_scatter * cc_energy_comp) * pbr.cc_strength; + indirect_specular_cc = max(0, indirect_specular_cc); specular += indirect_specular_cc; remainder = saturate(remainder - indirect_specular_cc); #endif diff --git a/lighting.cginc b/lighting.cginc index cb3160a..4e5a61b 100644 --- a/lighting.cginc +++ b/lighting.cginc @@ -198,7 +198,7 @@ void GetLighting(v2f i, Pbr pbr, out LightData data) { data.indirect.LoH_cc = saturate(dot(dir_cc, H_cc)); #endif data.indirect.LoH = saturate(dot(data.indirect.dir, data.indirect.H)); - float indirect_LoV = dot(data.direct.dir, data.common.V); + float indirect_LoV = dot(data.indirect.dir, data.common.V); data.indirect.LoV = saturate(indirect_LoV); data.indirect.double_LoV = saturate(2.0f * indirect_LoV * indirect_LoV - 1.0f); @@ -214,4 +214,3 @@ void GetLighting(v2f i, Pbr pbr, out LightData data) { } #endif // __LIGHTING_INC - -- cgit v1.2.3