diff options
| author | yum <yum.food.vr@gmail.com> | 2026-03-11 17:35:46 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2026-03-11 17:35:46 -0700 |
| commit | c36b919595874355c511b2c75ba9797440be09a5 (patch) | |
| tree | 1328f04615d58591883c2c7d9de60614975846be /lighting.cginc | |
| parent | c8cfc043c105a32e1efab341536311277bfc90eb (diff) | |
Update specular occlusion; always runs now
Diffstat (limited to 'lighting.cginc')
| -rwxr-xr-x | lighting.cginc | 32 |
1 files changed, 12 insertions, 20 deletions
diff --git a/lighting.cginc b/lighting.cginc index 9ea2052..2e3a79b 100755 --- a/lighting.cginc +++ b/lighting.cginc @@ -34,9 +34,10 @@ float4 getDirectLightColorIntensity() { return float4(_LightColor0.xyz, _LightColor0.w); } -float3 getIndirectSpecular(v2f i, float perceptual_roughness, float3 view_dir, float3 reflect_dir) { +float3 getIndirectSpecular(v2f i, float perceptual_roughness, float3 view_dir, float3 reflect_dir, float3 indirect_diffuse) { UnityGIInput data = InitialiseUnityGIInput(i.worldPos, view_dir); float3 env_refl = UnityGI_prefilteredRadiance(data, perceptual_roughness, reflect_dir); + return env_refl; } @@ -173,35 +174,26 @@ float getAO(v2f i) { } float getSpecularAO(v2f i, Pbr pbr, LightData data, float3 reflect_dir) { - float spec_ao = 1; -#if defined(_AMBIENT_OCCLUSION) || defined(_BENT_NORMALS) float ao_vis = 1.0; #if defined(_AMBIENT_OCCLUSION) ao_vis = data.common.ao; #endif + + // Exposure occlusion: derive specular AO from diffuse irradiance magnitude. + // When IBL diffuse goes dark, attenuate specular to avoid implausible + // reflections. Based on filamented's IrradianceToExposureOcclusion. + float exposure_ao = saturate(length(data.indirect.diffuse) / _Exposure_Occlusion); + ao_vis *= exposure_ao; + #if defined(_BENT_NORMALS) float3 spec_ao_normal = pbr.bent_normal; #else float3 spec_ao_normal = pbr.normal; #endif - spec_ao = computeSpecularAO(data.common.NoV, ao_vis, pbr.roughness, spec_ao_normal, -data.indirect.dir); + float spec_ao = computeSpecularAO(data.common.NoV, ao_vis, pbr.roughness, spec_ao_normal, -data.indirect.dir); #if defined(_BENT_NORMALS) spec_ao = saturate(lerp(1.0, spec_ao, _Bent_Normals_Strength)); #endif -#endif - - // Didn't see a big difference in testbed, so commented out. - // Bent normals get us most of what we want. -#if 0 - // Horizon fading - // https://marmosetco.tumblr.com/post/81245981087 - // The goal is to attenuate anything which points into the mesh. - // TODO expose fade strength as a parameter. - float horizon_fade_str = 1.3; - float horizon_fade = saturate(1.0f + horizon_fade_str * dot(pbr.normal, -reflect_dir)); - horizon_fade *= horizon_fade; - spec_ao *= horizon_fade; -#endif return spec_ao; } @@ -259,13 +251,13 @@ void GetLighting(v2f i, Pbr pbr, out LightData data) { data.indirect.double_LoV = saturate(2.0f * indirect_LoV * indirect_LoV - 1.0f); data.indirect.diffuse = getIndirectDiffuse(i, pbr, data); - data.indirect.specular = getIndirectSpecular(i, pbr.roughness_perceptual, view_dir, data.indirect.dir); + data.indirect.specular = getIndirectSpecular(i, pbr.roughness_perceptual, view_dir, data.indirect.dir, data.indirect.diffuse); data.common.ao = getAO(i); data.common.spec_ao = getSpecularAO(i, pbr, data, reflect_dir); #if defined(_CLEARCOAT) - data.indirect.specular_cc = getIndirectSpecular(i, pbr.cc_roughness_perceptual, view_dir, dir_cc); + data.indirect.specular_cc = getIndirectSpecular(i, pbr.cc_roughness_perceptual, view_dir, dir_cc, data.indirect.diffuse); #if defined(_CLEARCOAT_MASK) float cc_mask = _Clearcoat_Mask.Sample(bilinear_clamp_s, i.uv01.xy).r; data.indirect.specular_cc *= cc_mask; |
