@@ -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+
280297void 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+
20362176void Renderer::drawProbesDbg (Encoder<CommandBuffer>& cmd, const WorldView& wview) {
20372177 if (!settings.giEnabled )
20382178 return ;
0 commit comments