Reflections.cpp 24 KB

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