Reflections.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  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_cvarRenderReflectionsRt;
  28. const Bool bSsrSamplesGBuffer = bRtReflections;
  29. std::initializer_list<SubMutation> mutation = {{"SSR_SAMPLE_GBUFFER", bSsrSamplesGBuffer},
  30. {"INDIRECT_DIFFUSE_CLIPMAPS", isIndirectDiffuseClipmapsEnabled()}};
  31. constexpr CString kProgFname = "ShaderBinaries/Reflections.ankiprogbin";
  32. // Ray gen and miss
  33. if(bRtReflections)
  34. {
  35. ANKI_CHECK(ResourceManager::getSingleton().loadResource(kProgFname, m_mainProg));
  36. ShaderProgramResourceVariantInitInfo variantInitInfo(m_mainProg);
  37. variantInitInfo.requestTechniqueAndTypes(ShaderTypeBit::kRayGen, "RtMaterialFetch");
  38. variantInitInfo.addMutation("SSR_SAMPLE_GBUFFER", bSsrSamplesGBuffer);
  39. variantInitInfo.addMutation("INDIRECT_DIFFUSE_CLIPMAPS", isIndirectDiffuseClipmapsEnabled());
  40. const ShaderProgramResourceVariant* variant;
  41. m_mainProg->getOrCreateVariant(variantInitInfo, variant);
  42. m_libraryGrProg.reset(&variant->getProgram());
  43. m_rayGenShaderGroupIdx = variant->getShaderGroupHandleIndex();
  44. ANKI_CHECK(ResourceManager::getSingleton().loadResource("ShaderBinaries/RtMaterialFetchMiss.ankiprogbin", m_missProg));
  45. ShaderProgramResourceVariantInitInfo variantInitInfo2(m_missProg);
  46. variantInitInfo2.requestTechniqueAndTypes(ShaderTypeBit::kMiss, "RtMaterialFetch");
  47. m_missProg->getOrCreateVariant(variantInitInfo2, variant);
  48. m_missShaderGroupIdx = variant->getShaderGroupHandleIndex();
  49. m_sbtRecordSize = getAlignedRoundUp(GrManager::getSingleton().getDeviceCapabilities().m_sbtRecordAlignment,
  50. GrManager::getSingleton().getDeviceCapabilities().m_shaderGroupHandleSize + U32(sizeof(UVec4)));
  51. ANKI_CHECK(loadShaderProgram(kProgFname, mutation, m_mainProg, m_rtMaterialFetchInlineRtGrProg, "RtMaterialFetchInlineRt"));
  52. }
  53. ANKI_CHECK(loadShaderProgram(kProgFname, mutation, m_mainProg, m_spatialDenoisingGrProg, "SpatialDenoise"));
  54. ANKI_CHECK(loadShaderProgram(kProgFname, mutation, m_mainProg, m_temporalDenoisingGrProg, "TemporalDenoise"));
  55. ANKI_CHECK(loadShaderProgram(kProgFname, mutation, m_mainProg, m_verticalBilateralDenoisingGrProg, "BilateralDenoiseVertical"));
  56. ANKI_CHECK(loadShaderProgram(kProgFname, mutation, m_mainProg, m_horizontalBilateralDenoisingGrProg, "BilateralDenoiseHorizontal"));
  57. ANKI_CHECK(loadShaderProgram(kProgFname, mutation, m_mainProg, m_ssrGrProg, "Ssr"));
  58. ANKI_CHECK(loadShaderProgram(kProgFname, mutation, m_mainProg, m_probeFallbackGrProg, "ReflectionProbeFallback"));
  59. ANKI_CHECK(loadShaderProgram(kProgFname, 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, getRenderer().getInternalResolution().y,
  70. 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_cvarRenderReflectionsRt;
  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_cvarRenderReflectionsSsrStepIncrement;
  138. consts.m_ssrMaxIterations = g_cvarRenderReflectionsSsrMaxIterations;
  139. consts.m_roughnessCutoffToGiEdges = Vec2(g_cvarRenderReflectionsRoughnessCutoffToGiEdge0, g_cvarRenderReflectionsRoughnessCutoffToGiEdge1);
  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, getRenderer().getInternalResolution().y);
  158. });
  159. }
  160. // SSR
  161. BufferView pixelsFailedSsrBuff;
  162. {
  163. const U32 pixelCount = getRenderer().getInternalResolution().x / 2 * getRenderer().getInternalResolution().y;
  164. pixelsFailedSsrBuff = GpuVisibleTransientMemoryPool::getSingleton().allocateStructuredBuffer<PixelFailedSsr>(pixelCount);
  165. // Create the pass
  166. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("SSR");
  167. rpass.newTextureDependency(getDepthDownscale().getRt(), TextureUsageBit::kSrvCompute);
  168. rpass.newTextureDependency(getGBuffer().getColorRt(0), TextureUsageBit::kSrvCompute);
  169. rpass.newTextureDependency(getGBuffer().getColorRt(1), TextureUsageBit::kSrvCompute);
  170. rpass.newTextureDependency(getGBuffer().getColorRt(2), TextureUsageBit::kSrvCompute);
  171. rpass.newTextureDependency(getGBuffer().getDepthRt(), TextureUsageBit::kSrvCompute);
  172. rpass.newTextureDependency(getRenderer().getBloom().getPyramidRt(), TextureUsageBit::kSrvCompute);
  173. rpass.newBufferDependency(getClusterBinning().getDependency(), BufferUsageBit::kSrvCompute);
  174. rpass.newTextureDependency(getShadowMapping().getShadowmapRt(), TextureUsageBit::kSrvCompute);
  175. rpass.newTextureDependency(classTileMapRt, TextureUsageBit::kSrvCompute);
  176. rpass.newTextureDependency(transientRt1, TextureUsageBit::kUavCompute);
  177. rpass.newTextureDependency(hitPosAndDepthRt, TextureUsageBit::kUavCompute);
  178. rpass.newBufferDependency(indirectArgsHandle, BufferUsageBit::kUavCompute);
  179. rpass.setWork([this, transientRt1, hitPosAndDepthRt, &ctx, pixelsFailedSsrBuff, consts, classTileMapRt](RenderPassWorkContext& rgraphCtx) {
  180. ANKI_TRACE_SCOPED_EVENT(ReflectionsSsr);
  181. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  182. cmdb.bindShaderProgram(m_ssrGrProg.get());
  183. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearClamp.get());
  184. cmdb.bindSampler(1, 0, getRenderer().getSamplers().m_trilinearClampShadow.get());
  185. cmdb.bindSampler(2, 0, getRenderer().getSamplers().m_trilinearRepeat.get());
  186. rgraphCtx.bindSrv(0, 0, getGBuffer().getColorRt(0));
  187. rgraphCtx.bindSrv(1, 0, getGBuffer().getColorRt(1));
  188. rgraphCtx.bindSrv(2, 0, getGBuffer().getColorRt(2));
  189. rgraphCtx.bindSrv(3, 0, getDepthDownscale().getRt());
  190. rgraphCtx.bindSrv(4, 0, getGBuffer().getDepthRt());
  191. rgraphCtx.bindSrv(5, 0, getRenderer().getBloom().getPyramidRt());
  192. cmdb.bindSrv(6, 0, getClusterBinning().getPackedObjectsBuffer(GpuSceneNonRenderableObjectType::kGlobalIlluminationProbe));
  193. cmdb.bindSrv(7, 0, getClusterBinning().getClustersBuffer());
  194. rgraphCtx.bindSrv(8, 0, getShadowMapping().getShadowmapRt());
  195. rgraphCtx.bindSrv(9, 0, classTileMapRt);
  196. cmdb.bindSrv(10, 0, getClusterBinning().getPackedObjectsBuffer(GpuSceneNonRenderableObjectType::kLight));
  197. cmdb.bindSrv(11, 0, getClusterBinning().getPackedObjectsBuffer(GpuSceneNonRenderableObjectType::kLight));
  198. rgraphCtx.bindUav(0, 0, transientRt1);
  199. rgraphCtx.bindUav(1, 0, hitPosAndDepthRt);
  200. cmdb.bindUav(2, 0, pixelsFailedSsrBuff);
  201. cmdb.bindUav(3, 0, BufferView(m_indirectArgsBuffer.get()));
  202. cmdb.bindConstantBuffer(0, 0, ctx.m_globalRenderingConstantsBuffer);
  203. cmdb.setFastConstants(&consts, sizeof(consts));
  204. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x / 2, getRenderer().getInternalResolution().y);
  205. });
  206. }
  207. // SBT build
  208. BufferHandle sbtHandle;
  209. BufferView sbtBuffer;
  210. if(bRtReflections && !g_cvarRenderReflectionsInlineRt)
  211. {
  212. buildShaderBindingTablePass("RtReflections: Build SBT", m_libraryGrProg.get(), m_rayGenShaderGroupIdx, m_missShaderGroupIdx, m_sbtRecordSize,
  213. rgraph, sbtHandle, sbtBuffer);
  214. }
  215. // Ray gen
  216. if(bRtReflections)
  217. {
  218. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtReflections");
  219. const TextureUsageBit uavTexUsage = (g_cvarRenderReflectionsInlineRt) ? TextureUsageBit::kUavCompute : TextureUsageBit::kUavDispatchRays;
  220. const BufferUsageBit indirectBuffUsage =
  221. (g_cvarRenderReflectionsInlineRt) ? BufferUsageBit::kIndirectCompute : BufferUsageBit::kIndirectDispatchRays;
  222. const TextureUsageBit srvTexUsage = (g_cvarRenderReflectionsInlineRt) ? TextureUsageBit::kSrvCompute : TextureUsageBit::kSrvDispatchRays;
  223. if(!g_cvarRenderReflectionsInlineRt)
  224. {
  225. rpass.newBufferDependency(sbtHandle, BufferUsageBit::kShaderBindingTable);
  226. }
  227. rpass.newTextureDependency(transientRt1, uavTexUsage);
  228. rpass.newTextureDependency(hitPosAndDepthRt, uavTexUsage);
  229. rpass.newBufferDependency(indirectArgsHandle, indirectBuffUsage);
  230. setRgenSpace2Dependencies(rpass, g_cvarRenderReflectionsInlineRt);
  231. if(isIndirectDiffuseClipmapsEnabled())
  232. {
  233. getIndirectDiffuseClipmaps().setDependencies(rpass, srvTexUsage);
  234. }
  235. rpass.setWork([this, sbtBuffer, &ctx, transientRt1, hitPosAndDepthRt, pixelsFailedSsrBuff](RenderPassWorkContext& rgraphCtx) {
  236. ANKI_TRACE_SCOPED_EVENT(ReflectionsRayGen);
  237. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  238. cmdb.bindShaderProgram((g_cvarRenderReflectionsInlineRt) ? m_rtMaterialFetchInlineRtGrProg.get() : m_libraryGrProg.get());
  239. // More globals
  240. cmdb.bindSampler(ANKI_MATERIAL_REGISTER_TILINEAR_REPEAT_SAMPLER, 0, getRenderer().getSamplers().m_trilinearRepeat.get());
  241. cmdb.bindSrv(ANKI_MATERIAL_REGISTER_GPU_SCENE, 0, GpuSceneBuffer::getSingleton().getBufferView());
  242. cmdb.bindSrv(ANKI_MATERIAL_REGISTER_MESH_LODS, 0, GpuSceneArrays::MeshLod::getSingleton().getBufferView());
  243. cmdb.bindSrv(ANKI_MATERIAL_REGISTER_TRANSFORMS, 0, GpuSceneArrays::Transform::getSingleton().getBufferView());
  244. cmdb.bindSrv(ANKI_MATERIAL_REGISTER_UNIFIED_GEOMETRY, 0, UnifiedGeometryBuffer::getSingleton().getBufferView());
  245. #define ANKI_UNIFIED_GEOM_FORMAT(fmt, shaderType, reg) \
  246. cmdb.bindSrv( \
  247. reg, 0, \
  248. BufferView(&UnifiedGeometryBuffer::getSingleton().getBuffer(), 0, \
  249. getAlignedRoundDown(getFormatInfo(Format::k##fmt).m_texelSize, UnifiedGeometryBuffer::getSingleton().getBuffer().getSize())), \
  250. Format::k##fmt);
  251. #include <AnKi/Shaders/Include/UnifiedGeometryTypes.def.h>
  252. bindRgenSpace2Resources(ctx, rgraphCtx);
  253. cmdb.bindSrv(7, 2, pixelsFailedSsrBuff);
  254. rgraphCtx.bindUav(0, 2, transientRt1);
  255. rgraphCtx.bindUav(1, 2, hitPosAndDepthRt);
  256. struct Consts
  257. {
  258. F32 m_maxRayT;
  259. U32 m_giProbeCount;
  260. F32 m_padding1;
  261. F32 m_padding2;
  262. Vec4 m_padding[2];
  263. } consts = {g_cvarRenderReflectionsRtMaxRayDistance, GpuSceneArrays::GlobalIlluminationProbe::getSingleton().getElementCount(), 0, 0, {}};
  264. cmdb.setFastConstants(&consts, sizeof(consts));
  265. if(g_cvarRenderReflectionsInlineRt)
  266. {
  267. cmdb.dispatchComputeIndirect(BufferView(m_indirectArgsBuffer.get()).incrementOffset(sizeof(DispatchIndirectArgs)));
  268. }
  269. else
  270. {
  271. cmdb.dispatchRaysIndirect(sbtBuffer, m_sbtRecordSize, GpuSceneArrays::RenderableBoundingVolumeRt::getSingleton().getElementCount(), 1,
  272. BufferView(m_indirectArgsBuffer.get()).setRange(sizeof(DispatchIndirectArgs)));
  273. }
  274. });
  275. }
  276. else
  277. {
  278. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("ReflectionProbeFallback");
  279. rpass.newTextureDependency(getGBuffer().getDepthRt(), TextureUsageBit::kSrvCompute);
  280. rpass.newBufferDependency(getClusterBinning().getDependency(), BufferUsageBit::kSrvCompute);
  281. rpass.newBufferDependency(indirectArgsHandle, BufferUsageBit::kIndirectCompute);
  282. rpass.newTextureDependency(transientRt1, TextureUsageBit::kUavCompute);
  283. rpass.newTextureDependency(hitPosAndDepthRt, TextureUsageBit::kUavCompute);
  284. if(getRenderer().getGeneratedSky().isEnabled())
  285. {
  286. rpass.newTextureDependency(getRenderer().getGeneratedSky().getEnvironmentMapRt(), TextureUsageBit::kSrvCompute);
  287. }
  288. if(getRenderer().getProbeReflections().getHasCurrentlyRefreshedReflectionRt())
  289. {
  290. rpass.newTextureDependency(getRenderer().getProbeReflections().getCurrentlyRefreshedReflectionRt(), TextureUsageBit::kSrvCompute);
  291. }
  292. rpass.setWork([this, pixelsFailedSsrBuff, &ctx, transientRt1, hitPosAndDepthRt](RenderPassWorkContext& rgraphCtx) {
  293. ANKI_TRACE_SCOPED_EVENT(ReflectionsProbeFallback);
  294. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  295. cmdb.bindShaderProgram(m_probeFallbackGrProg.get());
  296. rgraphCtx.bindSrv(0, 0, getGBuffer().getDepthRt());
  297. cmdb.bindSrv(1, 0, pixelsFailedSsrBuff);
  298. cmdb.bindSrv(2, 0, getClusterBinning().getPackedObjectsBuffer(GpuSceneNonRenderableObjectType::kReflectionProbe));
  299. cmdb.bindSrv(3, 0, getClusterBinning().getClustersBuffer());
  300. cmdb.bindSrv(4, 0, BufferView(m_indirectArgsBuffer.get()).setRange(sizeof(U32)));
  301. const LightComponent* dirLight = SceneGraph::getSingleton().getDirectionalLight();
  302. const SkyboxComponent* sky = SceneGraph::getSingleton().getSkybox();
  303. const Bool bSkySolidColor =
  304. (!sky || sky->getSkyboxType() == SkyboxType::kSolidColor || (!dirLight && sky->getSkyboxType() == SkyboxType::kGenerated));
  305. if(bSkySolidColor)
  306. {
  307. cmdb.bindSrv(5, 0, TextureView(getDummyGpuResources().m_texture2DSrv.get(), TextureSubresourceDesc::all()));
  308. }
  309. else if(sky->getSkyboxType() == SkyboxType::kImage2D)
  310. {
  311. cmdb.bindSrv(5, 0, TextureView(&sky->getImageResource().getTexture(), TextureSubresourceDesc::all()));
  312. }
  313. else
  314. {
  315. rgraphCtx.bindSrv(5, 0, getRenderer().getGeneratedSky().getEnvironmentMapRt());
  316. }
  317. cmdb.bindConstantBuffer(0, 0, ctx.m_globalRenderingConstantsBuffer);
  318. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearClamp.get());
  319. rgraphCtx.bindUav(0, 0, transientRt1);
  320. rgraphCtx.bindUav(1, 0, hitPosAndDepthRt);
  321. cmdb.dispatchComputeIndirect(BufferView(m_indirectArgsBuffer.get()).incrementOffset(sizeof(DispatchIndirectArgs)));
  322. });
  323. }
  324. // Spatial denoising
  325. {
  326. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("ReflectionsSpatialDenoise");
  327. rpass.newTextureDependency(transientRt1, TextureUsageBit::kSrvCompute);
  328. rpass.newTextureDependency(hitPosAndDepthRt, TextureUsageBit::kSrvCompute);
  329. rpass.newTextureDependency(getGBuffer().getDepthRt(), TextureUsageBit::kSrvCompute);
  330. rpass.newTextureDependency(getGBuffer().getColorRt(1), TextureUsageBit::kSrvCompute);
  331. rpass.newTextureDependency(getGBuffer().getColorRt(2), TextureUsageBit::kSrvCompute);
  332. rpass.newTextureDependency(classTileMapRt, TextureUsageBit::kSrvCompute);
  333. rpass.newTextureDependency(transientRt2, TextureUsageBit::kUavCompute);
  334. rpass.newTextureDependency(hitPosRt, TextureUsageBit::kUavCompute);
  335. rpass.setWork([this, &ctx, transientRt1, transientRt2, hitPosAndDepthRt, hitPosRt, consts, classTileMapRt](RenderPassWorkContext& rgraphCtx) {
  336. ANKI_TRACE_SCOPED_EVENT(ReflectionsSpatialDenoise);
  337. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  338. cmdb.bindShaderProgram(m_spatialDenoisingGrProg.get());
  339. rgraphCtx.bindSrv(0, 0, transientRt1);
  340. rgraphCtx.bindSrv(1, 0, hitPosAndDepthRt);
  341. rgraphCtx.bindSrv(2, 0, getGBuffer().getDepthRt());
  342. rgraphCtx.bindSrv(3, 0, getGBuffer().getColorRt(1));
  343. rgraphCtx.bindSrv(4, 0, getGBuffer().getColorRt(2));
  344. rgraphCtx.bindSrv(5, 0, classTileMapRt);
  345. rgraphCtx.bindUav(0, 0, transientRt2);
  346. rgraphCtx.bindUav(1, 0, hitPosRt);
  347. cmdb.bindConstantBuffer(0, 0, ctx.m_globalRenderingConstantsBuffer);
  348. cmdb.setFastConstants(&consts, sizeof(consts));
  349. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x, getRenderer().getInternalResolution().y);
  350. });
  351. }
  352. // Temporal denoising
  353. {
  354. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("ReflectionsTemporalDenoise");
  355. rpass.newTextureDependency(transientRt2, TextureUsageBit::kSrvCompute);
  356. rpass.newTextureDependency(mainRt, TextureUsageBit::kSrvCompute);
  357. rpass.newTextureDependency(readMomentsRt, TextureUsageBit::kSrvCompute);
  358. rpass.newTextureDependency(getRenderer().getMotionVectors().getMotionVectorsRt(), TextureUsageBit::kSrvCompute);
  359. rpass.newTextureDependency(hitPosRt, TextureUsageBit::kSrvCompute);
  360. rpass.newTextureDependency(classTileMapRt, TextureUsageBit::kSrvCompute);
  361. rpass.newTextureDependency(transientRt1, TextureUsageBit::kUavCompute);
  362. rpass.newTextureDependency(writeMomentsRt, TextureUsageBit::kUavCompute);
  363. rpass.setWork([this, &ctx, transientRt1, transientRt2, mainRt, readMomentsRt, writeMomentsRt, hitPosRt,
  364. classTileMapRt](RenderPassWorkContext& rgraphCtx) {
  365. ANKI_TRACE_SCOPED_EVENT(ReflectionsTemporalDenoise);
  366. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  367. cmdb.bindShaderProgram(m_temporalDenoisingGrProg.get());
  368. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearClamp.get());
  369. rgraphCtx.bindSrv(0, 0, transientRt2);
  370. rgraphCtx.bindSrv(1, 0, mainRt);
  371. rgraphCtx.bindSrv(2, 0, readMomentsRt);
  372. rgraphCtx.bindSrv(3, 0, getRenderer().getMotionVectors().getMotionVectorsRt());
  373. rgraphCtx.bindSrv(4, 0, hitPosRt);
  374. rgraphCtx.bindSrv(5, 0, classTileMapRt);
  375. rgraphCtx.bindUav(0, 0, transientRt1);
  376. rgraphCtx.bindUav(1, 0, writeMomentsRt);
  377. cmdb.bindConstantBuffer(0, 0, ctx.m_globalRenderingConstantsBuffer);
  378. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x, getRenderer().getInternalResolution().y);
  379. });
  380. }
  381. // Hotizontal bilateral filter
  382. {
  383. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("ReflectionsHorizBilateral");
  384. rpass.newTextureDependency(transientRt1, TextureUsageBit::kSrvCompute);
  385. rpass.newTextureDependency(writeMomentsRt, TextureUsageBit::kSrvCompute);
  386. rpass.newTextureDependency(getGBuffer().getColorRt(1), TextureUsageBit::kSrvCompute);
  387. rpass.newTextureDependency(classTileMapRt, TextureUsageBit::kSrvCompute);
  388. rpass.newTextureDependency(transientRt2, TextureUsageBit::kUavCompute);
  389. rpass.setWork([this, transientRt1, transientRt2, writeMomentsRt, consts, classTileMapRt](RenderPassWorkContext& rgraphCtx) {
  390. ANKI_TRACE_SCOPED_EVENT(ReflectionsHorizontalDenoise);
  391. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  392. cmdb.bindShaderProgram(m_horizontalBilateralDenoisingGrProg.get());
  393. rgraphCtx.bindSrv(0, 0, transientRt1);
  394. rgraphCtx.bindSrv(1, 0, writeMomentsRt);
  395. rgraphCtx.bindSrv(2, 0, getGBuffer().getColorRt(1));
  396. rgraphCtx.bindSrv(3, 0, classTileMapRt);
  397. rgraphCtx.bindUav(0, 0, transientRt2);
  398. cmdb.setFastConstants(&consts, sizeof(consts));
  399. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x, getRenderer().getInternalResolution().y);
  400. });
  401. }
  402. // Vertical bilateral filter
  403. {
  404. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("ReflectionsVertBilateral");
  405. rpass.newTextureDependency(transientRt2, TextureUsageBit::kSrvCompute);
  406. rpass.newTextureDependency(mainRt, TextureUsageBit::kUavCompute);
  407. rpass.newTextureDependency(classTileMapRt, TextureUsageBit::kSrvCompute);
  408. rpass.setWork([this, transientRt2, mainRt, classTileMapRt](RenderPassWorkContext& rgraphCtx) {
  409. ANKI_TRACE_SCOPED_EVENT(ReflectionsVerticalDenoise);
  410. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  411. cmdb.bindShaderProgram(m_verticalBilateralDenoisingGrProg.get());
  412. rgraphCtx.bindSrv(0, 0, transientRt2);
  413. rgraphCtx.bindSrv(1, 0, classTileMapRt);
  414. rgraphCtx.bindUav(0, 0, mainRt);
  415. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x, getRenderer().getInternalResolution().y);
  416. });
  417. }
  418. m_runCtx.m_rt = mainRt;
  419. }
  420. } // end namespace anki