Skip to content

Commit

Permalink
vsm: support fog pages
Browse files Browse the repository at this point in the history
  • Loading branch information
Try committed Oct 4, 2024
1 parent c695afa commit 0c229cf
Show file tree
Hide file tree
Showing 16 changed files with 320 additions and 121 deletions.
39 changes: 30 additions & 9 deletions game/graphics/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,11 @@ void Renderer::resetSwapchain() {
}

if(smSize>0) {
for(int i=0; i<Resources::ShadowLayers; ++i)
for(int i=0; i<Resources::ShadowLayers; ++i) {
if(settings.vsmEnabled && (i+1)!=Resources::ShadowLayers)
continue;
shadowMap[i] = device.zbuffer(shadowFormat,smSize,smSize);
}
}

sceneOpaque = device.attachment(TextureFormat::R11G11B10UF,w,h);
Expand Down Expand Up @@ -195,6 +198,7 @@ void Renderer::resetSwapchain() {
vsm.uboPages = device.descriptors(Shaders::inst().vsmMarkPages );
vsm.uboClump = device.descriptors(Shaders::inst().vsmClumpPages);
vsm.uboAlloc = device.descriptors(Shaders::inst().vsmAllocPages);
vsm.uboReproj = device.descriptors(Shaders::inst().vsmReprojectSm);

vsm.directLightPso = &Shaders::inst().vsmDirectLight;
vsm.pagesDbgPso = &Shaders::inst().vsmDbg;
Expand Down Expand Up @@ -479,6 +483,13 @@ void Renderer::prepareUniforms() {
if(!vsm.pageDataCs.isEmpty())
vsm.uboLight.set(6, vsm.pageDataCs); else
vsm.uboLight.set(6, vsm.pageData);

vsm.uboReproj.set(0, wview->sceneGlobals().uboGlobal[SceneGlobals::V_Main]);
vsm.uboReproj.set(1, vsm.pageTbl);
vsm.uboReproj.set(2, vsm.pageList);
if(!vsm.pageDataCs.isEmpty())
vsm.uboReproj.set(3, vsm.pageDataCs); else
vsm.uboReproj.set(3, vsm.pageData);
}

if(settings.swrEnabled) {
Expand Down Expand Up @@ -850,7 +861,7 @@ void Renderer::buildHiZ(Tempest::Encoder<Tempest::CommandBuffer>& cmd, uint8_t f
cmd.dispatchThreads(w,h);
}

void Renderer::drawVsm(Tempest::Encoder<Tempest::CommandBuffer>& cmd, uint8_t fId, WorldView& view) {
void Renderer::drawVsm(Tempest::Encoder<Tempest::CommandBuffer>& cmd, uint8_t fId, WorldView& wview) {
if(!settings.vsmEnabled)
return;

Expand All @@ -863,10 +874,12 @@ void Renderer::drawVsm(Tempest::Encoder<Tempest::CommandBuffer>& cmd, uint8_t fI
cmd.setUniforms(shaders.vsmMarkPages, vsm.uboPages, &settings.vsmMipBias, sizeof(settings.vsmMipBias));
cmd.dispatchThreads(zbuffer.size());

wview.vsmMarkSkyPages(cmd, fId);

if(vsm.pageDataCs.isEmpty()) {
// trimming
cmd.setUniforms(shaders.vsmTrimPages, vsm.uboClump);
cmd.dispatch(1);
// cmd.setUniforms(shaders.vsmTrimPages, vsm.uboClump);
// cmd.dispatch(1);

// clump
cmd.setUniforms(shaders.vsmClumpPages, vsm.uboClump);
Expand All @@ -883,11 +896,20 @@ void Renderer::drawVsm(Tempest::Encoder<Tempest::CommandBuffer>& cmd, uint8_t fI
cmd.dispatch(1);

cmd.setDebugMarker("VSM-visibility");
view.visibilityVsm(cmd,fId);
wview.visibilityVsm(cmd,fId);

cmd.setDebugMarker("VSM-rendering");
cmd.setFramebuffer({}, {vsm.pageData, 0.f, Tempest::Preserve});
view.drawVsm(cmd,fId);
wview.drawVsm(cmd,fId);

if(false) {
cmd.setDebugMarker("VSM-reproject");
cmd.setFramebuffer({}, {shadowMap[1], 0.f, Tempest::Preserve});
auto viewShadowLwcInv = shadowMatrix[1];
viewShadowLwcInv.inverse();
cmd.setUniforms(shaders.vsmReprojectSm, vsm.uboReproj, &viewShadowLwcInv, sizeof(viewShadowLwcInv));
cmd.draw(Resources::fsqVbo());
}
}

void Renderer::drawSwr(Tempest::Encoder<Tempest::CommandBuffer>& cmd, uint8_t fId, WorldView& view) {
Expand Down Expand Up @@ -940,10 +962,9 @@ void Renderer::drawUnderwater(Encoder<CommandBuffer>& cmd, uint8_t fId) {
}

void Renderer::drawShadowMap(Encoder<CommandBuffer>& cmd, uint8_t fId, WorldView& view) {
if(settings.shadowResolution<=0)
return;

for(uint8_t i=0; i<Resources::ShadowLayers; ++i) {
if(shadowMap[i].isEmpty())
continue;
cmd.setDebugMarker(string_frm("ShadowMap #",i));
cmd.setFramebuffer({}, {shadowMap[i], 0.f, Tempest::Preserve});
if(view.mainLight().dir().y > Camera::minShadowY)
Expand Down
1 change: 1 addition & 0 deletions game/graphics/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ class Renderer final {
Tempest::DescriptorSet uboClear;
Tempest::DescriptorSet uboClearPages;
Tempest::DescriptorSet uboPages;
Tempest::DescriptorSet uboReproj;

Tempest::DescriptorSet uboClump, uboAlloc;

Expand Down
14 changes: 14 additions & 0 deletions game/graphics/shaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,14 +200,28 @@ Shaders::Shaders() {
vsmClear = computeShader("vsm_clear.comp.sprv");
vsmClearPages = computeShader("vsm_clear_pages.comp.sprv");
vsmMarkPages = computeShader("vsm_mark_pages.comp.sprv");
vsmMarkSky = computeShader("fog3d_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");
vsmPackDraw1 = computeShader("vsm_pack_draws1.comp.sprv");
vsmDirectLight = postEffect("copy", "direct_light_vsm", RenderState::ZTestMode::NoEqual);
// vsmReprojectSm = postEffect("copy", "vsm_reproject_sm", RenderState::ZTestMode::Always);
vsmDbg = postEffect("copy", "vsm_dbg", RenderState::ZTestMode::Always);
vsmRendering = computeShader("vsm_rendering.comp.sprv");
{
RenderState state;
state.setZWriteEnabled(true);
state.setZTestMode (RenderState::ZTestMode::Always);
state.setCullFaceMode (RenderState::CullMode::Front);

auto sh = GothicShader::get("copy.vert.sprv");
auto vs = device.shader(sh.data,sh.len);
sh = GothicShader::get("vsm_reproject_sm.frag.sprv");
auto fs = device.shader(sh.data,sh.len);
vsmReprojectSm = device.pipeline(Triangles,state,vs,fs);
}
}

if(Gothic::options().swRenderingPreset>0) {
Expand Down
3 changes: 2 additions & 1 deletion game/graphics/shaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,11 @@ class Shaders {

// Virtual shadow
Tempest::ComputePipeline vsmClusterTask;
Tempest::ComputePipeline vsmClear, vsmClearPages, vsmMarkPages;
Tempest::ComputePipeline vsmClear, vsmClearPages, vsmMarkPages, vsmMarkSky;
Tempest::ComputePipeline vsmTrimPages, vsmClumpPages, vsmAllocPages;
Tempest::ComputePipeline vsmPackDraw0, vsmPackDraw1;
Tempest::RenderPipeline vsmDirectLight;
Tempest::RenderPipeline vsmReprojectSm;
Tempest::RenderPipeline vsmDbg;

Tempest::ComputePipeline vsmRendering;
Expand Down
20 changes: 20 additions & 0 deletions game/graphics/sky/sky.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,15 @@ void Sky::prepareUniforms() {
uboOcclusion.set(4, *scene.shadowMap[1], Resources::shadowSampler());
}

if(quality==VolumetricHQVsm) {
uboVsmPages = device.descriptors(Shaders::inst().vsmMarkSky);
uboVsmPages.set(1, *scene.zbuffer, Sampler::nearest());
uboVsmPages.set(2, scene.uboGlobal[SceneGlobals::V_Main]);
uboVsmPages.set(3, occlusionLut);
uboVsmPages.set(4, *scene.vsmPageTbl);
uboVsmPages.set(5, *scene.vsmPageHiZ);
}

uboFogViewLut3d = device.descriptors(Shaders::inst().fogViewLut3d);
uboFogViewLut3d.set(0, scene.uboGlobal[SceneGlobals::V_Main]);
uboFogViewLut3d.set(1, transLut, smpB);
Expand Down Expand Up @@ -446,6 +455,17 @@ void Sky::prepareSky(Tempest::Encoder<Tempest::CommandBuffer>& cmd, uint32_t fra
cmd.draw(Resources::fsqVbo());
}

void Sky::vsmMarkPage(Tempest::Encoder<Tempest::CommandBuffer>& cmd, uint32_t frameId) {
if(quality!=VolumetricHQVsm)
return;

UboSky ubo = mkPush();
auto& vsmMarkSky = Shaders::inst().vsmMarkSky;
cmd.setFramebuffer({});
cmd.setUniforms(vsmMarkSky, uboVsmPages, &ubo, sizeof(ubo));
cmd.dispatchThreads(occlusionLut.size());
}

void Sky::prepareFog(Tempest::Encoder<Tempest::CommandBuffer>& cmd, uint32_t frameId) {
UboSky ubo = mkPush();

Expand Down
2 changes: 2 additions & 0 deletions game/graphics/sky/sky.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Sky final {
void updateLight(const int64_t now);

void prepareSky (Tempest::Encoder<Tempest::CommandBuffer>& p, uint32_t frameId);
void vsmMarkPage(Tempest::Encoder<Tempest::CommandBuffer>& p, uint32_t frameId);
void drawSky (Tempest::Encoder<Tempest::CommandBuffer>& p, uint32_t frameId);
void drawSunMoon(Tempest::Encoder<Tempest::CommandBuffer>& p, uint32_t frameId);

Expand Down Expand Up @@ -82,6 +83,7 @@ class Sky final {
Tempest::DescriptorSet uboFogViewLut3d;
Tempest::DescriptorSet uboSky, uboFog, uboFog3d;
Tempest::DescriptorSet uboOcclusion, uboShadowRq;
Tempest::DescriptorSet uboVsmPages;
Tempest::DescriptorSet uboIrradiance, uboExp;

Tempest::DescriptorSet uboSkyPathtrace;
Expand Down
4 changes: 4 additions & 0 deletions game/graphics/worldview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ void WorldView::prepareExposure(Tempest::Encoder<Tempest::CommandBuffer>& cmd, u
gSky.prepareExposure(cmd, frameId);
}

void WorldView::vsmMarkSkyPages(Tempest::Encoder<Tempest::CommandBuffer>& cmd, uint8_t frameId) {
gSky.vsmMarkPage(cmd, frameId);
}

void WorldView::updateFrustrum(const Frustrum fr[]) {
for(uint8_t i=0; i<SceneGlobals::V_Count; ++i)
sGlobal.frustrum[i] = fr[i];
Expand Down
2 changes: 2 additions & 0 deletions game/graphics/worldview.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ class WorldView {
void prepareIrradiance(Tempest::Encoder<Tempest::CommandBuffer> &cmd, uint8_t frameId);
void prepareExposure (Tempest::Encoder<Tempest::CommandBuffer> &cmd, uint8_t frameId);

void vsmMarkSkyPages (Tempest::Encoder<Tempest::CommandBuffer> &cmd, uint8_t frameId);

bool updateLights();
bool updateRtScene();

Expand Down
11 changes: 6 additions & 5 deletions shader/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -234,12 +234,12 @@ add_shader(sky_view_clouds_lut.frag sky/sky_view_clouds_lut.frag)
add_shader(shadow_downsample.comp sky/shadow_downsample.comp)
add_shader(clouds_lut.comp sky/clouds_lut.comp)

add_shader(fog_view_lut.comp sky/fog_view_lut.comp -DCOMPUTE)

add_shader(fog3d_hq.frag sky/fog.frag -S frag -DVOLUMETRIC)
add_shader(fog3d.comp sky/fog.frag -S comp -DVOLUMETRIC -DCOMPUTE)
add_shader(fog3d_vsm.comp sky/fog.frag -S comp -DVOLUMETRIC -DCOMPUTE -DVIRTUAL_SHADOW)
add_shader(fog_view_lut.comp sky/fog_view_lut.comp)

add_shader(fog3d.comp sky/fog.frag -S comp -DVOLUMETRIC)
add_shader(fog3d_vsm_mark_pages.comp sky/fog.frag -S comp -DVOLUMETRIC -DVIRTUAL_SHADOW_MARK)
add_shader(fog3d_vsm.comp sky/fog.frag -S comp -DVOLUMETRIC -DVIRTUAL_SHADOW)
add_shader(fog3d_hq.frag sky/fog.frag -DVOLUMETRIC)
add_shader(fog.frag sky/fog.frag)
add_shader(sky.frag sky/sky.frag)

Expand Down Expand Up @@ -299,6 +299,7 @@ add_shader(cmaa2_deferred_color_apply_2x2.frag antialiasing/cmaa2/deferred_c

# virtual shadows
add_shader(direct_light_vsm.frag virtual_shadow/vsm_direct_light.frag)
add_shader(vsm_reproject_sm.frag virtual_shadow/vsm_reproject_sm.frag)
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)
Expand Down
19 changes: 19 additions & 0 deletions shader/common.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,25 @@ uvec4 unpackUint4x8(uint v) {
return r;
}

uint pack565_16(ivec3 a, uint b) {
uint x = (a.x & 0x1F) << 0;
uint y = (a.y & 0x3F) << 5;
uint z = (a.z & 0x1F) << 11;
uint w = ( b & 0xFFFF);
//uint d = uint(z*0xFFFF) << 16;
return ((x | y | z) << 16) | w;
}

uvec4 unpack565_16(uint p) {
uvec4 ret;
ret.w = p & 0xFFFF;
p = p >> 16;
ret.x = (p >> 0) & 0x1F;
ret.y = (p >> 5) & 0x3F;
ret.z = (p >> 11) & 0x1F;
return ret;
}

uint encodeNormal(vec3 n) {
return octahedral_32(n);
}
Expand Down
Loading

0 comments on commit 0c229cf

Please sign in to comment.