Reflections.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  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. const Bool bRtReflections = GrManager::getSingleton().getDeviceCapabilities().m_rayTracingEnabled && g_rtReflectionsCVar;
  26. const Bool bSsrSamplesGBuffer = bRtReflections;
  27. std::initializer_list<SubMutation> mutation = {{"SSR_SAMPLE_GBUFFER", bSsrSamplesGBuffer}};
  28. if(bRtReflections)
  29. {
  30. ANKI_CHECK(loadShaderProgram("ShaderBinaries/RtSbtBuild.ankiprogbin", {{"TECHNIQUE", 1}}, m_sbtProg, m_sbtBuildGrProg, "SbtBuild"));
  31. }
  32. // Ray gen and miss
  33. if(bRtReflections)
  34. {
  35. ANKI_CHECK(ResourceManager::getSingleton().loadResource("ShaderBinaries/Reflections.ankiprogbin", m_mainProg));
  36. ShaderProgramResourceVariantInitInfo variantInitInfo(m_mainProg);
  37. variantInitInfo.requestTechniqueAndTypes(ShaderTypeBit::kRayGen, "RtMaterialFetch");
  38. variantInitInfo.addMutation("SSR_SAMPLE_GBUFFER", bSsrSamplesGBuffer);
  39. const ShaderProgramResourceVariant* variant;
  40. m_mainProg->getOrCreateVariant(variantInitInfo, variant);
  41. m_libraryGrProg.reset(&variant->getProgram());
  42. m_rayGenShaderGroupIdx = variant->getShaderGroupHandleIndex();
  43. ShaderProgramResourceVariantInitInfo variantInitInfo2(m_mainProg);
  44. variantInitInfo2.requestTechniqueAndTypes(ShaderTypeBit::kMiss, "RtMaterialFetch");
  45. variantInitInfo2.addMutation("SSR_SAMPLE_GBUFFER", bSsrSamplesGBuffer);
  46. m_mainProg->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(getRenderer().getGBuffer().getColorRt(1), TextureUsageBit::kSrvCompute);
  145. rpass.newTextureDependency(getRenderer().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, getRenderer().getGBuffer().getColorRt(1));
  153. rgraphCtx.bindSrv(1, 0, getRenderer().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(getRenderer().getDepthDownscale().getRt(), TextureUsageBit::kSrvCompute);
  169. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(0), TextureUsageBit::kSrvCompute);
  170. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(1), TextureUsageBit::kSrvCompute);
  171. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(2), TextureUsageBit::kSrvCompute);
  172. rpass.newTextureDependency(getRenderer().getGBuffer().getDepthRt(), TextureUsageBit::kSrvCompute);
  173. rpass.newTextureDependency(getRenderer().getBloom().getPyramidRt(), TextureUsageBit::kSrvCompute);
  174. rpass.newBufferDependency(getRenderer().getClusterBinning().getDependency(), BufferUsageBit::kSrvCompute);
  175. rpass.newTextureDependency(getRenderer().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. rgraphCtx.bindSrv(0, 0, getRenderer().getGBuffer().getColorRt(0));
  187. rgraphCtx.bindSrv(1, 0, getRenderer().getGBuffer().getColorRt(1));
  188. rgraphCtx.bindSrv(2, 0, getRenderer().getGBuffer().getColorRt(2));
  189. rgraphCtx.bindSrv(3, 0, getRenderer().getDepthDownscale().getRt());
  190. rgraphCtx.bindSrv(4, 0, getRenderer().getGBuffer().getDepthRt());
  191. rgraphCtx.bindSrv(5, 0, getRenderer().getBloom().getPyramidRt());
  192. cmdb.bindSrv(6, 0, getRenderer().getClusterBinning().getPackedObjectsBuffer(GpuSceneNonRenderableObjectType::kGlobalIlluminationProbe));
  193. cmdb.bindSrv(7, 0, getRenderer().getClusterBinning().getClustersBuffer());
  194. rgraphCtx.bindSrv(8, 0, getRenderer().getShadowMapping().getShadowmapRt());
  195. rgraphCtx.bindSrv(9, 0, classTileMapRt);
  196. rgraphCtx.bindUav(0, 0, transientRt1);
  197. rgraphCtx.bindUav(1, 0, hitPosAndDepthRt);
  198. cmdb.bindUav(2, 0, pixelsFailedSsrBuff);
  199. cmdb.bindUav(3, 0, BufferView(m_indirectArgsBuffer.get()));
  200. cmdb.bindConstantBuffer(0, 0, ctx.m_globalRenderingConstantsBuffer);
  201. cmdb.setFastConstants(&consts, sizeof(consts));
  202. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x() / 2, getRenderer().getInternalResolution().y());
  203. });
  204. }
  205. // SBT build
  206. BufferHandle sbtHandle;
  207. BufferView sbtBuffer;
  208. if(bRtReflections)
  209. {
  210. BufferHandle visibilityDep;
  211. BufferView visibleRenderableIndicesBuff, buildSbtIndirectArgsBuff;
  212. getRenderer().getAccelerationStructureBuilder().getVisibilityInfo(visibilityDep, visibleRenderableIndicesBuff, buildSbtIndirectArgsBuff);
  213. // Allocate SBT
  214. U32 sbtAlignment = (GrManager::getSingleton().getDeviceCapabilities().m_structuredBufferNaturalAlignment)
  215. ? sizeof(U32)
  216. : GrManager::getSingleton().getDeviceCapabilities().m_structuredBufferBindOffsetAlignment;
  217. sbtAlignment = computeCompoundAlignment(sbtAlignment, GrManager::getSingleton().getDeviceCapabilities().m_sbtRecordAlignment);
  218. U8* sbtMem;
  219. sbtBuffer = RebarTransientMemoryPool::getSingleton().allocate(
  220. (GpuSceneArrays::RenderableBoundingVolumeRt::getSingleton().getElementCount() + 2) * m_sbtRecordSize, sbtAlignment, sbtMem);
  221. sbtHandle = rgraph.importBuffer(sbtBuffer, BufferUsageBit::kNone);
  222. // Write the first 2 entries of the SBT
  223. ConstWeakArray<U8> shaderGroupHandles = m_libraryGrProg->getShaderGroupHandles();
  224. const U32 shaderHandleSize = GrManager::getSingleton().getDeviceCapabilities().m_shaderGroupHandleSize;
  225. memcpy(sbtMem, &shaderGroupHandles[m_rayGenShaderGroupIdx * shaderHandleSize], shaderHandleSize);
  226. memcpy(sbtMem + m_sbtRecordSize, &shaderGroupHandles[m_missShaderGroupIdx * shaderHandleSize], shaderHandleSize);
  227. // Create the pass
  228. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtReflections build SBT");
  229. rpass.newBufferDependency(visibilityDep, BufferUsageBit::kIndirectCompute | BufferUsageBit::kSrvCompute);
  230. rpass.newBufferDependency(sbtHandle, BufferUsageBit::kUavCompute);
  231. rpass.setWork([this, buildSbtIndirectArgsBuff, sbtBuffer, visibleRenderableIndicesBuff](RenderPassWorkContext& rgraphCtx) {
  232. ANKI_TRACE_SCOPED_EVENT(ReflectionsSbtBuild);
  233. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  234. cmdb.bindShaderProgram(m_sbtBuildGrProg.get());
  235. cmdb.bindSrv(0, 0, GpuSceneArrays::Renderable::getSingleton().getBufferView());
  236. cmdb.bindSrv(1, 0, visibleRenderableIndicesBuff);
  237. cmdb.bindSrv(2, 0, BufferView(&m_libraryGrProg->getShaderGroupHandlesGpuBuffer()));
  238. cmdb.bindUav(0, 0, sbtBuffer);
  239. RtShadowsSbtBuildConstants consts = {};
  240. ANKI_ASSERT(m_sbtRecordSize % 4 == 0);
  241. consts.m_sbtRecordDwordSize = m_sbtRecordSize / 4;
  242. const U32 shaderHandleSize = GrManager::getSingleton().getDeviceCapabilities().m_shaderGroupHandleSize;
  243. ANKI_ASSERT(shaderHandleSize % 4 == 0);
  244. consts.m_shaderHandleDwordSize = shaderHandleSize / 4;
  245. cmdb.setFastConstants(&consts, sizeof(consts));
  246. cmdb.dispatchComputeIndirect(buildSbtIndirectArgsBuff);
  247. });
  248. }
  249. // Ray gen
  250. if(bRtReflections)
  251. {
  252. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtReflections");
  253. rpass.newBufferDependency(sbtHandle, BufferUsageBit::kShaderBindingTable);
  254. rpass.newTextureDependency(transientRt1, TextureUsageBit::kUavTraceRays);
  255. rpass.newTextureDependency(hitPosAndDepthRt, TextureUsageBit::kUavTraceRays);
  256. rpass.newTextureDependency(getRenderer().getGBuffer().getDepthRt(), TextureUsageBit::kSrvTraceRays);
  257. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(1), TextureUsageBit::kSrvTraceRays);
  258. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(2), TextureUsageBit::kSrvTraceRays);
  259. if(getRenderer().getGeneratedSky().isEnabled())
  260. {
  261. rpass.newTextureDependency(getRenderer().getGeneratedSky().getEnvironmentMapRt(), TextureUsageBit::kSrvTraceRays);
  262. }
  263. rpass.newTextureDependency(getRenderer().getShadowMapping().getShadowmapRt(), TextureUsageBit::kSrvTraceRays);
  264. rpass.newAccelerationStructureDependency(getRenderer().getAccelerationStructureBuilder().getAccelerationStructureHandle(),
  265. AccelerationStructureUsageBit::kTraceRaysSrv);
  266. rpass.newBufferDependency(indirectArgsHandle, BufferUsageBit::kIndirectTraceRays);
  267. rpass.setWork([this, sbtBuffer, &ctx, transientRt1, hitPosAndDepthRt, pixelsFailedSsrBuff](RenderPassWorkContext& rgraphCtx) {
  268. ANKI_TRACE_SCOPED_EVENT(ReflectionsRayGen);
  269. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  270. cmdb.bindShaderProgram(m_libraryGrProg.get());
  271. // More globals
  272. cmdb.bindSampler(ANKI_MATERIAL_REGISTER_TILINEAR_REPEAT_SAMPLER, 0, getRenderer().getSamplers().m_trilinearRepeat.get());
  273. cmdb.bindSrv(ANKI_MATERIAL_REGISTER_GPU_SCENE, 0, GpuSceneBuffer::getSingleton().getBufferView());
  274. cmdb.bindSrv(ANKI_MATERIAL_REGISTER_MESH_LODS, 0, GpuSceneArrays::MeshLod::getSingleton().getBufferView());
  275. cmdb.bindSrv(ANKI_MATERIAL_REGISTER_TRANSFORMS, 0, GpuSceneArrays::Transform::getSingleton().getBufferView());
  276. #define ANKI_UNIFIED_GEOM_FORMAT(fmt, shaderType, reg) \
  277. cmdb.bindSrv( \
  278. reg, 0, \
  279. BufferView(&UnifiedGeometryBuffer::getSingleton().getBuffer(), 0, \
  280. getAlignedRoundDown(getFormatInfo(Format::k##fmt).m_texelSize, UnifiedGeometryBuffer::getSingleton().getBuffer().getSize())), \
  281. Format::k##fmt);
  282. #include <AnKi/Shaders/Include/UnifiedGeometryTypes.def.h>
  283. cmdb.bindConstantBuffer(0, 2, ctx.m_globalRenderingConstantsBuffer);
  284. rgraphCtx.bindSrv(0, 2, getRenderer().getAccelerationStructureBuilder().getAccelerationStructureHandle());
  285. rgraphCtx.bindSrv(1, 2, getRenderer().getGBuffer().getDepthRt());
  286. rgraphCtx.bindSrv(2, 2, getRenderer().getGBuffer().getColorRt(1));
  287. rgraphCtx.bindSrv(3, 2, getRenderer().getGBuffer().getColorRt(2));
  288. const LightComponent* dirLight = SceneGraph::getSingleton().getDirectionalLight();
  289. const SkyboxComponent* sky = SceneGraph::getSingleton().getSkybox();
  290. const Bool bSkySolidColor =
  291. (!sky || sky->getSkyboxType() == SkyboxType::kSolidColor || (!dirLight && sky->getSkyboxType() == SkyboxType::kGenerated));
  292. if(bSkySolidColor)
  293. {
  294. cmdb.bindSrv(4, 2, TextureView(&getRenderer().getDummyTexture2d(), TextureSubresourceDesc::all()));
  295. }
  296. else if(sky->getSkyboxType() == SkyboxType::kImage2D)
  297. {
  298. cmdb.bindSrv(4, 2, TextureView(&sky->getImageResource().getTexture(), TextureSubresourceDesc::all()));
  299. }
  300. else
  301. {
  302. rgraphCtx.bindSrv(4, 2, getRenderer().getGeneratedSky().getEnvironmentMapRt());
  303. }
  304. cmdb.bindSrv(
  305. 5, 2,
  306. (GpuSceneArrays::GlobalIlluminationProbe::getSingleton().getElementCount())
  307. ? GpuSceneArrays::GlobalIlluminationProbe::getSingleton().getBufferView()
  308. : BufferView(&getRenderer().getDummyBuffer(), 0, GpuSceneArrays::GlobalIlluminationProbe::getSingleton().getElementSize()));
  309. cmdb.bindSrv(6, 2, pixelsFailedSsrBuff);
  310. rgraphCtx.bindSrv(7, 2, getRenderer().getShadowMapping().getShadowmapRt());
  311. rgraphCtx.bindUav(0, 2, transientRt1);
  312. rgraphCtx.bindUav(1, 2, hitPosAndDepthRt);
  313. cmdb.bindSampler(0, 2, getRenderer().getSamplers().m_trilinearClamp.get());
  314. cmdb.bindSampler(1, 2, getRenderer().getSamplers().m_trilinearClampShadow.get());
  315. struct Consts
  316. {
  317. F32 m_maxRayT;
  318. U32 m_giProbeCount;
  319. F32 m_padding1;
  320. F32 m_padding2;
  321. } consts = {g_rtReflectionsMaxRayDistanceCVar, GpuSceneArrays::GlobalIlluminationProbe::getSingleton().getElementCount(), 0, 0};
  322. cmdb.setFastConstants(&consts, sizeof(consts));
  323. cmdb.traceRaysIndirect(sbtBuffer, m_sbtRecordSize, GpuSceneArrays::RenderableBoundingVolumeRt::getSingleton().getElementCount(), 1,
  324. BufferView(m_indirectArgsBuffer.get()).setRange(sizeof(DispatchIndirectArgs)));
  325. });
  326. }
  327. else
  328. {
  329. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("ReflectionProbeFallback");
  330. rpass.newTextureDependency(getRenderer().getGBuffer().getDepthRt(), TextureUsageBit::kSrvCompute);
  331. rpass.newBufferDependency(getRenderer().getClusterBinning().getDependency(), BufferUsageBit::kSrvCompute);
  332. rpass.newBufferDependency(indirectArgsHandle, BufferUsageBit::kIndirectCompute);
  333. rpass.newTextureDependency(transientRt1, TextureUsageBit::kUavCompute);
  334. rpass.newTextureDependency(hitPosAndDepthRt, TextureUsageBit::kUavCompute);
  335. if(getRenderer().getGeneratedSky().isEnabled())
  336. {
  337. rpass.newTextureDependency(getRenderer().getGeneratedSky().getEnvironmentMapRt(), TextureUsageBit::kSrvCompute);
  338. }
  339. if(getRenderer().getProbeReflections().getHasCurrentlyRefreshedReflectionRt())
  340. {
  341. rpass.newTextureDependency(getRenderer().getProbeReflections().getCurrentlyRefreshedReflectionRt(), TextureUsageBit::kSrvCompute);
  342. }
  343. rpass.setWork([this, pixelsFailedSsrBuff, &ctx, transientRt1, hitPosAndDepthRt](RenderPassWorkContext& rgraphCtx) {
  344. ANKI_TRACE_SCOPED_EVENT(ReflectionsProbeFallback);
  345. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  346. cmdb.bindShaderProgram(m_probeFallbackGrProg.get());
  347. rgraphCtx.bindSrv(0, 0, getRenderer().getGBuffer().getDepthRt());
  348. cmdb.bindSrv(1, 0, pixelsFailedSsrBuff);
  349. cmdb.bindSrv(2, 0, getRenderer().getClusterBinning().getPackedObjectsBuffer(GpuSceneNonRenderableObjectType::kReflectionProbe));
  350. cmdb.bindSrv(3, 0, getRenderer().getClusterBinning().getClustersBuffer());
  351. cmdb.bindSrv(4, 0, BufferView(m_indirectArgsBuffer.get()).setRange(sizeof(U32)));
  352. const LightComponent* dirLight = SceneGraph::getSingleton().getDirectionalLight();
  353. const SkyboxComponent* sky = SceneGraph::getSingleton().getSkybox();
  354. const Bool bSkySolidColor =
  355. (!sky || sky->getSkyboxType() == SkyboxType::kSolidColor || (!dirLight && sky->getSkyboxType() == SkyboxType::kGenerated));
  356. if(bSkySolidColor)
  357. {
  358. cmdb.bindSrv(5, 0, TextureView(&getRenderer().getDummyTexture2d(), TextureSubresourceDesc::all()));
  359. }
  360. else if(sky->getSkyboxType() == SkyboxType::kImage2D)
  361. {
  362. cmdb.bindSrv(5, 0, TextureView(&sky->getImageResource().getTexture(), TextureSubresourceDesc::all()));
  363. }
  364. else
  365. {
  366. rgraphCtx.bindSrv(5, 0, getRenderer().getGeneratedSky().getEnvironmentMapRt());
  367. }
  368. cmdb.bindConstantBuffer(0, 0, ctx.m_globalRenderingConstantsBuffer);
  369. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearClamp.get());
  370. rgraphCtx.bindUav(0, 0, transientRt1);
  371. rgraphCtx.bindUav(1, 0, hitPosAndDepthRt);
  372. cmdb.dispatchComputeIndirect(BufferView(m_indirectArgsBuffer.get()).incrementOffset(sizeof(DispatchIndirectArgs)));
  373. });
  374. }
  375. // Spatial denoising
  376. {
  377. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("ReflectionsSpatialDenoise");
  378. rpass.newTextureDependency(transientRt1, TextureUsageBit::kSrvCompute);
  379. rpass.newTextureDependency(hitPosAndDepthRt, TextureUsageBit::kSrvCompute);
  380. rpass.newTextureDependency(getRenderer().getGBuffer().getDepthRt(), TextureUsageBit::kSrvCompute);
  381. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(1), TextureUsageBit::kSrvCompute);
  382. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(2), TextureUsageBit::kSrvCompute);
  383. rpass.newTextureDependency(classTileMapRt, TextureUsageBit::kSrvCompute);
  384. rpass.newTextureDependency(transientRt2, TextureUsageBit::kUavCompute);
  385. rpass.newTextureDependency(hitPosRt, TextureUsageBit::kUavCompute);
  386. rpass.setWork([this, &ctx, transientRt1, transientRt2, hitPosAndDepthRt, hitPosRt, consts, classTileMapRt](RenderPassWorkContext& rgraphCtx) {
  387. ANKI_TRACE_SCOPED_EVENT(ReflectionsSpatialDenoise);
  388. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  389. cmdb.bindShaderProgram(m_spatialDenoisingGrProg.get());
  390. rgraphCtx.bindSrv(0, 0, transientRt1);
  391. rgraphCtx.bindSrv(1, 0, hitPosAndDepthRt);
  392. rgraphCtx.bindSrv(2, 0, getRenderer().getGBuffer().getDepthRt());
  393. rgraphCtx.bindSrv(3, 0, getRenderer().getGBuffer().getColorRt(1));
  394. rgraphCtx.bindSrv(4, 0, getRenderer().getGBuffer().getColorRt(2));
  395. rgraphCtx.bindSrv(5, 0, classTileMapRt);
  396. rgraphCtx.bindUav(0, 0, transientRt2);
  397. rgraphCtx.bindUav(1, 0, hitPosRt);
  398. cmdb.bindConstantBuffer(0, 0, ctx.m_globalRenderingConstantsBuffer);
  399. cmdb.setFastConstants(&consts, sizeof(consts));
  400. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y());
  401. });
  402. }
  403. // Temporal denoising
  404. {
  405. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("ReflectionsTemporalDenoise");
  406. rpass.newTextureDependency(transientRt2, TextureUsageBit::kSrvCompute);
  407. rpass.newTextureDependency(mainRt, TextureUsageBit::kSrvCompute);
  408. rpass.newTextureDependency(readMomentsRt, TextureUsageBit::kSrvCompute);
  409. rpass.newTextureDependency(getRenderer().getMotionVectors().getMotionVectorsRt(), TextureUsageBit::kSrvCompute);
  410. rpass.newTextureDependency(hitPosRt, TextureUsageBit::kSrvCompute);
  411. rpass.newTextureDependency(classTileMapRt, TextureUsageBit::kSrvCompute);
  412. rpass.newTextureDependency(transientRt1, TextureUsageBit::kUavCompute);
  413. rpass.newTextureDependency(writeMomentsRt, TextureUsageBit::kUavCompute);
  414. rpass.setWork([this, &ctx, transientRt1, transientRt2, mainRt, readMomentsRt, writeMomentsRt, hitPosRt,
  415. classTileMapRt](RenderPassWorkContext& rgraphCtx) {
  416. ANKI_TRACE_SCOPED_EVENT(ReflectionsTemporalDenoise);
  417. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  418. cmdb.bindShaderProgram(m_temporalDenoisingGrProg.get());
  419. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearClamp.get());
  420. rgraphCtx.bindSrv(0, 0, transientRt2);
  421. rgraphCtx.bindSrv(1, 0, mainRt);
  422. rgraphCtx.bindSrv(2, 0, readMomentsRt);
  423. rgraphCtx.bindSrv(3, 0, getRenderer().getMotionVectors().getMotionVectorsRt());
  424. rgraphCtx.bindSrv(4, 0, hitPosRt);
  425. rgraphCtx.bindSrv(5, 0, classTileMapRt);
  426. rgraphCtx.bindUav(0, 0, transientRt1);
  427. rgraphCtx.bindUav(1, 0, writeMomentsRt);
  428. cmdb.bindConstantBuffer(0, 0, ctx.m_globalRenderingConstantsBuffer);
  429. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y());
  430. });
  431. }
  432. // Hotizontal bilateral filter
  433. {
  434. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("ReflectionsHorizBilateral");
  435. rpass.newTextureDependency(transientRt1, TextureUsageBit::kSrvCompute);
  436. rpass.newTextureDependency(writeMomentsRt, TextureUsageBit::kSrvCompute);
  437. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(1), TextureUsageBit::kSrvCompute);
  438. rpass.newTextureDependency(classTileMapRt, TextureUsageBit::kSrvCompute);
  439. rpass.newTextureDependency(transientRt2, TextureUsageBit::kUavCompute);
  440. rpass.setWork([this, transientRt1, transientRt2, writeMomentsRt, consts, classTileMapRt](RenderPassWorkContext& rgraphCtx) {
  441. ANKI_TRACE_SCOPED_EVENT(ReflectionsHorizontalDenoise);
  442. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  443. cmdb.bindShaderProgram(m_horizontalBilateralDenoisingGrProg.get());
  444. rgraphCtx.bindSrv(0, 0, transientRt1);
  445. rgraphCtx.bindSrv(1, 0, writeMomentsRt);
  446. rgraphCtx.bindSrv(2, 0, getRenderer().getGBuffer().getColorRt(1));
  447. rgraphCtx.bindSrv(3, 0, classTileMapRt);
  448. rgraphCtx.bindUav(0, 0, transientRt2);
  449. cmdb.setFastConstants(&consts, sizeof(consts));
  450. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y());
  451. });
  452. }
  453. // Vertical bilateral filter
  454. {
  455. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("ReflectionsVertBilateral");
  456. rpass.newTextureDependency(transientRt2, TextureUsageBit::kSrvCompute);
  457. rpass.newTextureDependency(mainRt, TextureUsageBit::kUavCompute);
  458. rpass.newTextureDependency(classTileMapRt, TextureUsageBit::kSrvCompute);
  459. rpass.setWork([this, transientRt2, mainRt, classTileMapRt](RenderPassWorkContext& rgraphCtx) {
  460. ANKI_TRACE_SCOPED_EVENT(ReflectionsVerticalDenoise);
  461. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  462. cmdb.bindShaderProgram(m_verticalBilateralDenoisingGrProg.get());
  463. rgraphCtx.bindSrv(0, 0, transientRt2);
  464. rgraphCtx.bindSrv(1, 0, classTileMapRt);
  465. rgraphCtx.bindUav(0, 0, mainRt);
  466. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y());
  467. });
  468. }
  469. m_runCtx.m_rt = mainRt;
  470. }
  471. } // end namespace anki