Reflections.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Renderer/Reflections.h>
  6. #include <AnKi/Renderer/Renderer.h>
  7. #include <AnKi/Renderer/AccelerationStructureBuilder.h>
  8. #include <AnKi/Renderer/GBuffer.h>
  9. #include <AnKi/Renderer/MotionVectors.h>
  10. #include <AnKi/Renderer/Sky.h>
  11. #include <AnKi/Renderer/Bloom.h>
  12. #include <AnKi/Renderer/DepthDownscale.h>
  13. #include <AnKi/Renderer/ShadowMapping.h>
  14. #include <AnKi/Renderer/ClusterBinning.h>
  15. #include <AnKi/Renderer/ProbeReflections.h>
  16. #include <AnKi/GpuMemory/GpuVisibleTransientMemoryPool.h>
  17. #include <AnKi/GpuMemory/UnifiedGeometryBuffer.h>
  18. #include <AnKi/Scene/Components/SkyboxComponent.h>
  19. #include <AnKi/Util/Tracer.h>
  20. #include <AnKi/Resource/ImageAtlasResource.h>
  21. #include <AnKi/Shaders/Include/MaterialTypes.h>
  22. namespace anki {
  23. Error Reflections::init()
  24. {
  25. ANKI_CHECK(RtMaterialFetchRendererObject::init());
  26. const Bool bRtReflections = GrManager::getSingleton().getDeviceCapabilities().m_rayTracingEnabled && g_rtReflectionsCVar;
  27. const Bool bSsrSamplesGBuffer = bRtReflections;
  28. std::initializer_list<SubMutation> mutation = {{"SSR_SAMPLE_GBUFFER", bSsrSamplesGBuffer}};
  29. // Ray gen and miss
  30. if(bRtReflections)
  31. {
  32. ANKI_CHECK(ResourceManager::getSingleton().loadResource("ShaderBinaries/Reflections.ankiprogbin", m_mainProg));
  33. ShaderProgramResourceVariantInitInfo variantInitInfo(m_mainProg);
  34. variantInitInfo.requestTechniqueAndTypes(ShaderTypeBit::kRayGen, "RtMaterialFetch");
  35. variantInitInfo.addMutation("SSR_SAMPLE_GBUFFER", bSsrSamplesGBuffer);
  36. const ShaderProgramResourceVariant* variant;
  37. m_mainProg->getOrCreateVariant(variantInitInfo, variant);
  38. m_libraryGrProg.reset(&variant->getProgram());
  39. m_rayGenShaderGroupIdx = variant->getShaderGroupHandleIndex();
  40. ANKI_CHECK(ResourceManager::getSingleton().loadResource("ShaderBinaries/RtMaterialFetchMiss.ankiprogbin", m_missProg));
  41. ShaderProgramResourceVariantInitInfo variantInitInfo2(m_missProg);
  42. variantInitInfo2.requestTechniqueAndTypes(ShaderTypeBit::kMiss, "RtMaterialFetch");
  43. m_missProg->getOrCreateVariant(variantInitInfo2, variant);
  44. m_missShaderGroupIdx = variant->getShaderGroupHandleIndex();
  45. m_sbtRecordSize = getAlignedRoundUp(GrManager::getSingleton().getDeviceCapabilities().m_sbtRecordAlignment,
  46. GrManager::getSingleton().getDeviceCapabilities().m_shaderGroupHandleSize + U32(sizeof(UVec4)));
  47. }
  48. ANKI_CHECK(loadShaderProgram("ShaderBinaries/Reflections.ankiprogbin", mutation, m_mainProg, m_spatialDenoisingGrProg, "SpatialDenoise"));
  49. ANKI_CHECK(loadShaderProgram("ShaderBinaries/Reflections.ankiprogbin", mutation, m_mainProg, m_temporalDenoisingGrProg, "TemporalDenoise"));
  50. ANKI_CHECK(loadShaderProgram("ShaderBinaries/Reflections.ankiprogbin", mutation, m_mainProg, m_verticalBilateralDenoisingGrProg,
  51. "BilateralDenoiseVertical"));
  52. ANKI_CHECK(loadShaderProgram("ShaderBinaries/Reflections.ankiprogbin", mutation, m_mainProg, m_horizontalBilateralDenoisingGrProg,
  53. "BilateralDenoiseHorizontal"));
  54. ANKI_CHECK(loadShaderProgram("ShaderBinaries/Reflections.ankiprogbin", mutation, m_mainProg, m_ssrGrProg, "Ssr"));
  55. ANKI_CHECK(loadShaderProgram("ShaderBinaries/Reflections.ankiprogbin", mutation, m_mainProg, m_probeFallbackGrProg, "ReflectionProbeFallback"));
  56. ANKI_CHECK(loadShaderProgram("ShaderBinaries/Reflections.ankiprogbin", mutation, m_mainProg, m_tileClassificationGrProg, "Classification"));
  57. m_transientRtDesc1 = getRenderer().create2DRenderTargetDescription(
  58. getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y(), Format::kR16G16B16A16_Sfloat, "Reflections #1");
  59. m_transientRtDesc1.bake();
  60. m_transientRtDesc2 = getRenderer().create2DRenderTargetDescription(
  61. getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y(), Format::kR16G16B16A16_Sfloat, "Reflections #2");
  62. m_transientRtDesc2.bake();
  63. m_hitPosAndDepthRtDesc = getRenderer().create2DRenderTargetDescription(
  64. getRenderer().getInternalResolution().x() / 2u, getRenderer().getInternalResolution().y(), Format::kR16G16B16A16_Sfloat, "HitPosAndDepth");
  65. m_hitPosAndDepthRtDesc.bake();
  66. m_hitPosRtDesc = getRenderer().create2DRenderTargetDescription(getRenderer().getInternalResolution().x(),
  67. getRenderer().getInternalResolution().y(), Format::kR16G16B16A16_Sfloat, "HitPos");
  68. m_hitPosRtDesc.bake();
  69. TextureInitInfo texInit = getRenderer().create2DRenderTargetDescription(
  70. getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y(), getRenderer().getHdrFormat(), "ReflectionsMain");
  71. texInit.m_usage = TextureUsageBit::kAllShaderResource | TextureUsageBit::kAllUav;
  72. m_tex = getRenderer().createAndClearRenderTarget(texInit, TextureUsageBit::kSrvCompute);
  73. texInit = getRenderer().create2DRenderTargetDescription(getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y(),
  74. Format::kR32G32_Sfloat, "ReflectionsMoments #1");
  75. texInit.m_usage = TextureUsageBit::kAllShaderResource | TextureUsageBit::kAllUav;
  76. m_momentsTextures[0] = getRenderer().createAndClearRenderTarget(texInit, TextureUsageBit::kSrvCompute);
  77. texInit.setName("ReflectionsMoments #2");
  78. m_momentsTextures[1] = getRenderer().createAndClearRenderTarget(texInit, TextureUsageBit::kSrvCompute);
  79. m_classTileMapRtDesc = getRenderer().create2DRenderTargetDescription((getRenderer().getInternalResolution().x() + kTileSize - 1) / kTileSize,
  80. (getRenderer().getInternalResolution().y() + kTileSize - 1) / kTileSize,
  81. Format::kR8_Uint, "ReflClassTileMap");
  82. m_classTileMapRtDesc.bake();
  83. {
  84. BufferInitInfo buffInit("ReflRayGenIndirectArgs");
  85. buffInit.m_size = sizeof(DispatchIndirectArgs) * 2;
  86. buffInit.m_usage = BufferUsageBit::kAllIndirect | BufferUsageBit::kUavCompute;
  87. m_indirectArgsBuffer = GrManager::getSingleton().newBuffer(buffInit);
  88. CommandBufferInitInfo cmdbInit("Init buffer");
  89. cmdbInit.m_flags |= CommandBufferFlag::kSmallBatch;
  90. CommandBufferPtr cmdb = GrManager::getSingleton().newCommandBuffer(cmdbInit);
  91. U32 offset = 0;
  92. fillBuffer(*cmdb, BufferView(m_indirectArgsBuffer.get(), offset, sizeof(U32)), 0);
  93. offset += sizeof(U32);
  94. fillBuffer(*cmdb, BufferView(m_indirectArgsBuffer.get(), offset, 2 * sizeof(U32)), 1);
  95. offset += sizeof(U32) * 2;
  96. fillBuffer(*cmdb, BufferView(m_indirectArgsBuffer.get(), offset, sizeof(U32)), 0);
  97. offset += sizeof(U32);
  98. fillBuffer(*cmdb, BufferView(m_indirectArgsBuffer.get(), offset, 2 * sizeof(U32)), 1);
  99. FencePtr fence;
  100. cmdb->endRecording();
  101. GrManager::getSingleton().submit(cmdb.get(), {}, &fence);
  102. fence->clientWait(16.0_sec);
  103. }
  104. return Error::kNone;
  105. }
  106. void Reflections::populateRenderGraph(RenderingContext& ctx)
  107. {
  108. RenderGraphBuilder& rgraph = ctx.m_renderGraphDescr;
  109. const Bool bRtReflections = GrManager::getSingleton().getDeviceCapabilities().m_rayTracingEnabled && g_rtReflectionsCVar;
  110. // Create or import render targets
  111. RenderTargetHandle mainRt;
  112. RenderTargetHandle readMomentsRt;
  113. RenderTargetHandle writeMomentsRt;
  114. if(m_texImportedOnce)
  115. {
  116. mainRt = rgraph.importRenderTarget(m_tex.get());
  117. readMomentsRt = rgraph.importRenderTarget(m_momentsTextures[getRenderer().getFrameCount() & 1].get());
  118. writeMomentsRt = rgraph.importRenderTarget(m_momentsTextures[(getRenderer().getFrameCount() + 1) & 1].get());
  119. }
  120. else
  121. {
  122. mainRt = rgraph.importRenderTarget(m_tex.get(), TextureUsageBit::kAllSrv);
  123. readMomentsRt = rgraph.importRenderTarget(m_momentsTextures[getRenderer().getFrameCount() & 1].get(), TextureUsageBit::kAllSrv);
  124. writeMomentsRt = rgraph.importRenderTarget(m_momentsTextures[(getRenderer().getFrameCount() + 1) & 1].get(), TextureUsageBit::kAllSrv);
  125. m_texImportedOnce = true;
  126. }
  127. const RenderTargetHandle transientRt1 = rgraph.newRenderTarget(m_transientRtDesc1);
  128. const RenderTargetHandle transientRt2 = rgraph.newRenderTarget(m_transientRtDesc2);
  129. const RenderTargetHandle hitPosAndDepthRt = rgraph.newRenderTarget(m_hitPosAndDepthRtDesc);
  130. const RenderTargetHandle hitPosRt = rgraph.newRenderTarget(m_hitPosRtDesc);
  131. const RenderTargetHandle classTileMapRt = rgraph.newRenderTarget(m_classTileMapRtDesc);
  132. const BufferHandle indirectArgsHandle = rgraph.importBuffer(BufferView(m_indirectArgsBuffer.get()), BufferUsageBit::kNone);
  133. ReflectionConstants consts;
  134. consts.m_ssrStepIncrement = g_ssrStepIncrementCVar;
  135. consts.m_ssrMaxIterations = g_ssrMaxIterationsCVar;
  136. consts.m_roughnessCutoffToGiEdges = Vec2(g_roughnessCutoffToGiEdge0, g_roughnessCutoffToGiEdge1);
  137. // Classification
  138. {
  139. // Create the pass
  140. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("ReflTileClassification");
  141. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(1), TextureUsageBit::kSrvCompute);
  142. rpass.newTextureDependency(getRenderer().getGBuffer().getDepthRt(), TextureUsageBit::kSrvCompute);
  143. rpass.newTextureDependency(classTileMapRt, TextureUsageBit::kUavCompute);
  144. rpass.newBufferDependency(indirectArgsHandle, BufferUsageBit::kUavCompute);
  145. rpass.setWork([this, classTileMapRt, consts](RenderPassWorkContext& rgraphCtx) {
  146. ANKI_TRACE_SCOPED_EVENT(ReflectionsClassification);
  147. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  148. cmdb.bindShaderProgram(m_tileClassificationGrProg.get());
  149. rgraphCtx.bindSrv(0, 0, getRenderer().getGBuffer().getColorRt(1));
  150. rgraphCtx.bindSrv(1, 0, getRenderer().getGBuffer().getDepthRt());
  151. rgraphCtx.bindUav(0, 0, classTileMapRt);
  152. cmdb.bindUav(1, 0, BufferView(m_indirectArgsBuffer.get()));
  153. cmdb.setFastConstants(&consts, sizeof(consts));
  154. dispatchPPCompute(cmdb, kTileSize / 2, kTileSize, getRenderer().getInternalResolution().x() / 2,
  155. getRenderer().getInternalResolution().y());
  156. });
  157. }
  158. // SSR
  159. BufferView pixelsFailedSsrBuff;
  160. {
  161. const U32 pixelCount = getRenderer().getInternalResolution().x() / 2 * getRenderer().getInternalResolution().y();
  162. pixelsFailedSsrBuff = GpuVisibleTransientMemoryPool::getSingleton().allocateStructuredBuffer<PixelFailedSsr>(pixelCount);
  163. // Create the pass
  164. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("SSR");
  165. rpass.newTextureDependency(getRenderer().getDepthDownscale().getRt(), TextureUsageBit::kSrvCompute);
  166. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(0), TextureUsageBit::kSrvCompute);
  167. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(1), TextureUsageBit::kSrvCompute);
  168. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(2), TextureUsageBit::kSrvCompute);
  169. rpass.newTextureDependency(getRenderer().getGBuffer().getDepthRt(), TextureUsageBit::kSrvCompute);
  170. rpass.newTextureDependency(getRenderer().getBloom().getPyramidRt(), TextureUsageBit::kSrvCompute);
  171. rpass.newBufferDependency(getRenderer().getClusterBinning().getDependency(), BufferUsageBit::kSrvCompute);
  172. rpass.newTextureDependency(getRenderer().getShadowMapping().getShadowmapRt(), TextureUsageBit::kSrvCompute);
  173. rpass.newTextureDependency(classTileMapRt, TextureUsageBit::kSrvCompute);
  174. rpass.newTextureDependency(transientRt1, TextureUsageBit::kUavCompute);
  175. rpass.newTextureDependency(hitPosAndDepthRt, TextureUsageBit::kUavCompute);
  176. rpass.newBufferDependency(indirectArgsHandle, BufferUsageBit::kUavCompute);
  177. rpass.setWork([this, transientRt1, hitPosAndDepthRt, &ctx, pixelsFailedSsrBuff, consts, classTileMapRt](RenderPassWorkContext& rgraphCtx) {
  178. ANKI_TRACE_SCOPED_EVENT(ReflectionsSsr);
  179. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  180. cmdb.bindShaderProgram(m_ssrGrProg.get());
  181. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearClamp.get());
  182. cmdb.bindSampler(1, 0, getRenderer().getSamplers().m_trilinearClampShadow.get());
  183. rgraphCtx.bindSrv(0, 0, getRenderer().getGBuffer().getColorRt(0));
  184. rgraphCtx.bindSrv(1, 0, getRenderer().getGBuffer().getColorRt(1));
  185. rgraphCtx.bindSrv(2, 0, getRenderer().getGBuffer().getColorRt(2));
  186. rgraphCtx.bindSrv(3, 0, getRenderer().getDepthDownscale().getRt());
  187. rgraphCtx.bindSrv(4, 0, getRenderer().getGBuffer().getDepthRt());
  188. rgraphCtx.bindSrv(5, 0, getRenderer().getBloom().getPyramidRt());
  189. cmdb.bindSrv(6, 0, getRenderer().getClusterBinning().getPackedObjectsBuffer(GpuSceneNonRenderableObjectType::kGlobalIlluminationProbe));
  190. cmdb.bindSrv(7, 0, getRenderer().getClusterBinning().getClustersBuffer());
  191. rgraphCtx.bindSrv(8, 0, getRenderer().getShadowMapping().getShadowmapRt());
  192. rgraphCtx.bindSrv(9, 0, classTileMapRt);
  193. rgraphCtx.bindUav(0, 0, transientRt1);
  194. rgraphCtx.bindUav(1, 0, hitPosAndDepthRt);
  195. cmdb.bindUav(2, 0, pixelsFailedSsrBuff);
  196. cmdb.bindUav(3, 0, BufferView(m_indirectArgsBuffer.get()));
  197. cmdb.bindConstantBuffer(0, 0, ctx.m_globalRenderingConstantsBuffer);
  198. cmdb.setFastConstants(&consts, sizeof(consts));
  199. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x() / 2, getRenderer().getInternalResolution().y());
  200. });
  201. }
  202. // SBT build
  203. BufferHandle sbtHandle;
  204. BufferView sbtBuffer;
  205. if(bRtReflections)
  206. {
  207. buildShaderBindingTablePass("RtReflections: Build SBT", m_libraryGrProg.get(), m_rayGenShaderGroupIdx, m_missShaderGroupIdx, m_sbtRecordSize,
  208. rgraph, sbtHandle, sbtBuffer);
  209. }
  210. // Ray gen
  211. if(bRtReflections)
  212. {
  213. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtReflections");
  214. rpass.newBufferDependency(sbtHandle, BufferUsageBit::kShaderBindingTable);
  215. rpass.newTextureDependency(transientRt1, TextureUsageBit::kUavTraceRays);
  216. rpass.newTextureDependency(hitPosAndDepthRt, TextureUsageBit::kUavTraceRays);
  217. rpass.newTextureDependency(getRenderer().getGBuffer().getDepthRt(), TextureUsageBit::kSrvTraceRays);
  218. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(1), TextureUsageBit::kSrvTraceRays);
  219. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(2), TextureUsageBit::kSrvTraceRays);
  220. if(getRenderer().getGeneratedSky().isEnabled())
  221. {
  222. rpass.newTextureDependency(getRenderer().getGeneratedSky().getEnvironmentMapRt(), TextureUsageBit::kSrvTraceRays);
  223. }
  224. rpass.newTextureDependency(getRenderer().getShadowMapping().getShadowmapRt(), TextureUsageBit::kSrvTraceRays);
  225. rpass.newAccelerationStructureDependency(getRenderer().getAccelerationStructureBuilder().getAccelerationStructureHandle(),
  226. AccelerationStructureUsageBit::kTraceRaysSrv);
  227. rpass.newBufferDependency(indirectArgsHandle, BufferUsageBit::kIndirectTraceRays);
  228. rpass.setWork([this, sbtBuffer, &ctx, transientRt1, hitPosAndDepthRt, pixelsFailedSsrBuff](RenderPassWorkContext& rgraphCtx) {
  229. ANKI_TRACE_SCOPED_EVENT(ReflectionsRayGen);
  230. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  231. cmdb.bindShaderProgram(m_libraryGrProg.get());
  232. // More globals
  233. cmdb.bindSampler(ANKI_MATERIAL_REGISTER_TILINEAR_REPEAT_SAMPLER, 0, getRenderer().getSamplers().m_trilinearRepeat.get());
  234. cmdb.bindSrv(ANKI_MATERIAL_REGISTER_GPU_SCENE, 0, GpuSceneBuffer::getSingleton().getBufferView());
  235. cmdb.bindSrv(ANKI_MATERIAL_REGISTER_MESH_LODS, 0, GpuSceneArrays::MeshLod::getSingleton().getBufferView());
  236. cmdb.bindSrv(ANKI_MATERIAL_REGISTER_TRANSFORMS, 0, GpuSceneArrays::Transform::getSingleton().getBufferView());
  237. #define ANKI_UNIFIED_GEOM_FORMAT(fmt, shaderType, reg) \
  238. cmdb.bindSrv( \
  239. reg, 0, \
  240. BufferView(&UnifiedGeometryBuffer::getSingleton().getBuffer(), 0, \
  241. getAlignedRoundDown(getFormatInfo(Format::k##fmt).m_texelSize, UnifiedGeometryBuffer::getSingleton().getBuffer().getSize())), \
  242. Format::k##fmt);
  243. #include <AnKi/Shaders/Include/UnifiedGeometryTypes.def.h>
  244. cmdb.bindConstantBuffer(0, 2, ctx.m_globalRenderingConstantsBuffer);
  245. U32 srv = 0;
  246. rgraphCtx.bindSrv(srv++, 2, getRenderer().getAccelerationStructureBuilder().getAccelerationStructureHandle());
  247. const LightComponent* dirLight = SceneGraph::getSingleton().getDirectionalLight();
  248. const SkyboxComponent* sky = SceneGraph::getSingleton().getSkybox();
  249. const Bool bSkySolidColor =
  250. (!sky || sky->getSkyboxType() == SkyboxType::kSolidColor || (!dirLight && sky->getSkyboxType() == SkyboxType::kGenerated));
  251. if(bSkySolidColor)
  252. {
  253. cmdb.bindSrv(srv++, 2, TextureView(getDummyGpuResources().m_texture2DSrv.get(), TextureSubresourceDesc::all()));
  254. }
  255. else if(sky->getSkyboxType() == SkyboxType::kImage2D)
  256. {
  257. cmdb.bindSrv(srv++, 2, TextureView(&sky->getImageResource().getTexture(), TextureSubresourceDesc::all()));
  258. }
  259. else
  260. {
  261. rgraphCtx.bindSrv(srv++, 2, getRenderer().getGeneratedSky().getEnvironmentMapRt());
  262. }
  263. rgraphCtx.bindSrv(srv++, 2, getRenderer().getShadowMapping().getShadowmapRt());
  264. const auto& arr = GpuSceneArrays::GlobalIlluminationProbe::getSingleton();
  265. cmdb.bindSrv(srv++, 2,
  266. (arr.getElementCount()) ? arr.getBufferView() : BufferView(getDummyGpuResources().m_buffer.get(), 0, arr.getElementSize()));
  267. cmdb.bindSrv(srv++, 2, pixelsFailedSsrBuff);
  268. for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount * 3; ++clipmap)
  269. {
  270. cmdb.bindSrv(srv++, 2, TextureView(getDummyGpuResources().m_texture3DSrv.get(), TextureSubresourceDesc::all()));
  271. }
  272. rgraphCtx.bindSrv(srv++, 2, getRenderer().getGBuffer().getDepthRt());
  273. rgraphCtx.bindSrv(srv++, 2, getRenderer().getGBuffer().getColorRt(1));
  274. rgraphCtx.bindSrv(srv++, 2, getRenderer().getGBuffer().getColorRt(2));
  275. rgraphCtx.bindUav(0, 2, transientRt1);
  276. rgraphCtx.bindUav(1, 2, hitPosAndDepthRt);
  277. cmdb.bindSampler(0, 2, getRenderer().getSamplers().m_trilinearClamp.get());
  278. cmdb.bindSampler(1, 2, getRenderer().getSamplers().m_trilinearClampShadow.get());
  279. cmdb.bindSampler(2, 2, getRenderer().getSamplers().m_trilinearRepeat.get());
  280. struct Consts
  281. {
  282. F32 m_maxRayT;
  283. U32 m_giProbeCount;
  284. F32 m_padding1;
  285. F32 m_padding2;
  286. } consts = {g_rtReflectionsMaxRayDistanceCVar, GpuSceneArrays::GlobalIlluminationProbe::getSingleton().getElementCount(), 0, 0};
  287. cmdb.setFastConstants(&consts, sizeof(consts));
  288. cmdb.traceRaysIndirect(sbtBuffer, m_sbtRecordSize, GpuSceneArrays::RenderableBoundingVolumeRt::getSingleton().getElementCount(), 1,
  289. BufferView(m_indirectArgsBuffer.get()).setRange(sizeof(DispatchIndirectArgs)));
  290. });
  291. }
  292. else
  293. {
  294. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("ReflectionProbeFallback");
  295. rpass.newTextureDependency(getRenderer().getGBuffer().getDepthRt(), TextureUsageBit::kSrvCompute);
  296. rpass.newBufferDependency(getRenderer().getClusterBinning().getDependency(), BufferUsageBit::kSrvCompute);
  297. rpass.newBufferDependency(indirectArgsHandle, BufferUsageBit::kIndirectCompute);
  298. rpass.newTextureDependency(transientRt1, TextureUsageBit::kUavCompute);
  299. rpass.newTextureDependency(hitPosAndDepthRt, TextureUsageBit::kUavCompute);
  300. if(getRenderer().getGeneratedSky().isEnabled())
  301. {
  302. rpass.newTextureDependency(getRenderer().getGeneratedSky().getEnvironmentMapRt(), TextureUsageBit::kSrvCompute);
  303. }
  304. if(getRenderer().getProbeReflections().getHasCurrentlyRefreshedReflectionRt())
  305. {
  306. rpass.newTextureDependency(getRenderer().getProbeReflections().getCurrentlyRefreshedReflectionRt(), TextureUsageBit::kSrvCompute);
  307. }
  308. rpass.setWork([this, pixelsFailedSsrBuff, &ctx, transientRt1, hitPosAndDepthRt](RenderPassWorkContext& rgraphCtx) {
  309. ANKI_TRACE_SCOPED_EVENT(ReflectionsProbeFallback);
  310. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  311. cmdb.bindShaderProgram(m_probeFallbackGrProg.get());
  312. rgraphCtx.bindSrv(0, 0, getRenderer().getGBuffer().getDepthRt());
  313. cmdb.bindSrv(1, 0, pixelsFailedSsrBuff);
  314. cmdb.bindSrv(2, 0, getRenderer().getClusterBinning().getPackedObjectsBuffer(GpuSceneNonRenderableObjectType::kReflectionProbe));
  315. cmdb.bindSrv(3, 0, getRenderer().getClusterBinning().getClustersBuffer());
  316. cmdb.bindSrv(4, 0, BufferView(m_indirectArgsBuffer.get()).setRange(sizeof(U32)));
  317. const LightComponent* dirLight = SceneGraph::getSingleton().getDirectionalLight();
  318. const SkyboxComponent* sky = SceneGraph::getSingleton().getSkybox();
  319. const Bool bSkySolidColor =
  320. (!sky || sky->getSkyboxType() == SkyboxType::kSolidColor || (!dirLight && sky->getSkyboxType() == SkyboxType::kGenerated));
  321. if(bSkySolidColor)
  322. {
  323. cmdb.bindSrv(5, 0, TextureView(getDummyGpuResources().m_texture2DSrv.get(), TextureSubresourceDesc::all()));
  324. }
  325. else if(sky->getSkyboxType() == SkyboxType::kImage2D)
  326. {
  327. cmdb.bindSrv(5, 0, TextureView(&sky->getImageResource().getTexture(), TextureSubresourceDesc::all()));
  328. }
  329. else
  330. {
  331. rgraphCtx.bindSrv(5, 0, getRenderer().getGeneratedSky().getEnvironmentMapRt());
  332. }
  333. cmdb.bindConstantBuffer(0, 0, ctx.m_globalRenderingConstantsBuffer);
  334. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearClamp.get());
  335. rgraphCtx.bindUav(0, 0, transientRt1);
  336. rgraphCtx.bindUav(1, 0, hitPosAndDepthRt);
  337. cmdb.dispatchComputeIndirect(BufferView(m_indirectArgsBuffer.get()).incrementOffset(sizeof(DispatchIndirectArgs)));
  338. });
  339. }
  340. // Spatial denoising
  341. {
  342. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("ReflectionsSpatialDenoise");
  343. rpass.newTextureDependency(transientRt1, TextureUsageBit::kSrvCompute);
  344. rpass.newTextureDependency(hitPosAndDepthRt, TextureUsageBit::kSrvCompute);
  345. rpass.newTextureDependency(getRenderer().getGBuffer().getDepthRt(), TextureUsageBit::kSrvCompute);
  346. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(1), TextureUsageBit::kSrvCompute);
  347. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(2), TextureUsageBit::kSrvCompute);
  348. rpass.newTextureDependency(classTileMapRt, TextureUsageBit::kSrvCompute);
  349. rpass.newTextureDependency(transientRt2, TextureUsageBit::kUavCompute);
  350. rpass.newTextureDependency(hitPosRt, TextureUsageBit::kUavCompute);
  351. rpass.setWork([this, &ctx, transientRt1, transientRt2, hitPosAndDepthRt, hitPosRt, consts, classTileMapRt](RenderPassWorkContext& rgraphCtx) {
  352. ANKI_TRACE_SCOPED_EVENT(ReflectionsSpatialDenoise);
  353. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  354. cmdb.bindShaderProgram(m_spatialDenoisingGrProg.get());
  355. rgraphCtx.bindSrv(0, 0, transientRt1);
  356. rgraphCtx.bindSrv(1, 0, hitPosAndDepthRt);
  357. rgraphCtx.bindSrv(2, 0, getRenderer().getGBuffer().getDepthRt());
  358. rgraphCtx.bindSrv(3, 0, getRenderer().getGBuffer().getColorRt(1));
  359. rgraphCtx.bindSrv(4, 0, getRenderer().getGBuffer().getColorRt(2));
  360. rgraphCtx.bindSrv(5, 0, classTileMapRt);
  361. rgraphCtx.bindUav(0, 0, transientRt2);
  362. rgraphCtx.bindUav(1, 0, hitPosRt);
  363. cmdb.bindConstantBuffer(0, 0, ctx.m_globalRenderingConstantsBuffer);
  364. cmdb.setFastConstants(&consts, sizeof(consts));
  365. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y());
  366. });
  367. }
  368. // Temporal denoising
  369. {
  370. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("ReflectionsTemporalDenoise");
  371. rpass.newTextureDependency(transientRt2, TextureUsageBit::kSrvCompute);
  372. rpass.newTextureDependency(mainRt, TextureUsageBit::kSrvCompute);
  373. rpass.newTextureDependency(readMomentsRt, TextureUsageBit::kSrvCompute);
  374. rpass.newTextureDependency(getRenderer().getMotionVectors().getMotionVectorsRt(), TextureUsageBit::kSrvCompute);
  375. rpass.newTextureDependency(hitPosRt, TextureUsageBit::kSrvCompute);
  376. rpass.newTextureDependency(classTileMapRt, TextureUsageBit::kSrvCompute);
  377. rpass.newTextureDependency(transientRt1, TextureUsageBit::kUavCompute);
  378. rpass.newTextureDependency(writeMomentsRt, TextureUsageBit::kUavCompute);
  379. rpass.setWork([this, &ctx, transientRt1, transientRt2, mainRt, readMomentsRt, writeMomentsRt, hitPosRt,
  380. classTileMapRt](RenderPassWorkContext& rgraphCtx) {
  381. ANKI_TRACE_SCOPED_EVENT(ReflectionsTemporalDenoise);
  382. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  383. cmdb.bindShaderProgram(m_temporalDenoisingGrProg.get());
  384. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearClamp.get());
  385. rgraphCtx.bindSrv(0, 0, transientRt2);
  386. rgraphCtx.bindSrv(1, 0, mainRt);
  387. rgraphCtx.bindSrv(2, 0, readMomentsRt);
  388. rgraphCtx.bindSrv(3, 0, getRenderer().getMotionVectors().getMotionVectorsRt());
  389. rgraphCtx.bindSrv(4, 0, hitPosRt);
  390. rgraphCtx.bindSrv(5, 0, classTileMapRt);
  391. rgraphCtx.bindUav(0, 0, transientRt1);
  392. rgraphCtx.bindUav(1, 0, writeMomentsRt);
  393. cmdb.bindConstantBuffer(0, 0, ctx.m_globalRenderingConstantsBuffer);
  394. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y());
  395. });
  396. }
  397. // Hotizontal bilateral filter
  398. {
  399. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("ReflectionsHorizBilateral");
  400. rpass.newTextureDependency(transientRt1, TextureUsageBit::kSrvCompute);
  401. rpass.newTextureDependency(writeMomentsRt, TextureUsageBit::kSrvCompute);
  402. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(1), TextureUsageBit::kSrvCompute);
  403. rpass.newTextureDependency(classTileMapRt, TextureUsageBit::kSrvCompute);
  404. rpass.newTextureDependency(transientRt2, TextureUsageBit::kUavCompute);
  405. rpass.setWork([this, transientRt1, transientRt2, writeMomentsRt, consts, classTileMapRt](RenderPassWorkContext& rgraphCtx) {
  406. ANKI_TRACE_SCOPED_EVENT(ReflectionsHorizontalDenoise);
  407. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  408. cmdb.bindShaderProgram(m_horizontalBilateralDenoisingGrProg.get());
  409. rgraphCtx.bindSrv(0, 0, transientRt1);
  410. rgraphCtx.bindSrv(1, 0, writeMomentsRt);
  411. rgraphCtx.bindSrv(2, 0, getRenderer().getGBuffer().getColorRt(1));
  412. rgraphCtx.bindSrv(3, 0, classTileMapRt);
  413. rgraphCtx.bindUav(0, 0, transientRt2);
  414. cmdb.setFastConstants(&consts, sizeof(consts));
  415. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y());
  416. });
  417. }
  418. // Vertical bilateral filter
  419. {
  420. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("ReflectionsVertBilateral");
  421. rpass.newTextureDependency(transientRt2, TextureUsageBit::kSrvCompute);
  422. rpass.newTextureDependency(mainRt, TextureUsageBit::kUavCompute);
  423. rpass.newTextureDependency(classTileMapRt, TextureUsageBit::kSrvCompute);
  424. rpass.setWork([this, transientRt2, mainRt, classTileMapRt](RenderPassWorkContext& rgraphCtx) {
  425. ANKI_TRACE_SCOPED_EVENT(ReflectionsVerticalDenoise);
  426. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  427. cmdb.bindShaderProgram(m_verticalBilateralDenoisingGrProg.get());
  428. rgraphCtx.bindSrv(0, 0, transientRt2);
  429. rgraphCtx.bindSrv(1, 0, classTileMapRt);
  430. rgraphCtx.bindUav(0, 0, mainRt);
  431. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y());
  432. });
  433. }
  434. m_runCtx.m_rt = mainRt;
  435. }
  436. } // end namespace anki