improvements
This commit is contained in:
@@ -897,7 +897,7 @@ inline float2 clipspace_to_uv(in float2 clipspace)
|
||||
}
|
||||
inline float3 clipspace_to_uv(in float3 clipspace)
|
||||
{
|
||||
return clipspace * float3(0.5, -0.5, 0.5) + 0.5;
|
||||
return clipspace * float3(0.5, -0.5, 1) + float3(0.5, 0.5, 0);
|
||||
}
|
||||
inline half2 clipspace_to_uv(in half2 clipspace)
|
||||
{
|
||||
@@ -905,7 +905,7 @@ inline half2 clipspace_to_uv(in half2 clipspace)
|
||||
}
|
||||
inline half3 clipspace_to_uv(in half3 clipspace)
|
||||
{
|
||||
return clipspace * half3(0.5, -0.5, 0.5) + 0.5;
|
||||
return clipspace * half3(0.5, -0.5, 1) + half3(0.5, 0.5, 0);
|
||||
}
|
||||
|
||||
inline half3 GetSunColor() { return unpack_half3(GetWeather().sun_color); } // sun color with intensity applied
|
||||
|
||||
@@ -89,8 +89,9 @@ inline void light_directional(in ShaderEntity light, in Surface surface, inout L
|
||||
[branch]
|
||||
if (is_saturated(shadow_uv))
|
||||
{
|
||||
const half2 cascade_edgefactor = saturate(saturate(abs(shadow_pos.xy)) - 0.8) * 5.0; // fade will be on edge and inwards 10%
|
||||
const half cascade_fade = max(cascade_edgefactor.x, cascade_edgefactor.y);
|
||||
const half3 shadow_box = half3(shadow_pos.xy, shadow_pos.z * 2 - 1);
|
||||
const half3 cascade_edgefactor = saturate(saturate(abs(shadow_box)) - 0.8) * 5.0; // fade will be on edge and inwards 10%
|
||||
const half cascade_fade = max3(cascade_edgefactor);
|
||||
|
||||
// If we are on cascade edge threshold and not the last cascade, then fallback to a larger cascade:
|
||||
[branch]
|
||||
|
||||
@@ -2,17 +2,16 @@
|
||||
#define WI_SHADOW_HF
|
||||
#include "globals.hlsli"
|
||||
|
||||
static const float exponential_shadow_bias = 40;
|
||||
static const float exponential_shadow_bias = 80;
|
||||
|
||||
inline half3 sample_shadow(float2 uv, float cmp, float4 uv_clamping, half2 radius, float shadow_power = 1)
|
||||
inline half3 sample_shadow(float2 uv, float cmp)
|
||||
{
|
||||
Texture2D<float> texture_shadowatlas = bindless_textures_float[descriptor_index(GetFrame().texture_shadowatlas_index)];
|
||||
Texture2D<half4> texture_shadowatlas_transparent = bindless_textures_half4[descriptor_index(GetFrame().texture_shadowatlas_transparent_index)];
|
||||
|
||||
float shadowMapValue = texture_shadowatlas.SampleLevel(sampler_linear_clamp, uv, 0);
|
||||
half3 shadow = pow(saturate(shadowMapValue * exp(-exponential_shadow_bias * cmp)), shadow_power);
|
||||
half3 shadow = saturate(shadowMapValue * exp(-exponential_shadow_bias * 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)
|
||||
@@ -26,19 +25,20 @@ inline half3 sample_shadow(float2 uv, float cmp, float4 uv_clamping, half2 radiu
|
||||
}
|
||||
|
||||
// This is used to clamp the uvs to last texel center to avoid sampling on the border and overfiltering into a different shadow
|
||||
inline float4 shadow_border_clamp(in ShaderEntity light, in float slice)
|
||||
inline void shadow_border_clamp(in ShaderEntity light, in float slice, inout float2 uv)
|
||||
{
|
||||
const float border_size = 0.75 * GetFrame().shadow_atlas_resolution_rcp;
|
||||
const float2 topleft = mad(float2(slice, 0), light.shadowAtlasMulAdd.xy, light.shadowAtlasMulAdd.zw) + border_size;
|
||||
const float2 bottomright = mad(float2(slice + 1, 1), light.shadowAtlasMulAdd.xy, light.shadowAtlasMulAdd.zw) - border_size;
|
||||
return float4(topleft, bottomright);
|
||||
uv = clamp(uv, topleft, bottomright);
|
||||
}
|
||||
|
||||
inline half3 shadow_2D(in ShaderEntity light, in float z, in float2 shadow_uv, in uint cascade, in float shadow_power = 1)
|
||||
{
|
||||
shadow_uv.x += cascade;
|
||||
shadow_uv = mad(shadow_uv, light.shadowAtlasMulAdd.xy, light.shadowAtlasMulAdd.zw);
|
||||
return sample_shadow(shadow_uv, z, shadow_border_clamp(light, cascade), light.GetType() == ENTITY_TYPE_RECTLIGHT ? (half2(light.GetRadius(), light.GetLength()) * 0.05) : light.GetRadius(), shadow_power);
|
||||
shadow_border_clamp(light, cascade, shadow_uv);
|
||||
return sample_shadow(shadow_uv, z);
|
||||
}
|
||||
|
||||
inline half3 shadow_cube(in ShaderEntity light, in float3 Lunnormalized, in float shadow_power = 1)
|
||||
@@ -47,7 +47,8 @@ inline half3 shadow_cube(in ShaderEntity light, in float3 Lunnormalized, in floa
|
||||
float2 shadow_uv = uv_slice.xy;
|
||||
shadow_uv.x += uv_slice.z;
|
||||
shadow_uv = mad(shadow_uv, light.shadowAtlasMulAdd.xy, light.shadowAtlasMulAdd.zw);
|
||||
return sample_shadow(shadow_uv, length(Lunnormalized) / light.GetRange(), shadow_border_clamp(light, uv_slice.z), light.GetRadius(), shadow_power);
|
||||
shadow_border_clamp(light, uv_slice.z, shadow_uv);
|
||||
return sample_shadow(shadow_uv, length(Lunnormalized) / light.GetRange());
|
||||
}
|
||||
|
||||
inline half shadow_2D_volumetricclouds(float3 P)
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
ConstantBuffer<ShadowFilterData> filter : register(b2);
|
||||
|
||||
Texture2D<float> shadowAtlas : register(t0);
|
||||
Texture2D<float4> shadowAtlas_transparent : register(t1);
|
||||
|
||||
RWTexture2D<float> shadowAtlas_filtered : register(u0);
|
||||
RWTexture2D<float4> shadowAtlas_transparent_filtered : register(u1);
|
||||
|
||||
static const float kGoldenAngle = 2.4;
|
||||
|
||||
@@ -22,6 +24,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
|
||||
const float2 bottomright = (filter.rect.xy + filter.rect.zw - border) * filter.atlas_resolution_rcp;
|
||||
|
||||
float filtered = 0;
|
||||
float transparent_filtered = 0;
|
||||
|
||||
const float2 spread_offset = filter.atlas_resolution_rcp * (2 + filter.spread * 8);
|
||||
const uint soft_shadow_sample_count = (uint)lerp(8.0, 128.0, saturate(length(filter.spread)));
|
||||
@@ -55,11 +58,14 @@ void main(uint3 DTid : SV_DispatchThreadID)
|
||||
zzzz = saturate(zzzz);
|
||||
zzzz = exp(exponential_shadow_bias * zzzz);
|
||||
filtered += bilinear(zzzz, frac(sample_uv * filter.atlas_resolution));
|
||||
transparent_filtered += shadowAtlas_transparent.SampleLevel(sampler_linear_clamp, sample_uv, 0);
|
||||
}
|
||||
filtered *= soft_shadow_sample_count_rcp;
|
||||
transparent_filtered *= soft_shadow_sample_count_rcp;
|
||||
|
||||
if(all(DTid.xy < filter.rect.zw))
|
||||
{
|
||||
shadowAtlas_filtered[pixel] = filtered;
|
||||
shadowAtlas_transparent_filtered[pixel] = transparent_filtered;
|
||||
}
|
||||
}
|
||||
|
||||
+22
-11
@@ -150,6 +150,7 @@ bool SHADOW_LOD_OVERRIDE = true;
|
||||
Texture shadowMapAtlas;
|
||||
Texture shadowMapAtlas_Transparent;
|
||||
Texture shadowMapAtlas_Filtered;
|
||||
Texture shadowMapAtlas_Transparent_Filtered;
|
||||
int max_shadow_resolution_2D = 1024;
|
||||
int max_shadow_resolution_cube = 256;
|
||||
|
||||
@@ -2902,16 +2903,17 @@ inline void CreateDirLightShadowCams(const LightComponent& light, CameraComponen
|
||||
XMStoreFloat3(&_min, vMin);
|
||||
XMStoreFloat3(&_max, vMax);
|
||||
|
||||
// Extrude bounds to avoid early shadow clipping:
|
||||
const XMMATRIX lightProjection = XMMatrixOrthographicOffCenterLH(_min.x, _max.x, _min.y, _max.y, _max.z, _min.z); // notice reversed Z!
|
||||
shcams[cascade].view_projection = XMMatrixMultiply(lightView, lightProjection);
|
||||
|
||||
// Extrude bounds to avoid early shadow culling:
|
||||
float ext = abs(_center.z - _min.z);
|
||||
ext = std::max(ext, std::min(1500.0f, farPlane) * 0.5f);
|
||||
_min.z = _center.z - ext;
|
||||
_max.z = _center.z + ext;
|
||||
|
||||
const XMMATRIX lightProjection = XMMatrixOrthographicOffCenterLH(_min.x, _max.x, _min.y, _max.y, _max.z, _min.z); // notice reversed Z!
|
||||
|
||||
shcams[cascade].view_projection = XMMatrixMultiply(lightView, lightProjection);
|
||||
shcams[cascade].frustum.Create(shcams[cascade].view_projection);
|
||||
const XMMATRIX lightProjectionExtended = XMMatrixOrthographicOffCenterLH(_min.x, _max.x, _min.y, _max.y, _max.z, _min.z); // notice reversed Z!
|
||||
shcams[cascade].frustum.Create(XMMatrixMultiply(lightView, lightProjectionExtended));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3934,11 +3936,6 @@ void UpdateVisibility(Visibility& vis)
|
||||
device->CreateTexture(&desc, nullptr, &shadowMapAtlas);
|
||||
device->SetName(&shadowMapAtlas, "shadowMapAtlas");
|
||||
|
||||
desc.format = Format::R32_FLOAT;
|
||||
desc.bind_flags = BindFlag::UNORDERED_ACCESS | BindFlag::SHADER_RESOURCE;
|
||||
device->CreateTexture(&desc, nullptr, &shadowMapAtlas_Filtered);
|
||||
device->SetName(&shadowMapAtlas_Filtered, "shadowMapAtlas_Filtered");
|
||||
|
||||
desc.format = format_rendertarget_shadowmap;
|
||||
desc.bind_flags = BindFlag::RENDER_TARGET | BindFlag::SHADER_RESOURCE;
|
||||
desc.layout = ResourceState::SHADER_RESOURCE;
|
||||
@@ -3949,6 +3946,14 @@ void UpdateVisibility(Visibility& vis)
|
||||
device->CreateTexture(&desc, nullptr, &shadowMapAtlas_Transparent);
|
||||
device->SetName(&shadowMapAtlas_Transparent, "shadowMapAtlas_Transparent");
|
||||
|
||||
desc.bind_flags = BindFlag::UNORDERED_ACCESS | BindFlag::SHADER_RESOURCE;
|
||||
desc.format = Format::R32_FLOAT;
|
||||
device->CreateTexture(&desc, nullptr, &shadowMapAtlas_Filtered);
|
||||
device->SetName(&shadowMapAtlas_Filtered, "shadowMapAtlas_Filtered");
|
||||
desc.format = format_rendertarget_shadowmap;
|
||||
device->CreateTexture(&desc, nullptr, &shadowMapAtlas_Transparent_Filtered);
|
||||
device->SetName(&shadowMapAtlas_Transparent_Filtered, "shadowMapAtlas_Transparent_Filtered");
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -4241,7 +4246,7 @@ void UpdatePerFrameData(
|
||||
|
||||
// Note: shadow maps always assumed to be valid to avoid shader branching logic
|
||||
const Texture& shadowMap = shadowMapAtlas_Filtered.IsValid() ? shadowMapAtlas_Filtered : *wi::texturehelper::getBlack();
|
||||
const Texture& shadowMapTransparent = shadowMapAtlas_Transparent.IsValid() ? shadowMapAtlas_Transparent : *wi::texturehelper::getWhite();
|
||||
const Texture& shadowMapTransparent = shadowMapAtlas_Transparent_Filtered.IsValid() ? shadowMapAtlas_Transparent_Filtered : *wi::texturehelper::getWhite();
|
||||
frameCB.texture_shadowatlas_index = device->GetDescriptorIndex(&shadowMap, SubresourceType::SRV);
|
||||
frameCB.texture_shadowatlas_transparent_index = device->GetDescriptorIndex(&shadowMapTransparent, SubresourceType::SRV);
|
||||
frameCB.shadow_atlas_resolution.x = shadowMap.desc.width;
|
||||
@@ -7006,11 +7011,16 @@ void DrawShadowmaps(
|
||||
device->RenderPassEnd(cmd);
|
||||
device->EventBegin("Shadow Filtering", cmd);
|
||||
device->Barrier(GPUBarrier::Image(&shadowMapAtlas_Filtered, ResourceState::UNDEFINED, ResourceState::UNORDERED_ACCESS), cmd);
|
||||
device->Barrier(GPUBarrier::Image(&shadowMapAtlas_Transparent_Filtered, ResourceState::UNDEFINED, ResourceState::UNORDERED_ACCESS), cmd);
|
||||
device->ClearUAV(&shadowMapAtlas_Filtered, 0, cmd);
|
||||
device->ClearUAV(&shadowMapAtlas_Transparent_Filtered, 0, cmd);
|
||||
device->Barrier(GPUBarrier::Memory(&shadowMapAtlas_Filtered), cmd);
|
||||
device->Barrier(GPUBarrier::Memory(&shadowMapAtlas_Transparent_Filtered), cmd);
|
||||
device->BindComputeShader(&shaders[CSTYPE_SHADOW_FILTER], cmd);
|
||||
device->BindResource(&shadowMapAtlas, 0, cmd);
|
||||
device->BindResource(&shadowMapAtlas_Transparent, 1, cmd);
|
||||
device->BindUAV(&shadowMapAtlas_Filtered, 0, cmd);
|
||||
device->BindUAV(&shadowMapAtlas_Transparent_Filtered, 1, cmd);
|
||||
ShadowFilterData filter = {};
|
||||
filter.atlas_resolution.x = float(shadowMapAtlas.desc.width);
|
||||
filter.atlas_resolution.y = float(shadowMapAtlas.desc.height);
|
||||
@@ -7164,6 +7174,7 @@ void DrawShadowmaps(
|
||||
device->Dispatch((filter.rect.z + 7u) / 8u, (filter.rect.w + 7u) / 8u, 1, cmd);
|
||||
}
|
||||
device->Barrier(GPUBarrier::Image(&shadowMapAtlas_Filtered, ResourceState::UNORDERED_ACCESS, ResourceState::SHADER_RESOURCE), cmd);
|
||||
device->Barrier(GPUBarrier::Image(&shadowMapAtlas_Transparent_Filtered, ResourceState::UNORDERED_ACCESS, ResourceState::SHADER_RESOURCE), cmd);
|
||||
device->EventEnd(cmd);
|
||||
|
||||
wi::profiler::EndRange(range_gpu);
|
||||
|
||||
@@ -742,6 +742,7 @@ namespace wi::terrain
|
||||
if (chunk_object != nullptr)
|
||||
{
|
||||
chunk_object->SetWetmapEnabled(scene->IsWetmapProcessingRequired());
|
||||
chunk_object->SetCastShadow(true);
|
||||
}
|
||||
|
||||
// chunk removal:
|
||||
|
||||
Reference in New Issue
Block a user