Skip to content

Commit 07d2e5a

Browse files
Merge branch 'Try:master' into nix-flake
2 parents 51cd68a + 62fb06e commit 07d2e5a

13 files changed

Lines changed: 745 additions & 25 deletions

File tree

game/gothic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ class Gothic final {
146146
bool isBenchmarkModeCi() const;
147147
void setBenchmarkMode(Benchmark b);
148148

149-
Tempest::Signal<void()> toggleGi, toggleVsm, toggleRtsm;
149+
Tempest::Signal<void()> toggleGi, toggleVsm, toggleRtsm, togglePathtrace;
150150

151151
LoadState checkLoading() const;
152152
bool finishLoading();

game/graphics/renderer.cpp

Lines changed: 147 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ Renderer::Renderer(Tempest::Swapchain& swapchain)
8686
Gothic::inst().toggleVsm .bind(this, &Renderer::toggleVsm);
8787
Gothic::inst().toggleRtsm.bind(this, &Renderer::toggleRtsm);
8888

89+
Gothic::inst().togglePathtrace.bind(this, &Renderer::togglePathtrace);
90+
8991
settings.giEnabled = Gothic::options().doRtGi;
9092
settings.vsmEnabled = Gothic::options().doVirtualShadow;
9193
settings.rtsmEnabled = Gothic::options().doSoftwareShadow;
@@ -277,6 +279,21 @@ void Renderer::toggleRtsm() {
277279
}
278280
}
279281

