From a90ffbfd4e269ecf369575f74295127674af411d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tur=C3=A1nszki=20J=C3=A1nos?= Date: Sun, 6 Oct 2024 11:06:02 +0200 Subject: [PATCH] shader fixes for Intel igpu (#956) * shader fixes for Intel igpu * amd revert --- WickedEngine/shaders/lightingHF.hlsli | 65 ++++++++++++++++++--------- WickedEngine/wiVersion.cpp | 2 +- 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/WickedEngine/shaders/lightingHF.hlsli b/WickedEngine/shaders/lightingHF.hlsli index 8d2d855ae..77b1b5b08 100644 --- a/WickedEngine/shaders/lightingHF.hlsli +++ b/WickedEngine/shaders/lightingHF.hlsli @@ -61,17 +61,20 @@ inline void ApplyLighting(in Surface surface, in Lighting lighting, inout half4 inline void light_directional(in ShaderEntity light, in Surface surface, inout Lighting lighting, in half shadow_mask = 1) { - if ((light.layerMask & surface.layerMask) == 0) - return; // early exit: layer mismatch + bool early_exit = (light.layerMask & surface.layerMask) == 0; // layer mismatch half3 L = light.GetDirection(); SurfaceToLight surface_to_light; surface_to_light.create(surface, L); - - if (!any(surface_to_light.NdotL_sss)) - return; // early exit: facing away from light + + early_exit |= !any(surface_to_light.NdotL_sss); // facing away from light half3 light_color = light.GetColor().rgb * shadow_mask; + + early_exit |= !any(light_color); // light color lost + + if (WaveActiveAllTrue(early_exit)) + return; // COHERENT early exit before QuadBlur [branch] if (light.IsCastingShadow() && surface.IsReceiveShadow()) @@ -114,8 +117,13 @@ inline void light_directional(in ShaderEntity light, in Surface surface, inout L } QuadBlur(light_color); + + early_exit |= !any(light_color); // light color lost after shadow } + if (early_exit) + return; // DIVERGENT early exit after QuadBlur + [branch] if (GetFrame().options & OPTION_BIT_REALISTIC_SKY) { @@ -166,8 +174,7 @@ inline half attenuation_pointlight(in half dist2, in half range, in half range2) } inline void light_point(in ShaderEntity light, in Surface surface, inout Lighting lighting, in half shadow_mask = 1) { - if ((light.layerMask & surface.layerMask) == 0) - return; // early exit: layer mismatch + bool early_exit = (light.layerMask & surface.layerMask) == 0; // layer mismatch float3 Lunnormalized = light.position - surface.P; const float3 LunnormalizedShadow = Lunnormalized; @@ -188,9 +195,8 @@ inline void light_point(in ShaderEntity light, in Surface surface, inout Lightin const half dist2 = dot(Lunnormalized, Lunnormalized); const half range = light.GetRange(); const half range2 = range * range; - - if (dist2 > range2) - return; // early exit: outside range + + early_exit |= dist2 > range2; // outside range const half dist_rcp = rsqrt(dist2); half3 L = Lunnormalized * dist_rcp; @@ -198,10 +204,14 @@ inline void light_point(in ShaderEntity light, in Surface surface, inout Lightin SurfaceToLight surface_to_light; surface_to_light.create(surface, L); - if (!any(surface_to_light.NdotL_sss)) - return; // early exit: facing away from light + early_exit |= !any(surface_to_light.NdotL_sss); // facing away from light half3 light_color = light.GetColor().rgb * shadow_mask; + + early_exit |= !any(light_color); // light color lost + + if (WaveActiveAllTrue(early_exit)) + return; // COHERENT early exit before QuadBlur [branch] if (light.IsCastingShadow() && surface.IsReceiveShadow()) @@ -215,8 +225,14 @@ inline void light_point(in ShaderEntity light, in Surface surface, inout Lightin } QuadBlur(light_color); + + early_exit |= !any(light_color); // light color lost after shadow } + if (early_exit) + return; // DIVERGENT early exit after QuadBlur + + // Reminder: attenuation must be AFTER QuadBlur! light_color *= attenuation_pointlight(dist2, range, range2); lighting.direct.diffuse = mad(light_color, BRDF_GetDiffuse(surface, surface_to_light), lighting.direct.diffuse); @@ -272,16 +288,14 @@ inline half attenuation_spotlight(in half dist2, in half range, in half range2, } inline void light_spot(in ShaderEntity light, in Surface surface, inout Lighting lighting, in half shadow_mask = 1) { - if ((light.layerMask & surface.layerMask) == 0) - return; // early exit: layer mismatch + bool early_exit = (light.layerMask & surface.layerMask) == 0; // layer mismatch float3 Lunnormalized = light.position - surface.P; const half dist2 = dot(Lunnormalized, Lunnormalized); const half range = light.GetRange(); const half range2 = range * range; - if (dist2 > range2) - return; // early exit: outside range + early_exit |= dist2 > range2; // outside range const half dist_rcp = rsqrt(dist2); half3 L = Lunnormalized * dist_rcp; @@ -289,16 +303,19 @@ inline void light_spot(in ShaderEntity light, in Surface surface, inout Lighting SurfaceToLight surface_to_light; surface_to_light.create(surface, L); - if (!any(surface_to_light.NdotL_sss)) - return; // early exit: facing away from light + early_exit |= !any(surface_to_light.NdotL_sss); // facing away from light const half spot_factor = dot(L, light.GetDirection()); const half spot_cutoff = light.GetConeAngleCos(); - if (spot_factor < spot_cutoff) - return; // early exit: outside spotlight cone + early_exit |= spot_factor < spot_cutoff; // outside spotlight cone half3 light_color = light.GetColor().rgb * shadow_mask; + + early_exit |= !any(light_color); // light color lost + + if (WaveActiveAllTrue(early_exit)) + return; // COHERENT early exit before QuadBlur [branch] if (light.IsCastingShadow() && surface.IsReceiveShadow()) @@ -319,10 +336,16 @@ inline void light_spot(in ShaderEntity light, in Surface surface, inout Lighting } QuadBlur(light_color); + + early_exit |= !any(light_color); // light color lost after shadow } - light_color *= attenuation_spotlight(dist2, range, range2, spot_factor, light.GetAngleScale(), light.GetAngleOffset()); + if (early_exit) + return; // DIVERGENT early exit after QuadBlur + // Reminder: attenuation must be AFTER QuadBlur! + light_color *= attenuation_spotlight(dist2, range, range2, spot_factor, light.GetAngleScale(), light.GetAngleOffset()); + lighting.direct.diffuse = mad(light_color, BRDF_GetDiffuse(surface, surface_to_light), lighting.direct.diffuse); #ifndef DISABLE_AREA_LIGHTS diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index af7dac04b..01f97c323 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 71; // minor bug fixes, alterations, refactors, updates - const int revision = 589; + const int revision = 590; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);