This commit is contained in:
Turánszki János
2025-05-22 16:21:54 +02:00
parent fc64915e3a
commit fa4ab1deda
11 changed files with 31 additions and 43 deletions
+1
View File
@@ -212,6 +212,7 @@ wi::vector<ShaderEntry> shaders = {
{"depth_reprojectCS", wi::graphics::ShaderStage::CS },
{"depth_pyramidCS", wi::graphics::ShaderStage::CS },
{"lightmap_expandCS", wi::graphics::ShaderStage::CS },
{"shadow_filterCS", wi::graphics::ShaderStage::CS },
{"emittedparticlePS_soft", wi::graphics::ShaderStage::PS },
@@ -1787,7 +1787,8 @@ struct ShadowFilterData
float2 atlas_resolution_rcp;
float2 atlas_resolution;
float2 spread;
float2 padding;
float range;
uint type;
};
#endif // WI_SHADERINTEROP_RENDERER_H
+5 -5
View File
@@ -102,10 +102,10 @@ inline void light_directional(in ShaderEntity light, in Surface surface, inout L
if (cascade_fade > 0 && dither(surface.pixel + GetTemporalAASampleRotation()) < cascade_fade)
continue;
light_color *= shadow_2D(light, 1 - shadow_pos.z, shadow_uv.xy, cascade);
light_color *= shadow_2D(light, shadow_pos.z, shadow_uv.xy, cascade);
break;
#else
const half3 shadow_main = shadow_2D(light, 1 - shadow_pos.z, shadow_uv.xy, cascade);
const half3 shadow_main = shadow_2D(light, shadow_pos.z, shadow_uv.xy, cascade);
// If we are on cascade edge threshold and not the last cascade, then fallback to a larger cascade:
[branch]
@@ -115,7 +115,7 @@ inline void light_directional(in ShaderEntity light, in Surface surface, inout L
cascade += 1;
shadow_pos = mul(load_entitymatrix(light.GetMatrixIndex() + cascade), float4(surface.P, 1)).xyz;
shadow_uv = clipspace_to_uv(shadow_pos);
const half3 shadow_fallback = shadow_2D(light, 1 - shadow_pos.z, shadow_uv.xy, cascade);
const half3 shadow_fallback = shadow_2D(light, shadow_pos.z, shadow_uv.xy, cascade);
light_color *= lerp(shadow_main, shadow_fallback, cascade_fade);
}
@@ -344,7 +344,7 @@ inline void light_spot(in ShaderEntity light, in Surface surface, inout Lighting
[branch]
if (is_saturated(shadow_uv))
{
light_color *= shadow_2D(light, rcp(dist_rcp) / range, shadow_uv.xy, 0);
light_color *= shadow_2D(light, shadow_pos.z, shadow_uv.xy, 0);
}
}
@@ -477,7 +477,7 @@ inline void light_rect(in ShaderEntity light, in Surface surface, inout Lighting
[branch]
if (is_saturated(shadow_uv))
{
light_color *= shadow_2D(light, rcp(dist_rcp) / range, shadow_uv.xy, 0);
light_color *= shadow_2D(light, shadow_pos.z, shadow_uv.xy, 0);
}
}
+4 -3
View File
@@ -8,13 +8,13 @@ inline half3 sample_shadow(float2 uv, float cmp)
{
Texture2D<float> texture_shadowatlas = bindless_textures_float[descriptor_index(GetFrame().texture_shadowatlas_filtered_index)];
float shadowMapValue = texture_shadowatlas.SampleLevel(sampler_linear_clamp, uv, 0);
half3 shadow = sqr((half)saturate(shadowMapValue * exp(-exponential_shadow_bias * cmp)));
half3 shadow = sqr((half)saturate(shadowMapValue * exp(-exponential_shadow_bias * (1 - cmp))));
#ifndef DISABLE_TRANSPARENT_SHADOWMAP
Texture2D<half4> texture_shadowatlas_transparent = bindless_textures_half4[descriptor_index(GetFrame().texture_shadowatlas_transparent_index)];
half4 transparent_shadow = texture_shadowatlas_transparent.SampleLevel(sampler_linear_clamp, uv, 0);
#ifdef TRANSPARENT_SHADOWMAP_SECONDARY_DEPTH_CHECK
if (transparent_shadow.a < cmp - 0.001)
if (transparent_shadow.a > cmp + 0.0001)
#endif // TRANSPARENT_SHADOWMAP_SECONDARY_DEPTH_CHECK
{
shadow *= transparent_shadow.rgb;
@@ -43,12 +43,13 @@ inline half3 shadow_2D(in ShaderEntity light, in float z, in float2 shadow_uv, i
inline half3 shadow_cube(in ShaderEntity light, in float3 Lunnormalized)
{
const float remapped_distance = light.GetCubemapDepthRemapNear() + light.GetCubemapDepthRemapFar() / (max(max(abs(Lunnormalized.x), abs(Lunnormalized.y)), abs(Lunnormalized.z)) * 0.989); // little bias to avoid artifact
const float3 uv_slice = cubemap_to_uv(-Lunnormalized);
float2 shadow_uv = uv_slice.xy;
shadow_uv.x += uv_slice.z;
shadow_uv = mad(shadow_uv, light.shadowAtlasMulAdd.xy, light.shadowAtlasMulAdd.zw);
shadow_border_clamp(light, uv_slice.z, shadow_uv);
return sample_shadow(shadow_uv, length(Lunnormalized) / light.GetRange());
return sample_shadow(shadow_uv, remapped_distance);
}
inline half shadow_2D_volumetricclouds(float3 P)
+3 -27
View File
@@ -24,7 +24,6 @@ inline uint coord_to_cache(int2 coord)
[numthreads(THREADCOUNT, THREADCOUNT, 1)]
void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid : SV_GroupThreadID)
{
const bool ortho = filter.range_rcp < 0;
const float border = 0.51;
const float2 topleft = (filter.rect.xy + border) * filter.atlas_resolution_rcp;
const float2 bottomright = (filter.rect.xy + filter.rect.zw - border) * filter.atlas_resolution_rcp;
@@ -43,34 +42,11 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid :
half4 bbbb = shadowAtlas_transparent.GatherBlue(sampler_linear_clamp, uv);
half4 aaaa = shadowAtlas_transparent.GatherAlpha(sampler_linear_clamp, uv);
const uint t = coord_to_cache(int2(x, y));
if (ortho)
{
zzzz = 1 - zzzz;
}
else
{
zzzz.x = distance(filter.eye, reconstruct_position(origin_uv, zzzz.x, filter.inverse_view_projection)) * filter.range_rcp;
zzzz.y = distance(filter.eye, reconstruct_position(origin_uv, zzzz.y, filter.inverse_view_projection)) * filter.range_rcp;
zzzz.z = distance(filter.eye, reconstruct_position(origin_uv, zzzz.z, filter.inverse_view_projection)) * filter.range_rcp;
zzzz.w = distance(filter.eye, reconstruct_position(origin_uv, zzzz.w, filter.inverse_view_projection)) * filter.range_rcp;
}
zzzz = 1 - zzzz;
zzzz = saturate(zzzz);
zzzz = exp(exponential_shadow_bias * zzzz);
if (ortho)
{
aaaa = 1 - aaaa;
}
else
{
aaaa.x = distance(filter.eye, reconstruct_position(origin_uv, aaaa.x, filter.inverse_view_projection)) * filter.range_rcp;
aaaa.y = distance(filter.eye, reconstruct_position(origin_uv, aaaa.y, filter.inverse_view_projection)) * filter.range_rcp;
aaaa.z = distance(filter.eye, reconstruct_position(origin_uv, aaaa.z, filter.inverse_view_projection)) * filter.range_rcp;
aaaa.w = distance(filter.eye, reconstruct_position(origin_uv, aaaa.w, filter.inverse_view_projection)) * filter.range_rcp;
}
aaaa = saturate(aaaa);
cache_z[t] = zzzz.w;
cache_z[t + 1] = zzzz.z;
cache_z[t + TILE_SIZE] = zzzz.x;
@@ -90,7 +66,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid :
float4 transparent_filtered = 0;
const float2 spread_offset = filter.atlas_resolution_rcp * clamp(2 + filter.spread * 8, 2, TILE_BORDER);
const uint soft_shadow_sample_count = (uint)lerp(4.0, 64.0, saturate(length(filter.spread)));
const uint soft_shadow_sample_count = (uint)lerp(4.0, 16.0, saturate(length(filter.spread)));
const float soft_shadow_sample_count_rcp = 1.0 / (float)soft_shadow_sample_count;
const float soft_shadow_sample_count_sqrt_rcp = rsqrt((float)soft_shadow_sample_count);
+1 -1
View File
@@ -685,7 +685,7 @@ SingleScatteringResult IntegrateScatteredLuminance(
if (is_saturated(shadow_uv))
{
earthShadow *= shadow_2D(light, 1 - shadow_pos.z, shadow_uv.xy, furthestCascade).r;
earthShadow *= shadow_2D(light, shadow_pos.z, shadow_uv.xy, furthestCascade).r;
}
}
@@ -125,7 +125,7 @@ void OpaqueShadow(inout ParticipatingMedia participatingMedia, float3 worldPosit
if (is_saturated(shadow_uv))
{
shadow *= shadow_2D(light, 1 - shadow_pos.z, shadow_uv.xy, furthestCascade).r;
shadow *= shadow_2D(light, shadow_pos.z, shadow_uv.xy, furthestCascade).r;
}
}
@@ -60,7 +60,7 @@ float4 main(VertexToPixel input) : SV_Target
[branch]
if (is_saturated(shadow_uv))
{
shadow *= shadow_2D(light, 1 - shadow_pos.z, shadow_uv.xy, cascade);
shadow *= shadow_2D(light, shadow_pos.z, shadow_uv.xy, cascade);
break;
}
}
@@ -118,7 +118,7 @@ float4 main(VertexToPixel input) : SV_TARGET
[branch]
if ((saturate(shadow_uv.x) == shadow_uv.x) && (saturate(shadow_uv.y) == shadow_uv.y))
{
attenuation *= shadow_2D(light, dist / light.GetRange(), shadow_uv.xy, 0);
attenuation *= shadow_2D(light, shadow_pos.z, shadow_uv.xy, 0);
}
}
@@ -104,7 +104,7 @@ float4 main(VertexToPixel input) : SV_TARGET
[branch]
if ((saturate(shadow_uv.x) == shadow_uv.x) && (saturate(shadow_uv.y) == shadow_uv.y))
{
attenuation *= shadow_2D(light, dist / light.GetRange(), shadow_uv.xy, 0);
attenuation *= shadow_2D(light, shadow_pos.z, shadow_uv.xy, 0);
}
}
+11 -2
View File
@@ -7055,12 +7055,14 @@ void DrawShadowmaps(
{
XMStoreFloat4x4(&filter.inverse_view_projection, XMMatrixInverse(nullptr, shcams[cascade].view_projection));
filter.eye = float3(0, 0, 0);
filter.range = 0;
filter.range_rcp = -1;
filter.rect.x = shadow_rect.x + cascade * shadow_rect.w;
filter.rect.y = shadow_rect.y;
filter.rect.z = shadow_rect.w;
filter.rect.w = shadow_rect.h;
filter.spread = float2(light.radius, light.radius);
filter.type = SHADER_ENTITY_TYPE::ENTITY_TYPE_DIRECTIONALLIGHT;
device->BindDynamicConstantBuffer(filter, 2, cmd);
device->Dispatch((filter.rect.z + SHADOW_FILTER_THREADSIZE - 1) / SHADOW_FILTER_THREADSIZE, (filter.rect.w + SHADOW_FILTER_THREADSIZE - 1) / SHADOW_FILTER_THREADSIZE, 1, cmd);
}
@@ -7089,7 +7091,8 @@ void DrawShadowmaps(
XMStoreFloat4x4(&filter.inverse_view_projection, XMMatrixInverse(nullptr, shcam.view_projection));
filter.eye = light.position;
filter.range_rcp = 1.0f / light.GetRange();
filter.range = light.GetRange();
filter.range_rcp = 1.0f / filter.range;
filter.rect.x = shadow_rect.x;
filter.rect.y = shadow_rect.y;
filter.rect.z = shadow_rect.w;
@@ -7097,10 +7100,12 @@ void DrawShadowmaps(
if (light.type == LightComponent::RECTANGLE)
{
filter.spread = float2(light.length * 0.2f, light.height * 0.2f);
filter.type = SHADER_ENTITY_TYPE::ENTITY_TYPE_RECTLIGHT;
}
else
{
filter.spread = float2(light.radius, light.radius);
filter.type = SHADER_ENTITY_TYPE::ENTITY_TYPE_SPOTLIGHT;
}
device->BindDynamicConstantBuffer(filter, 2, cmd);
device->Dispatch((filter.rect.z + SHADOW_FILTER_THREADSIZE - 1) / SHADOW_FILTER_THREADSIZE, (filter.rect.w + SHADOW_FILTER_THREADSIZE - 1) / SHADOW_FILTER_THREADSIZE, 1, cmd);
@@ -7140,12 +7145,14 @@ void DrawShadowmaps(
{
XMStoreFloat4x4(&filter.inverse_view_projection, XMMatrixInverse(nullptr, cameras[shcam].view_projection));
filter.eye = light.position;
filter.range_rcp = 1.0f / light.GetRange();
filter.range = light.GetRange();
filter.range_rcp = 1.0f / filter.range;
filter.rect.x = shadow_rect.x + shcam * shadow_rect.w;
filter.rect.y = shadow_rect.y;
filter.rect.z = shadow_rect.w;
filter.rect.w = shadow_rect.h;
filter.spread = float2(light.radius, light.radius);
filter.type = SHADER_ENTITY_TYPE::ENTITY_TYPE_POINTLIGHT;
device->BindDynamicConstantBuffer(filter, 2, cmd);
device->Dispatch((filter.rect.z + SHADOW_FILTER_THREADSIZE - 1) / SHADOW_FILTER_THREADSIZE, (filter.rect.w + SHADOW_FILTER_THREADSIZE - 1) / SHADOW_FILTER_THREADSIZE, 1, cmd);
}
@@ -7167,12 +7174,14 @@ void DrawShadowmaps(
CreateDirLightShadowCams(vis.scene->rain_blocker_dummy_light, *vis.camera, &shcam, 1, vis.rain_blocker_shadow_rect);
XMStoreFloat4x4(&filter.inverse_view_projection, XMMatrixInverse(nullptr, shcam.view_projection));
filter.eye = float3(0, 0, 0);
filter.range = 0;
filter.range_rcp = -1;
filter.rect.x = vis.rain_blocker_shadow_rect.x;
filter.rect.y = vis.rain_blocker_shadow_rect.y;
filter.rect.z = vis.rain_blocker_shadow_rect.w;
filter.rect.w = vis.rain_blocker_shadow_rect.h;
filter.spread = float2(0.5f, 0.5f);
filter.type = SHADER_ENTITY_TYPE::ENTITY_TYPE_DIRECTIONALLIGHT;
device->BindDynamicConstantBuffer(filter, 2, cmd);
device->Dispatch((filter.rect.z + SHADOW_FILTER_THREADSIZE - 1) / SHADOW_FILTER_THREADSIZE, (filter.rect.w + SHADOW_FILTER_THREADSIZE - 1) / SHADOW_FILTER_THREADSIZE, 1, cmd);
}