From 444596beed56e65187b275061c9868b5a5a0a396 Mon Sep 17 00:00:00 2001 From: Try Date: Wed, 2 Oct 2024 20:28:54 +0200 Subject: [PATCH] vsm: page trimming; fog #681 --- game/graphics/renderer.cpp | 6 +-- game/graphics/shaders.cpp | 1 + game/graphics/shaders.h | 2 +- game/graphics/sky/sky.cpp | 2 +- shader/CMakeLists.txt | 1 + shader/virtual_shadow/vsm_alloc_pages.comp | 4 +- shader/virtual_shadow/vsm_clump_pages.comp | 28 ---------- shader/virtual_shadow/vsm_common.glsl | 61 ++++++++++------------ shader/virtual_shadow/vsm_trim_pages.comp | 46 ++++++++++++++++ 9 files changed, 83 insertions(+), 68 deletions(-) create mode 100644 shader/virtual_shadow/vsm_trim_pages.comp diff --git a/game/graphics/renderer.cpp b/game/graphics/renderer.cpp index 0a040aa0..a09aa574 100644 --- a/game/graphics/renderer.cpp +++ b/game/graphics/renderer.cpp @@ -864,9 +864,9 @@ void Renderer::drawVsm(Tempest::Encoder& cmd, uint8_t fI cmd.dispatchThreads(zbuffer.size()); if(vsm.pageDataCs.isEmpty()) { - //TODO: trimming - //cmd.setUniforms(shaders.vsmClumpPages0, vsm.uboClump); - //cmd.dispatch(1); + // trimming + cmd.setUniforms(shaders.vsmTrimPages, vsm.uboClump); + cmd.dispatch(1); // clump cmd.setUniforms(shaders.vsmClumpPages, vsm.uboClump); diff --git a/game/graphics/shaders.cpp b/game/graphics/shaders.cpp index 22248bd1..9ad2bbe2 100644 --- a/game/graphics/shaders.cpp +++ b/game/graphics/shaders.cpp @@ -200,6 +200,7 @@ Shaders::Shaders() { vsmClear = computeShader("vsm_clear.comp.sprv"); vsmClearPages = computeShader("vsm_clear_pages.comp.sprv"); vsmMarkPages = computeShader("vsm_mark_pages.comp.sprv"); + vsmTrimPages = computeShader("vsm_trim_pages.comp.sprv"); vsmClumpPages = computeShader("vsm_clump_pages.comp.sprv"); vsmAllocPages = computeShader("vsm_alloc_pages.comp.sprv"); vsmPackDraw0 = computeShader("vsm_pack_draws0.comp.sprv"); diff --git a/game/graphics/shaders.h b/game/graphics/shaders.h index 1f9202a7..80531745 100644 --- a/game/graphics/shaders.h +++ b/game/graphics/shaders.h @@ -77,7 +77,7 @@ class Shaders { // Virtual shadow Tempest::ComputePipeline vsmClusterTask; Tempest::ComputePipeline vsmClear, vsmClearPages, vsmMarkPages; - Tempest::ComputePipeline vsmClumpPages, vsmAllocPages; + Tempest::ComputePipeline vsmTrimPages, vsmClumpPages, vsmAllocPages; Tempest::ComputePipeline vsmPackDraw0, vsmPackDraw1; Tempest::RenderPipeline vsmDirectLight; Tempest::RenderPipeline vsmDbg; diff --git a/game/graphics/sky/sky.cpp b/game/graphics/sky/sky.cpp index 65dbb8be..c9e2e093 100644 --- a/game/graphics/sky/sky.cpp +++ b/game/graphics/sky/sky.cpp @@ -109,7 +109,7 @@ Sky::~Sky() { void Sky::setupSettings() { auto& device = Resources::device(); const bool fog = Gothic::inst().settingsGetI("RENDERER_D3D","zFogRadial")!=0; - const bool vsm = false;//Gothic::inst().options().doVirtualShadow; + const bool vsm = false; //Gothic::inst().options().doVirtualShadow; auto q = Quality::VolumetricLQ; if(!fog) { diff --git a/shader/CMakeLists.txt b/shader/CMakeLists.txt index 86fc7e04..1c456402 100644 --- a/shader/CMakeLists.txt +++ b/shader/CMakeLists.txt @@ -303,6 +303,7 @@ add_shader(vsm_dbg.frag virtual_shadow/vsm_direct_light.frag -DDEBUG) add_shader(vsm_mark_pages.comp virtual_shadow/vsm_mark_pages.comp) add_shader(vsm_clear.comp virtual_shadow/vsm_clear.comp) add_shader(vsm_clear_pages.comp virtual_shadow/vsm_clear_pages.comp) +add_shader(vsm_trim_pages.comp virtual_shadow/vsm_trim_pages.comp) add_shader(vsm_clump_pages.comp virtual_shadow/vsm_clump_pages.comp) add_shader(vsm_alloc_pages.comp virtual_shadow/vsm_alloc_pages.comp) add_shader(vsm_pack_draws0.comp virtual_shadow/vsm_pack_draws.comp -DPASS0) diff --git a/shader/virtual_shadow/vsm_alloc_pages.comp b/shader/virtual_shadow/vsm_alloc_pages.comp index 34f729d7..56a2493b 100644 --- a/shader/virtual_shadow/vsm_alloc_pages.comp +++ b/shader/virtual_shadow/vsm_alloc_pages.comp @@ -194,7 +194,7 @@ void horizontalMerge() { uint sz = unpackVsmPageSize(p0).x; ivec3 at = unpackVsmPageInfo(p0); uint size = sz; - for(uint i=col+sz; i < VSM_PAGE_TBL_SIZE; i+=sz) { + for(uint i=col+sz; i=0) { - if(abs(page.x)>=1 || abs(page.y)>=1) - break; - //page-local - const ivec2 pageI = ivec2((page*0.5+0.5)*VSM_PAGE_TBL_SIZE); - const vec2 pageF = fract((page*0.5+0.5)*VSM_PAGE_TBL_SIZE); - const ivec2 at = ivec2(pageF*VSM_PAGE_SIZE); - - //page-global - const uint pageId = texelFetch(pageTbl, ivec3(pageI, mip), 0).x >> 16u; - if(pageId==0xFFFF) { - page *= 2.0; - --mip; - continue; - } - - const ivec2 pageImageAt = unpackVsmPageId(pageId)*VSM_PAGE_SIZE + at; - return vsmTexelFetch(pageData, pageImageAt); - } - return 0; -#else +float shadowTexelFetchDirect(in vec2 page, in int mip, in utexture3D pageTbl, + #if defined(VSM_ATOMIC) + in utexture2D pageData + #else + in texture2D pageData + #endif + ) { //page-local const ivec2 pageI = ivec2((page*0.5+0.5)*VSM_PAGE_TBL_SIZE); const vec2 pageF = fract((page*0.5+0.5)*VSM_PAGE_TBL_SIZE); const ivec2 at = ivec2(pageF*VSM_PAGE_SIZE); //page-global - const uint pageId = texelFetch(pageTbl, ivec3(pageI, mip), 0).x >> 16u; - if(pageId==0xFFFF) - return 0; + const uint pageD = texelFetch(pageTbl, ivec3(pageI, mip), 0).x; + if(pageD==0) + return -1; + const uint pageId = pageD >> 16u; const ivec2 pageImageAt = unpackVsmPageId(pageId)*VSM_PAGE_SIZE + at; return vsmTexelFetch(pageData, pageImageAt); -#endif + } + +float shadowTexelFetch(in vec2 page, in int mip, in utexture3D pageTbl, + #if defined(VSM_ATOMIC) + in utexture2D pageData + #else + in texture2D pageData + #endif + ) { + while(mip >= 0) { + float s = shadowTexelFetchDirect(page, mip, pageTbl, pageData); + if(s>=0) + return s; + page *= 2.0; + mip--; + } + return 0; } #endif diff --git a/shader/virtual_shadow/vsm_trim_pages.comp b/shader/virtual_shadow/vsm_trim_pages.comp new file mode 100644 index 00000000..9bdd2fd5 --- /dev/null +++ b/shader/virtual_shadow/vsm_trim_pages.comp @@ -0,0 +1,46 @@ +#version 450 + +#extension GL_GOOGLE_include_directive : enable +#extension GL_ARB_separate_shader_objects : enable +#extension GL_EXT_samplerless_texture_functions : enable + +#include "virtual_shadow/vsm_common.glsl" +#include "scene.glsl" +#include "common.glsl" + +layout(local_size_x = 32, local_size_y = 32) in; + +layout(binding = 0, std430) buffer Pages { VsmHeader header; uint pageList[]; } vsm; +layout(binding = 1, r32ui) uniform uimage3D pageTbl; + +void trimPage(int mip) { + const ivec3 size = imageSize(pageTbl); + const ivec3 id = ivec3(gl_LocalInvocationID); + + const ivec2 b = ivec2(VSM_PAGE_TBL_SIZE/4); + const ivec2 h = ivec2(VSM_PAGE_TBL_SIZE/2); + + for(int i=id.x; i