Skip to content

Commit

Permalink
removed shadow QuadBlur because some graphics cards didn't handle it …
Browse files Browse the repository at this point in the history
…correctly
  • Loading branch information
turanszkij committed Oct 14, 2024
1 parent f9f3805 commit 465406a
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 58 deletions.
88 changes: 31 additions & 57 deletions WickedEngine/shaders/lightingHF.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,6 @@
#define LIGHTING_SCATTER
#endif // WATER

template<typename T>
inline void QuadBlur(inout T value)
{
#if __SHADER_TARGET_STAGE == __SHADER_STAGE_PIXEL && defined(SHADOW_SAMPLING_DISK) && !defined(__spirv__) // Note: Vulkan is disabled because AMD doesn't handle it correctly
// Average shadow within quad, this smooths out the dithering a bit:
// Note that I don't implement this in shadowHF.hlsli because we need to
// make sure that when averaging, all lanes in the quad are coherent
// It wouldn't be good if some waves are not sampling shadows or sampling different slices
value = (value + QuadReadAcrossX(value) + QuadReadAcrossY(value) + QuadReadAcrossDiagonal(value)) * 0.25;
#endif // __SHADER_STAGE_PIXEL
}

struct LightingPart
{
half3 diffuse;
Expand Down Expand Up @@ -61,20 +49,19 @@ 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)
{
bool early_exit = (light.layerMask & surface.layerMask) == 0; // layer mismatch
if (shadow_mask <= 0.001)
return; // shadow mask zero
if ((light.layerMask & surface.layerMask) == 0)
return; // layer mismatch

half3 L = light.GetDirection();
SurfaceToLight surface_to_light;
surface_to_light.create(surface, L);

early_exit |= !any(surface_to_light.NdotL_sss); // facing away from light
if (!any(surface_to_light.NdotL_sss))
return; // 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())
Expand Down Expand Up @@ -116,14 +103,10 @@ 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 (!any(light_color))
return; // light color lost after shadow
}

if (early_exit)
return; // DIVERGENT early exit after QuadBlur

[branch]
if (GetFrame().options & OPTION_BIT_REALISTIC_SKY)
{
Expand Down Expand Up @@ -174,7 +157,10 @@ 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)
{
bool early_exit = (light.layerMask & surface.layerMask) == 0; // layer mismatch
if (shadow_mask <= 0.001)
return; // shadow mask zero
if ((light.layerMask & surface.layerMask) == 0)
return; // layer mismatch

float3 Lunnormalized = light.position - surface.P;
const float3 LunnormalizedShadow = Lunnormalized;
Expand All @@ -196,22 +182,19 @@ inline void light_point(in ShaderEntity light, in Surface surface, inout Lightin
const half range = light.GetRange();
const half range2 = range * range;

early_exit |= dist2 > range2; // outside range
if (dist2 > range2)
return; // outside range

const half dist_rcp = rsqrt(dist2);
half3 L = Lunnormalized * dist_rcp;

SurfaceToLight surface_to_light;
surface_to_light.create(surface, L);

early_exit |= !any(surface_to_light.NdotL_sss); // facing away from light
if (!any(surface_to_light.NdotL_sss))
return; // 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())
Expand All @@ -224,15 +207,10 @@ inline void light_point(in ShaderEntity light, in Surface surface, inout Lightin
light_color *= shadow_cube(light, LunnormalizedShadow, surface.pixel);
}

QuadBlur(light_color);

early_exit |= !any(light_color); // light color lost after shadow
if (!any(light_color))
return; // 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);
Expand Down Expand Up @@ -288,34 +266,35 @@ 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)
{
bool early_exit = (light.layerMask & surface.layerMask) == 0; // layer mismatch
if (shadow_mask <= 0.001)
return; // shadow mask zero
if ((light.layerMask & surface.layerMask) == 0)
return; // layer mismatch

float3 Lunnormalized = light.position - surface.P;
const half dist2 = dot(Lunnormalized, Lunnormalized);
const half range = light.GetRange();
const half range2 = range * range;

early_exit |= dist2 > range2; // outside range
if (dist2 > range2)
return; // outside range

const half dist_rcp = rsqrt(dist2);
half3 L = Lunnormalized * dist_rcp;

SurfaceToLight surface_to_light;
surface_to_light.create(surface, L);

early_exit |= !any(surface_to_light.NdotL_sss); // facing away from light
if (!any(surface_to_light.NdotL_sss))
return; // facing away from light

const half spot_factor = dot(L, light.GetDirection());
const half spot_cutoff = light.GetConeAngleCos();

early_exit |= spot_factor < spot_cutoff; // outside spotlight cone
if (spot_factor < spot_cutoff)
return; // 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())
Expand All @@ -335,15 +314,10 @@ 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
if (!any(light_color))
return; // light color lost after shadow
}

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);
Expand Down
2 changes: 1 addition & 1 deletion WickedEngine/wiVersion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 = 594;
const int revision = 595;

const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);

Expand Down

0 comments on commit 465406a

Please sign in to comment.