From e851efa0a84353f53ea6ef2b2f108ff0c07d0844 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 10 Feb 2026 22:50:32 +0100 Subject: [PATCH] Fix applying AO twice for lighting in Forward shading and use correct specular occlusion on reflections #3717 --- .../MaterialTemplates/Features/ForwardShading.hlsl | 6 +++--- Source/Shaders/Reflections.shader | 2 +- Source/Shaders/ReflectionsCommon.hlsl | 9 ++++++++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl index 123201d1e..e1b884734 100644 --- a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl +++ b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl @@ -142,11 +142,11 @@ void PS_Forward( #endif #endif - light.rgb += reflections * GetReflectionSpecularLighting(ViewPos, gBuffer) * light.a; + light.rgb += reflections * GetReflectionSpecularLighting(ViewPos, gBuffer) * light.a; #endif - // Add lighting (apply ambient occlusion) - output.rgb += light.rgb * gBuffer.AO; + // Add lighting + output.rgb += light.rgb; #endif diff --git a/Source/Shaders/Reflections.shader b/Source/Shaders/Reflections.shader index dd0b695e5..c257ca35b 100644 --- a/Source/Shaders/Reflections.shader +++ b/Source/Shaders/Reflections.shader @@ -79,7 +79,7 @@ float4 PS_CombinePass(Quad_VS2PS input) : SV_Target0 // Calculate specular color float3 specularColor = GetSpecularColor(gBuffer); - // Calculate reflecion color + // Calculate reflection color float3 V = normalize(gBufferData.ViewPos - gBuffer.WorldPos); float NoV = saturate(dot(gBuffer.Normal, V)); reflections *= EnvBRDF(PreIntegratedGF, specularColor, gBuffer.Roughness, NoV); diff --git a/Source/Shaders/ReflectionsCommon.hlsl b/Source/Shaders/ReflectionsCommon.hlsl index 87e871edf..4abf295c6 100644 --- a/Source/Shaders/ReflectionsCommon.hlsl +++ b/Source/Shaders/ReflectionsCommon.hlsl @@ -48,10 +48,17 @@ float4 SampleReflectionProbe(float3 viewPos, TextureCube probe, ProbeData data, // Calculates the reflective environment lighting to multiply the raw reflection color for the specular light (eg. from Env Probe or SSR). float3 GetReflectionSpecularLighting(float3 viewPos, GBufferSample gBuffer) { + // Calculate reflection color float3 specularColor = GetSpecularColor(gBuffer); float3 V = normalize(viewPos - gBuffer.WorldPos); float NoV = saturate(dot(gBuffer.Normal, V)); - return EnvBRDFApprox(specularColor, gBuffer.Roughness, NoV); + float3 reflections = EnvBRDFApprox(specularColor, gBuffer.Roughness, NoV); + + // Apply specular occlusion + float roughnessSq = gBuffer.Roughness * gBuffer.Roughness; + reflections *= GetSpecularOcclusion(NoV, roughnessSq, gBuffer.AO); + + return reflections; } #endif