282+
void Renderer::togglePathtrace() {
283+
settings.pathTraceEnabled = !settings.pathTraceEnabled;
284+
285+
pt.numFrames = 0;
286+
287+
auto& device = Resources::device();
288+
device.waitIdle();
289+
290+
setupSettings();
291+
resetSwapchain();
292+
if(auto wview = Gothic::inst().worldView()) {
293+
wview->resetRendering();
294+
}
295+
}
296+
280297
void Renderer::onWorldChanged() {
281298
sky.lutIsInitialized = false;
282299
shaders.waitCompiler();
@@ -308,7 +325,7 @@ bool Renderer::requiresTlas() const {
308325
if(!Gothic::options().doRayQuery)
309326
return false;
310327

311-
if(settings.giEnabled)
328+
if(settings.giEnabled || settings.pathTraceEnabled)
312329
return true;
313330
if(!(settings.rtsmEnabled || settings.vsmEnabled))
314331
return true;
@@ -387,11 +404,14 @@ void Renderer::resetShadowmap() {
387404
for(int i=0; i<Resources::ShadowLayers; ++i)
388405
Resources::recycle(std::move(shadowMap[i]));
389406

407+
const bool forceSm1 = (settings.giEnabled || settings.pathTraceEnabled || sky.quality==PathTrace);
390408
for(int i=0; i<Resources::ShadowLayers; ++i) {
391-
if(settings.vsmEnabled && !(settings.giEnabled && i==1) && !(sky.quality==PathTrace && i==1) && !(settings.rtsmEnabled && i==1))
392-
continue; //TODO: support vsm in gi code
393-
if(settings.rtsmEnabled && !(settings.giEnabled && i==1) && !(sky.quality!=None && i==1))
394-
continue; //TODO: support vsm in gi code
409+
if(!(i==1 && forceSm1)) {
410+
if(settings.vsmEnabled && !(settings.rtsmEnabled && i==1))
411+
continue; //TODO: support vsm in gi code
412+
if(settings.rtsmEnabled && !(sky.quality!=None && i==1))
413+
continue; //TODO: support vsm in gi code
414+
}
395415
shadowMap[i] = device.zbuffer(shadowFormat, settings.shadowResolution, settings.shadowResolution);
396416
}
397417
}
@@ -601,6 +621,14 @@ void Renderer::draw(Tempest::Attachment& result, Encoder<CommandBuffer>& cmd, ui
601621
wview->preFrameUpdate(*camera,Gothic::inst().world()->tickCount(),fId);
602622
wview->prepareGlobals(cmd,fId);
603623

624+
if(settings.pathTraceEnabled) {
625+
drawPathtrace(cmd, *wview, fId);
626+
cmd.setDebugMarker("Tonemapping");
627+
drawTonemapping(result, cmd, *wview);
628+
wview->postFrameupdate();
629+
return;
630+
}
631+
604632
wview->visibilityPass(cmd, 0);
605633
prepareSky(cmd,*wview);
606634

@@ -647,6 +675,7 @@ void Renderer::draw(Tempest::Attachment& result, Encoder<CommandBuffer>& cmd, ui
647675
drawVsmDbg(cmd, *wview);
648676
drawSwrDbg(cmd, *wview);
649677
drawRtsmDbg(cmd, *wview);
678+
drawRayQueryDbg(cmd, *wview);
650679

651680
cmd.setFramebuffer({{sceneLinear, Tempest::Preserve, Tempest::Preserve}});
652681
drawReflections(cmd, *wview);
@@ -666,6 +695,8 @@ void Renderer::draw(Tempest::Attachment& result, Encoder<CommandBuffer>& cmd, ui
666695
drawTonemapping(result, cmd, *wview);
667696
}
668697

698+
//drawRayQueryDbg(cmd, *wview);
699+
669700
wview->postFrameupdate();
670701
}
671702

@@ -1783,7 +1814,7 @@ void Renderer::prepareFog(Encoder<Tempest::CommandBuffer>& cmd, WorldView& wview
17831814
cmd.dispatchThreads(uint32_t(sky.fogLut3D.w()), uint32_t(sky.fogLut3D.h()));
17841815
}
17851816

1786-
if(settings.vsmEnabled && (sky.quality==VolumetricHQ || sky.quality==Epipolar)) {
1817+
if(settings.vsmEnabled && !settings.pathTraceEnabled && (sky.quality==VolumetricHQ || sky.quality==Epipolar)) {
17871818
cmd.setFramebuffer({});
17881819
cmd.setDebugMarker("VSM-epipolar-fog");
17891820
cmd.setBinding(0, epipolar.epTrace);
@@ -1800,7 +1831,7 @@ void Renderer::prepareFog(Encoder<Tempest::CommandBuffer>& cmd, WorldView& wview
18001831
case VolumetricLQ:
18011832
break;
18021833
case VolumetricHQ: {
1803-
if(settings.vsmEnabled && !settings.rtsmEnabled) {
1834+
if(settings.vsmEnabled && !settings.rtsmEnabled && !settings.pathTraceEnabled) {
18041835
cmd.setFramebuffer({});
18051836
cmd.setBinding(0, sky.occlusionLut);
18061837
cmd.setBinding(1, epipolar.epTrace);
@@ -2033,6 +2064,115 @@ void Renderer::prepareExposure(Encoder<CommandBuffer>& cmd, WorldView& wview) {
20332064
cmd.dispatch(1);
20342065
}
20352066

2067+
void Renderer::drawPathtrace(Tempest::Encoder<Tempest::CommandBuffer>& cmd, WorldView& wview, uint8_t fId) {
2068+
if(wview.sceneGlobals().rtScene.tlas.isEmpty())
2069+
return;
2070+
2071+
static bool enable = true;
2072+
if(!enable)
2073+
return;
2074+
2075+
if(!settings.pathTraceEnabled)
2076+
return;
2077+
2078+
if(pt.frame.size()!=sceneLinear.size()) {
2079+
Resources::recycle(std::move(pt.frame));
2080+
pt.frame = Resources::device().attachment(Tempest::R11G11B10UF, sceneLinear.size());
2081+
}
2082+
2083+
cmd.setFramebuffer({});
2084+
prepareSky(cmd, wview);
2085+
prepareIrradiance(cmd,wview);
2086+
prepareExposure(cmd,wview);
2087+
2088+
drawShadowMap(cmd,fId,wview);
2089+
2090+
static float eps = 2.f;
2091+
for(int i=0; i<16; ++i) {
2092+
float a = viewProj.data()[i];
2093+
float b = pt.mvpLast.data()[i];
2094+
if(std::abs(a-b)>eps) {
2095+
pt.numFrames = 0;
2096+
break;
2097+
}
2098+
}
2099+
2100+
if(pt.numFrames==0)
2101+
pt.mvpLast = viewProj;
2102+
2103+
struct Push {
2104+
uint32_t numFrames;
2105+
};
2106+
Push push;
2107+
push.numFrames = pt.numFrames; ++pt.numFrames;
2108+
2109+
if(push.numFrames==0)
2110+
cmd.setFramebuffer({{pt.frame, Vec4(0), Tempest::Preserve}}, {zbuffer, 1, Tempest::Preserve}); else
2111+
cmd.setFramebuffer({{pt.frame, Tempest::Preserve, Tempest::Preserve}}, {zbuffer, 1, Tempest::Preserve});
2112+
auto& scene = wview.sceneGlobals();
2113+
cmd.setDebugMarker("Pathtrace");
2114+
cmd.setPushData(push);
2115+
cmd.setBinding(0, scene.uboGlobal[SceneGlobals::V_Main]);
2116+
//cmd.setBinding(1, zbuffer);
2117+
cmd.setBinding(2, sky.irradianceLut);
2118+
cmd.setBinding(3, sky.viewCldLut);
2119+
//cmd.setBinding(4, shadowMap[1], Sampler::bilinear());
2120+
cmd.setBinding(4, Resources::fallbackBlack(), Sampler::bilinear());
2121+
//
2122+
cmd.setBinding(6, scene.rtScene.tlas);
2123+
cmd.setBinding(7, Sampler::trillinear());
2124+
cmd.setBinding(8, scene.rtScene.tex);
2125+
cmd.setBinding(9, scene.rtScene.vbo);
2126+
cmd.setBinding(10,scene.rtScene.ibo);
2127+
cmd.setBinding(11,scene.rtScene.rtDesc);
2128+
2129+
cmd.setPipeline(shaders.rtPathtrace);
2130+
cmd.draw(nullptr, 0, 3);
2131+
2132+
prepareFog(cmd,wview);
2133+
2134+
cmd.setFramebuffer({{sceneLinear, Tempest::Discard, Tempest::Preserve}});
2135+
cmd.setDebugMarker("Blit");
2136+
cmd.setBinding(0, pt.frame, Sampler::nearest());
2137+
cmd.setPipeline(shaders.copy);
2138+
cmd.draw(nullptr, 0, 3);
2139+
2140+
cmd.setFramebuffer({{sceneLinear, Tempest::Discard, Tempest::Preserve}}, {zbuffer, Tempest::Readonly});
2141+
cmd.setDebugMarker("Sky");
2142+
drawSky(cmd,wview);
2143+
drawSunMoon(cmd,wview);
2144+
2145+
cmd.setDebugMarker("Fog");
2146+
drawFog(cmd, wview);
2147+
}
2148+
2149+
void Renderer::drawRayQueryDbg(Tempest::Encoder<Tempest::CommandBuffer>& cmd, const WorldView& wview) {
2150+
if(wview.sceneGlobals().rtScene.tlas.isEmpty() || shadowMap[1].isEmpty())
2151+
return;
2152+
2153+
static bool enable = false;
2154+
if(!enable)
2155+
return;
2156+
2157+
auto& scene = wview.sceneGlobals();
2158+
cmd.setDebugMarker("RQ-dbg");
2159+
cmd.setBinding(0, scene.uboGlobal[SceneGlobals::V_Main]);
2160+
cmd.setBinding(1, zbuffer);
2161+
cmd.setBinding(2, sky.irradianceLut);
2162+
cmd.setBinding(3, shadowMap[1], Sampler::bilinear());
2163+
//
2164+
cmd.setBinding(6, scene.rtScene.tlas);
2165+
cmd.setBinding(7, Sampler::trillinear());
2166+
cmd.setBinding(8, scene.rtScene.tex);
2167+
cmd.setBinding(9, scene.rtScene.vbo);
2168+
cmd.setBinding(10,scene.rtScene.ibo);
2169+
cmd.setBinding(11,scene.rtScene.rtDesc);
2170+
2171+
cmd.setFramebuffer({{sceneLinear, Tempest::Preserve, Tempest::Preserve}}, {zbuffer, Tempest::Readonly});
2172+
cmd.setPipeline(shaders.rtDbg);
2173+
cmd.draw(nullptr, 0, 3);
2174+
}
2175+
20362176
void Renderer::drawProbesDbg(Encoder<CommandBuffer>& cmd, const WorldView& wview) {
20372177
if(!settings.giEnabled)
20382178
return;

game/graphics/renderer.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,11 @@ class Renderer final {
8787
void drawSunMoon (Tempest::Encoder<Tempest::CommandBuffer>& cmd, const WorldView& wview, bool isSun);
8888

8989
void drawSwRT (Tempest::Encoder<Tempest::CommandBuffer>& cmd, const WorldView& wview);
90+
void drawPathtrace (Tempest::Encoder<Tempest::CommandBuffer>& cmd, WorldView& wview, uint8_t fId);
9091

9192
void stashSceneAux (Tempest::Encoder<Tempest::CommandBuffer>& cmd);
9293

94+
void drawRayQueryDbg (Tempest::Encoder<Tempest::CommandBuffer>& cmd, const WorldView& wview);
9395
void drawProbesDbg (Tempest::Encoder<Tempest::CommandBuffer>& cmd, const WorldView& wview);
9496
void drawProbesHitDbg (Tempest::Encoder<Tempest::CommandBuffer>& cmd);
9597
void drawVsmDbg (Tempest::Encoder<Tempest::CommandBuffer>& cmd, const WorldView& wview);
@@ -100,13 +102,15 @@ class Renderer final {
100102
void toggleGi();
101103
void toggleVsm();
102104
void toggleRtsm();
105+
void togglePathtrace();
103106

104107
struct Settings {
105108
const uint32_t shadowResolution = 2048;
106109
bool vsmEnabled = false;
107110
bool rtsmEnabled = false;
108111
bool swrEnabled = false;
109112
bool swrtEnabled = false;
113+
bool pathTraceEnabled = false;
110114

111115
bool zEnvMappingEnabled = false;
112116
bool zCloudShadowScale = false;
@@ -201,6 +205,12 @@ class Renderer final {
201205
Tempest::StorageImage probesLightingPrev;
202206
} gi;
203207

208+
struct {
209+
Tempest::Attachment frame;
210+
uint32_t numFrames = 0;
211+
Tempest::Matrix4x4 mvpLast;
212+
} pt;
213+
204214
struct {
205215
Tempest::StorageBuffer epipoles;
206216
Tempest::StorageImage epTrace;

game/graphics/rtscene.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,20 @@
66

77
using namespace Tempest;
88

9+
static bool isSupported(Material::AlphaFunc alpha, RtScene::Category cat) {
10+
if(cat!=RtScene::Landscape && cat!=RtScene::Static)
11+
return false; // not supported
12+
if(alpha!=Material::Solid && alpha!=Material::AlphaTest && alpha!=Material::Water)
13+
return false; // not supported
14+
return true;
15+
}
16+
917
RtScene::RtScene() {
1018
}
1119

1220
void RtScene::notifyTlas(const Material& mat, Category cat) const {
13-
if(cat!=Landscape && cat!=Static)
14-
return; // not supported
15-
if(mat.alpha!=Material::Solid && mat.alpha!=Material::AlphaTest)
16-
return; // not supported
21+
if(!isSupported(mat.alpha, cat))
22+
return;
1723
needToUpdate = true;
1824
}
1925

@@ -37,10 +43,8 @@ uint32_t RtScene::aquireBucketId(const Material& mat, const StaticMesh& mesh) {
3743
void RtScene::addInstance(const Matrix4x4& pos, const AccelerationStructure& blas,
3844
const Material& mat, const StaticMesh& mesh, size_t firstIndex, size_t iboLength,
3945
Category cat) {
40-
if(cat!=Landscape && cat!=Static)
41-
return; // not supported
42-
if(mat.alpha!=Material::Solid && mat.alpha!=Material::AlphaTest && mat.alpha!=Material::Water)
43-
return; // not supported
46+
if(!isSupported(mat.alpha, cat))
47+
return;
4448

4549
const uint32_t bucketId = aquireBucketId(mat,mesh);
4650
const uint32_t firstPrimitive = uint32_t(firstIndex/3);
@@ -65,6 +69,9 @@ void RtScene::addInstance(const Matrix4x4& pos, const AccelerationStructure& bla
6569
ix.flags = RtInstanceFlags::Opaque;
6670
ix.flags = ix.flags | RtInstanceFlags::CullFlip;
6771

72+
if(mat.alpha==Material::Solid)
73+
ix.flags = ix.flags | RtInstanceFlags::CullDisable;
74+
6875
if(mat.alpha==Material::Solid)
6976
ix.mask = CullMask::CM_Opaque;
7077
else if(mat.alpha==Material::AlphaTest)
@@ -74,12 +81,12 @@ void RtScene::addInstance(const Matrix4x4& pos, const AccelerationStructure& bla
7481
else
7582
ix.mask = CullMask::CM_Unknown;
7683

77-
if(mat.alpha==Material::Solid && (cat==Landscape /*|| cat==Static*/)) {
84+
if(mat.alpha==Material::Solid && cat==Landscape) {
7885
build.staticOpaque.geom .push_back({mesh.vbo, mesh.ibo, firstIndex, iboLength});
7986
build.staticOpaque.rtDesc.push_back(desc);
8087
return;
8188
}
82-
if(mat.alpha==Material::AlphaTest && (cat==Landscape /*|| cat==Static*/)) {
89+
if(mat.alpha==Material::AlphaTest && cat==Landscape) {
8390
build.staticAt.geom .push_back({mesh.vbo, mesh.ibo, firstIndex, iboLength});
8491
build.staticAt.rtDesc.push_back(desc);
8592
return;
@@ -96,7 +103,8 @@ void RtScene::addInstance(const BuildBlas& ctx, Tempest::AccelerationStructure&
96103
Tempest::RtInstance ix;
97104
ix.mat = Matrix4x4::mkIdentity();
98105
ix.id = uint32_t(build.rtDesc.size());
99-
ix.flags = flags | RtInstanceFlags::CullFlip;
106+
ix.flags = ix.flags | flags;
107+
ix.flags = ix.flags | RtInstanceFlags::CullFlip;
100108
ix.blas = &blas;
101109
build.inst.push_back(ix);
102110

@@ -106,7 +114,7 @@ void RtScene::addInstance(const BuildBlas& ctx, Tempest::AccelerationStructure&
106114
void RtScene::buildTlas() {
107115
needToUpdate = false;
108116

109-
addInstance(build.staticOpaque, blasStaticOpaque, Tempest::RtInstanceFlags::Opaque);
117+
addInstance(build.staticOpaque, blasStaticOpaque, Tempest::RtInstanceFlags::Opaque | RtInstanceFlags::CullDisable);
110118
addInstance(build.staticAt, blasStaticAt, Tempest::RtInstanceFlags::NonOpaque);
111119

112120
Resources::recycle(std::move(tex));

game/graphics/shaders.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,25 @@ void Shaders::compileShaders() {
178178
hiZPot = computeShader("hiz_pot.comp.sprv");
179179
hiZMip = computeShader("hiz_mip.comp.sprv");
180180

181+
if(Gothic::options().doRayQuery) {
182+
rtDbg = postEffect("triangle_uv", "rt_dbg", RenderState::ZTestMode::NoEqual);
183+
}
184+
185+
if(Gothic::options().doRayQuery) {
186+
RenderState state;
187+
state.setZTestMode (RenderState::ZTestMode::Always);
188+
state.setZWriteEnabled(true);
189+
state.setBlendSource (RenderState::BlendMode::SrcAlpha);
190+
state.setBlendDest (RenderState::BlendMode::OneMinusSrcAlpha);
191+
192+
auto sh = GothicShader::get(string_frm("triangle_uv",".vert.sprv"));
193+
auto vs = device.shader(sh.data,sh.len);
194+
195+
sh = GothicShader::get(string_frm("pathtrace",".frag.sprv"));
196+
auto fs = device.shader(sh.data,sh.len);
197+
rtPathtrace = device.pipeline(Triangles,state,vs,fs);
198+
}
199+
181200
if(Gothic::options().doRayQuery) {
182201
RenderState state;
183202
state.setCullFaceMode(RenderState::CullMode::NoCull);

game/graphics/shaders.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ class Shaders {
7272
Tempest::ComputePipeline clusterInit, clusterPatch;
7373
Tempest::ComputePipeline visibilityPassSh, visibilityPassHiZ, visibilityPassHiZCr;
7474

75+
// RT/RQ
76+
Tempest::RenderPipeline rtDbg;
77+
Tempest::RenderPipeline rtPathtrace;
78+
7579
// GI
7680
Tempest::RenderPipeline probeDbg, probeHitDbg;
7781
Tempest::ComputePipeline probeInit, probeClear, probeClearHash, probeMakeHash;

0 commit comments

Comments
 (0)