From c516b29b3bdd61de4bfbdbd38aee4ddbce0f3930 Mon Sep 17 00:00:00 2001 From: soda3000 Date: Fri, 13 Mar 2026 17:27:00 -0300 Subject: [PATCH 1/2] fix(pbr): use GTSO, remove ao^2 mult with direct lighting --- package/Shaders/Common/PBR.hlsli | 2 +- package/Shaders/Common/Shading.hlsli | 7 +++++++ package/Shaders/DeferredCompositeCS.hlsl | 5 +---- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/package/Shaders/Common/PBR.hlsli b/package/Shaders/Common/PBR.hlsli index dd8033f4d6..082c49633d 100644 --- a/package/Shaders/Common/PBR.hlsli +++ b/package/Shaders/Common/PBR.hlsli @@ -268,7 +268,7 @@ namespace PBR // Apply ambient occlusion with multi-bounce approximation lobeWeights.diffuse *= MultiBounceAO(material.BaseColor, material.AO); float alpha = material.Roughness * material.Roughness; - lobeWeights.specular *= SpecularOcclusion(NdotV, alpha, material.AO); + lobeWeights.specular *= SpecularOcclusionGTSO(NdotV, material.AO); } } diff --git a/package/Shaders/Common/Shading.hlsli b/package/Shaders/Common/Shading.hlsli index 02be2cf7da..af723eb59c 100644 --- a/package/Shaders/Common/Shading.hlsli +++ b/package/Shaders/Common/Shading.hlsli @@ -10,6 +10,13 @@ float3 MultiBounceAO(float3 baseColor, float ao) return max(ao, ((ao * a + b) * ao + c) * ao); } +// [Jimenez et al. 2016, "Practical Realtime Strategies for Accurate Indirect Occlusion"] +float SpecularOcclusionGTSO(float NdotV, float ao) +{ + float d = NdotV + ao; + return saturate(d * d - 1.0 + ao); +} + // [Lagarde et al. 2014, "Moving Frostbite to Physically Based Rendering 3.0"] float SpecularAOLagarde(float NdotV, float ao, float roughness) { diff --git a/package/Shaders/DeferredCompositeCS.hlsl b/package/Shaders/DeferredCompositeCS.hlsl index c96e56aeb2..85e7696d00 100644 --- a/package/Shaders/DeferredCompositeCS.hlsl +++ b/package/Shaders/DeferredCompositeCS.hlsl @@ -55,8 +55,7 @@ void SampleSSGI(uint2 pixCoord, float3 normalWS, out float ao, out float3 il) void SampleSSGISpecular(uint2 pixCoord, sh2 lobe, inout float ao, out float3 il, in float3 normal, in float3 view, in float roughness) { float NdotV = dot(normal, view); - float alpha = roughness * roughness; - ao = SpecularOcclusion(saturate(NdotV), alpha, ao); + ao = SpecularOcclusionGTSO(saturate(NdotV), ao); float4 ssgiIlYSh = SsgiYTexture[pixCoord]; float ssgiIlY = SphericalHarmonics::FuncProductIntegral(ssgiIlYSh, lobe); @@ -145,8 +144,6 @@ void SampleSSGISpecular(uint2 pixCoord, sh2 lobe, inout float ao, out float3 il, float3 multiBounceSSGIAo = MultiBounceAO(linAlbedo, ssgiAo); - linDiffuseColor *= sqrt(multiBounceSSGIAo); - diffuseColor = Color::IrradianceToGamma(linDiffuseColor); diffuseColor += Color::IrradianceToGamma(Color::IrradianceToLinear(directionalAmbientColor) * multiBounceSSGIAo); From e697d75d6dd0eca857549e3f64d907ef8f8e989d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 20:28:23 +0000 Subject: [PATCH 2/2] =?UTF-8?q?style:=20=F0=9F=8E=A8=20apply=20pre-commit.?= =?UTF-8?q?ci=20formatting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Automated formatting by clang-format, prettier, and other hooks. See https://pre-commit.ci for details. --- package/Shaders/Common/Shading.hlsli | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/Shaders/Common/Shading.hlsli b/package/Shaders/Common/Shading.hlsli index af723eb59c..97cbdeaf93 100644 --- a/package/Shaders/Common/Shading.hlsli +++ b/package/Shaders/Common/Shading.hlsli @@ -13,8 +13,8 @@ float3 MultiBounceAO(float3 baseColor, float ao) // [Jimenez et al. 2016, "Practical Realtime Strategies for Accurate Indirect Occlusion"] float SpecularOcclusionGTSO(float NdotV, float ao) { - float d = NdotV + ao; - return saturate(d * d - 1.0 + ao); + float d = NdotV + ao; + return saturate(d * d - 1.0 + ao); } // [Lagarde et al. 2014, "Moving Frostbite to Physically Based Rendering 3.0"]