IndirectDiffuseClipmaps.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  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/IndirectDiffuseClipmaps.h>
  6. #include <AnKi/Renderer/Renderer.h>
  7. #include <AnKi/Renderer/GBuffer.h>
  8. #include <AnKi/Renderer/AccelerationStructureBuilder.h>
  9. #include <AnKi/Renderer/Sky.h>
  10. #include <AnKi/Renderer/ShadowMapping.h>
  11. #include <AnKi/Scene/Components/SkyboxComponent.h>
  12. #include <AnKi/Shaders/Include/MaterialTypes.h>
  13. #include <AnKi/Util/Tracer.h>
  14. #include <AnKi/GpuMemory/UnifiedGeometryBuffer.h>
  15. namespace anki {
  16. Error IndirectDiffuseClipmaps::init()
  17. {
  18. m_tmpRtDesc = getRenderer().create2DRenderTargetDescription(getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y(),
  19. Format::kR8G8B8A8_Unorm, "Test");
  20. m_tmpRtDesc.bake();
  21. m_clipmapInfo[0].m_probeCounts =
  22. UVec3(g_indirectDiffuseClipmapProbesXZCVar, g_indirectDiffuseClipmapProbesYCVar, g_indirectDiffuseClipmapProbesXZCVar);
  23. m_clipmapInfo[1].m_probeCounts = m_clipmapInfo[0].m_probeCounts;
  24. m_clipmapInfo[2].m_probeCounts = m_clipmapInfo[0].m_probeCounts;
  25. m_clipmapInfo[0].m_size = Vec3(g_indirectDiffuseClipmap0XZSizeCVar, g_indirectDiffuseClipmap0YSizeCVar, g_indirectDiffuseClipmap0XZSizeCVar);
  26. m_clipmapInfo[1].m_size = Vec3(g_indirectDiffuseClipmap1XZSizeCVar, g_indirectDiffuseClipmap1YSizeCVar, g_indirectDiffuseClipmap1XZSizeCVar);
  27. m_clipmapInfo[2].m_size = Vec3(g_indirectDiffuseClipmap2XZSizeCVar, g_indirectDiffuseClipmap2YSizeCVar, g_indirectDiffuseClipmap2XZSizeCVar);
  28. U32 probesPerClipmap = 0;
  29. for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
  30. {
  31. const U32 count = m_clipmapInfo[i].m_probeCounts.x() * m_clipmapInfo[i].m_probeCounts.y() * m_clipmapInfo[i].m_probeCounts.z();
  32. m_clipmapInfo[i].m_probeCountsTotal = count;
  33. m_clipmapInfo[i].m_index = i;
  34. if(i == 0)
  35. {
  36. probesPerClipmap = count;
  37. }
  38. else
  39. {
  40. ANKI_ASSERT(probesPerClipmap == count);
  41. }
  42. }
  43. for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
  44. {
  45. m_probeValidityRtDescs[i] =
  46. getRenderer().create2DRenderTargetDescription(m_clipmapInfo[i].m_probeCounts.x(), m_clipmapInfo[i].m_probeCounts.z(), Format::kR8_Unorm,
  47. generateTempPassName("IndirectDiffuseClipmap: Probe validity #%u", i));
  48. m_probeValidityRtDescs[i].m_depth = m_clipmapInfo[i].m_probeCounts.y();
  49. m_probeValidityRtDescs[i].m_type = TextureType::k3D;
  50. m_probeValidityRtDescs[i].bake();
  51. }
  52. // Create the lighting result texture
  53. m_rtResultRtDesc = getRenderer().create2DRenderTargetDescription(probesPerClipmap, kRaysPerProbePerFrame, Format::kR16G16B16A16_Sfloat,
  54. "IndirectDiffuseClipmap: RT result");
  55. m_rtResultRtDesc.bake();
  56. for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount; ++clipmap)
  57. {
  58. TextureInitInfo volumeInit = getRenderer().create2DRenderTargetInitInfo(
  59. m_clipmapInfo[clipmap].m_probeCounts.x() * (g_indirectDiffuseClipmapRadianceOctMapSize + 2),
  60. m_clipmapInfo[clipmap].m_probeCounts.z() * (g_indirectDiffuseClipmapRadianceOctMapSize + 2), Format::kB10G11R11_Ufloat_Pack32,
  61. TextureUsageBit::kAllShaderResource, generateTempPassName("IndirectDiffuseClipmap: Radiance #%u", clipmap));
  62. volumeInit.m_depth = m_clipmapInfo[clipmap].m_probeCounts.y();
  63. volumeInit.m_type = TextureType::k3D;
  64. m_radianceVolumes[clipmap] = getRenderer().createAndClearRenderTarget(volumeInit, TextureUsageBit::kSrvCompute);
  65. }
  66. for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount; ++clipmap)
  67. {
  68. TextureInitInfo volumeInit = getRenderer().create2DRenderTargetInitInfo(
  69. m_clipmapInfo[clipmap].m_probeCounts.x() * (g_indirectDiffuseClipmapIrradianceOctMapSize + 2),
  70. m_clipmapInfo[clipmap].m_probeCounts.z() * (g_indirectDiffuseClipmapIrradianceOctMapSize + 2), Format::kB10G11R11_Ufloat_Pack32,
  71. TextureUsageBit::kAllShaderResource, generateTempPassName("IndirectDiffuseClipmap: Irradiance #%u", clipmap));
  72. volumeInit.m_depth = m_clipmapInfo[clipmap].m_probeCounts.y();
  73. volumeInit.m_type = TextureType::k3D;
  74. m_irradianceVolumes[clipmap] = getRenderer().createAndClearRenderTarget(volumeInit, TextureUsageBit::kSrvCompute);
  75. }
  76. for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount; ++clipmap)
  77. {
  78. TextureInitInfo volumeInit = getRenderer().create2DRenderTargetInitInfo(
  79. m_clipmapInfo[clipmap].m_probeCounts.x() * (g_indirectDiffuseClipmapRadianceOctMapSize + 2),
  80. m_clipmapInfo[clipmap].m_probeCounts.z() * (g_indirectDiffuseClipmapRadianceOctMapSize + 2), Format::kR16G16_Sfloat,
  81. TextureUsageBit::kAllShaderResource, generateTempPassName("IndirectDiffuseClipmap: Dist moments #%u", clipmap));
  82. volumeInit.m_depth = m_clipmapInfo[clipmap].m_probeCounts.y();
  83. volumeInit.m_type = TextureType::k3D;
  84. m_distanceMomentsVolumes[clipmap] = getRenderer().createAndClearRenderTarget(volumeInit, TextureUsageBit::kSrvCompute);
  85. }
  86. const Array<SubMutation, 4> mutation = {{{"RAYS_PER_PROBE_PER_FRAME", kRaysPerProbePerFrame},
  87. {"GPU_WAVE_SIZE", MutatorValue(GrManager::getSingleton().getDeviceCapabilities().m_maxWaveSize)},
  88. {"RADIANCE_OCTAHEDRON_MAP_SIZE", MutatorValue(g_indirectDiffuseClipmapRadianceOctMapSize)},
  89. {"IRRADIANCE_OCTAHEDRON_MAP_SIZE", MutatorValue(g_indirectDiffuseClipmapIrradianceOctMapSize)}}};
  90. ANKI_CHECK(loadShaderProgram("ShaderBinaries/IndirectDiffuseClipmaps.ankiprogbin", mutation, m_prog, m_tmpVisGrProg, "Test"));
  91. ANKI_CHECK(loadShaderProgram("ShaderBinaries/IndirectDiffuseClipmaps.ankiprogbin", mutation, m_prog, m_visProbesGrProg, "VisualizeProbes"));
  92. ANKI_CHECK(loadShaderProgram("ShaderBinaries/IndirectDiffuseClipmaps.ankiprogbin", mutation, m_prog, m_populateCachesGrProg, "PopulateCaches"));
  93. ANKI_CHECK(
  94. loadShaderProgram("ShaderBinaries/IndirectDiffuseClipmaps.ankiprogbin", mutation, m_prog, m_computeIrradianceGrProg, "ComputeIrradiance"));
  95. ANKI_CHECK(loadShaderProgram("ShaderBinaries/RtSbtBuild.ankiprogbin", {{"TECHNIQUE", 1}}, m_sbtProg, m_sbtBuildGrProg, "SbtBuild"));
  96. {
  97. ShaderProgramResourcePtr tmpProg;
  98. ANKI_CHECK(ResourceManager::getSingleton().loadResource("ShaderBinaries/IndirectDiffuseClipmaps.ankiprogbin", tmpProg));
  99. ANKI_ASSERT(tmpProg == m_prog);
  100. ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
  101. variantInitInfo.requestTechniqueAndTypes(ShaderTypeBit::kRayGen, "RtMaterialFetch");
  102. for(const SubMutation& s : mutation)
  103. {
  104. variantInitInfo.addMutation(s.m_mutatorName, s.m_value);
  105. }
  106. const ShaderProgramResourceVariant* variant;
  107. m_prog->getOrCreateVariant(variantInitInfo, variant);
  108. m_libraryGrProg.reset(&variant->getProgram());
  109. m_rayGenShaderGroupIdx = variant->getShaderGroupHandleIndex();
  110. }
  111. {
  112. ANKI_CHECK(ResourceManager::getSingleton().loadResource("ShaderBinaries/RtMaterialFetchMiss.ankiprogbin", m_missProg));
  113. ShaderProgramResourceVariantInitInfo variantInitInfo(m_missProg);
  114. variantInitInfo.requestTechniqueAndTypes(ShaderTypeBit::kMiss, "RtMaterialFetch");
  115. const ShaderProgramResourceVariant* variant;
  116. m_missProg->getOrCreateVariant(variantInitInfo, variant);
  117. m_missShaderGroupIdx = variant->getShaderGroupHandleIndex();
  118. }
  119. m_sbtRecordSize = getAlignedRoundUp(GrManager::getSingleton().getDeviceCapabilities().m_sbtRecordAlignment,
  120. GrManager::getSingleton().getDeviceCapabilities().m_shaderGroupHandleSize + U32(sizeof(UVec4)));
  121. ANKI_CHECK(ResourceManager::getSingleton().loadResource("EngineAssets/BlueNoise_Rgba8_64x64.png", m_blueNoiseImg));
  122. return Error::kNone;
  123. }
  124. void IndirectDiffuseClipmaps::populateRenderGraph(RenderingContext& ctx)
  125. {
  126. ANKI_TRACE_SCOPED_EVENT(IndirectDiffuse);
  127. RenderGraphBuilder& rgraph = ctx.m_renderGraphDescr;
  128. const RenderTargetHandle rtResultHandle = rgraph.newRenderTarget(m_rtResultRtDesc);
  129. m_runCtx.m_tmpRt = rgraph.newRenderTarget(m_tmpRtDesc);
  130. Array<RenderTargetHandle, kIndirectDiffuseClipmapCount> radianceVolumes;
  131. Array<RenderTargetHandle, kIndirectDiffuseClipmapCount> irradianceVolumes;
  132. Array<RenderTargetHandle, kIndirectDiffuseClipmapCount> distanceMomentsVolumes;
  133. for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
  134. {
  135. if(m_texturesImportedOnce)
  136. {
  137. radianceVolumes[i] = rgraph.importRenderTarget(m_radianceVolumes[i].get());
  138. irradianceVolumes[i] = rgraph.importRenderTarget(m_irradianceVolumes[i].get());
  139. distanceMomentsVolumes[i] = rgraph.importRenderTarget(m_distanceMomentsVolumes[i].get());
  140. }
  141. else
  142. {
  143. radianceVolumes[i] = rgraph.importRenderTarget(m_radianceVolumes[i].get(), TextureUsageBit::kSrvCompute);
  144. irradianceVolumes[i] = rgraph.importRenderTarget(m_irradianceVolumes[i].get(), TextureUsageBit::kSrvCompute);
  145. distanceMomentsVolumes[i] = rgraph.importRenderTarget(m_distanceMomentsVolumes[i].get(), TextureUsageBit::kSrvCompute);
  146. }
  147. }
  148. Array<RenderTargetHandle, kIndirectDiffuseClipmapCount> probeValidityRts;
  149. for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
  150. {
  151. probeValidityRts[i] = rgraph.newRenderTarget(m_probeValidityRtDescs[i]);
  152. }
  153. m_runCtx.m_probeValidityRts = probeValidityRts;
  154. // SBT build
  155. BufferHandle sbtHandle;
  156. BufferView sbtBuffer;
  157. {
  158. BufferHandle visibilityDep;
  159. BufferView visibleRenderableIndicesBuff, buildSbtIndirectArgsBuff;
  160. getRenderer().getAccelerationStructureBuilder().getVisibilityInfo(visibilityDep, visibleRenderableIndicesBuff, buildSbtIndirectArgsBuff);
  161. // Allocate SBT
  162. U32 sbtAlignment = (GrManager::getSingleton().getDeviceCapabilities().m_structuredBufferNaturalAlignment)
  163. ? sizeof(U32)
  164. : GrManager::getSingleton().getDeviceCapabilities().m_structuredBufferBindOffsetAlignment;
  165. sbtAlignment = computeCompoundAlignment(sbtAlignment, GrManager::getSingleton().getDeviceCapabilities().m_sbtRecordAlignment);
  166. U8* sbtMem;
  167. sbtBuffer = RebarTransientMemoryPool::getSingleton().allocate(
  168. (GpuSceneArrays::RenderableBoundingVolumeRt::getSingleton().getElementCount() + 2) * m_sbtRecordSize, sbtAlignment, sbtMem);
  169. sbtHandle = rgraph.importBuffer(sbtBuffer, BufferUsageBit::kNone);
  170. // Write the first 2 entries of the SBT
  171. ConstWeakArray<U8> shaderGroupHandles = m_libraryGrProg->getShaderGroupHandles();
  172. const U32 shaderHandleSize = GrManager::getSingleton().getDeviceCapabilities().m_shaderGroupHandleSize;
  173. memcpy(sbtMem, &shaderGroupHandles[m_rayGenShaderGroupIdx * shaderHandleSize], shaderHandleSize);
  174. memcpy(sbtMem + m_sbtRecordSize, &shaderGroupHandles[m_missShaderGroupIdx * shaderHandleSize], shaderHandleSize);
  175. // Create the pass
  176. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtReflections build SBT");
  177. rpass.newBufferDependency(visibilityDep, BufferUsageBit::kIndirectCompute | BufferUsageBit::kSrvCompute);
  178. rpass.newBufferDependency(sbtHandle, BufferUsageBit::kUavCompute);
  179. rpass.setWork([this, buildSbtIndirectArgsBuff, sbtBuffer, visibleRenderableIndicesBuff](RenderPassWorkContext& rgraphCtx) {
  180. ANKI_TRACE_SCOPED_EVENT(ReflectionsSbtBuild);
  181. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  182. cmdb.bindShaderProgram(m_sbtBuildGrProg.get());
  183. cmdb.bindSrv(0, 0, GpuSceneArrays::Renderable::getSingleton().getBufferView());
  184. cmdb.bindSrv(1, 0, visibleRenderableIndicesBuff);
  185. cmdb.bindSrv(2, 0, BufferView(&m_libraryGrProg->getShaderGroupHandlesGpuBuffer()));
  186. cmdb.bindUav(0, 0, sbtBuffer);
  187. RtShadowsSbtBuildConstants consts = {};
  188. ANKI_ASSERT(m_sbtRecordSize % 4 == 0);
  189. consts.m_sbtRecordDwordSize = m_sbtRecordSize / 4;
  190. const U32 shaderHandleSize = GrManager::getSingleton().getDeviceCapabilities().m_shaderGroupHandleSize;
  191. ANKI_ASSERT(shaderHandleSize % 4 == 0);
  192. consts.m_shaderHandleDwordSize = shaderHandleSize / 4;
  193. cmdb.setFastConstants(&consts, sizeof(consts));
  194. cmdb.dispatchComputeIndirect(buildSbtIndirectArgsBuff);
  195. });
  196. }
  197. for(U32 clipmap = 0; clipmap < kIndirectDiffuseClipmapCount; ++clipmap)
  198. {
  199. // Do ray tracing around the probes
  200. {
  201. NonGraphicsRenderPass& pass = rgraph.newNonGraphicsRenderPass(generateTempPassName("IndirectDiffuseClipmaps: RT #%u", clipmap));
  202. pass.newTextureDependency(rtResultHandle, TextureUsageBit::kUavCompute);
  203. pass.newBufferDependency(sbtHandle, BufferUsageBit::kShaderBindingTable);
  204. if(getRenderer().getGeneratedSky().isEnabled())
  205. {
  206. pass.newTextureDependency(getRenderer().getGeneratedSky().getEnvironmentMapRt(), TextureUsageBit::kSrvTraceRays);
  207. }
  208. pass.newTextureDependency(getRenderer().getShadowMapping().getShadowmapRt(), TextureUsageBit::kSrvTraceRays);
  209. pass.newAccelerationStructureDependency(getRenderer().getAccelerationStructureBuilder().getAccelerationStructureHandle(),
  210. AccelerationStructureUsageBit::kTraceRaysSrv);
  211. pass.setWork([this, rtResultHandle, &ctx, sbtBuffer, clipmap](RenderPassWorkContext& rgraphCtx) {
  212. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  213. cmdb.bindShaderProgram(m_libraryGrProg.get());
  214. // More globals
  215. cmdb.bindSampler(ANKI_MATERIAL_REGISTER_TILINEAR_REPEAT_SAMPLER, 0, getRenderer().getSamplers().m_trilinearRepeat.get());
  216. cmdb.bindSrv(ANKI_MATERIAL_REGISTER_GPU_SCENE, 0, GpuSceneBuffer::getSingleton().getBufferView());
  217. cmdb.bindSrv(ANKI_MATERIAL_REGISTER_MESH_LODS, 0, GpuSceneArrays::MeshLod::getSingleton().getBufferView());
  218. cmdb.bindSrv(ANKI_MATERIAL_REGISTER_TRANSFORMS, 0, GpuSceneArrays::Transform::getSingleton().getBufferView());
  219. #define ANKI_UNIFIED_GEOM_FORMAT(fmt, shaderType, reg) \
  220. cmdb.bindSrv( \
  221. reg, 0, \
  222. BufferView(&UnifiedGeometryBuffer::getSingleton().getBuffer(), 0, \
  223. getAlignedRoundDown(getFormatInfo(Format::k##fmt).m_texelSize, UnifiedGeometryBuffer::getSingleton().getBuffer().getSize())), \
  224. Format::k##fmt);
  225. #include <AnKi/Shaders/Include/UnifiedGeometryTypes.def.h>
  226. cmdb.bindConstantBuffer(0, 2, ctx.m_globalRenderingConstantsBuffer);
  227. rgraphCtx.bindSrv(0, 2, getRenderer().getAccelerationStructureBuilder().getAccelerationStructureHandle());
  228. cmdb.bindSrv(1, 2, TextureView(getDummyGpuResources().m_texture2DSrv.get(), TextureSubresourceDesc::all()));
  229. cmdb.bindSrv(2, 2, TextureView(getDummyGpuResources().m_texture2DSrv.get(), TextureSubresourceDesc::all()));
  230. cmdb.bindSrv(3, 2, TextureView(getDummyGpuResources().m_texture2DSrv.get(), TextureSubresourceDesc::all()));
  231. const LightComponent* dirLight = SceneGraph::getSingleton().getDirectionalLight();
  232. const SkyboxComponent* sky = SceneGraph::getSingleton().getSkybox();
  233. const Bool bSkySolidColor =
  234. (!sky || sky->getSkyboxType() == SkyboxType::kSolidColor || (!dirLight && sky->getSkyboxType() == SkyboxType::kGenerated));
  235. if(bSkySolidColor)
  236. {
  237. cmdb.bindSrv(4, 2, TextureView(getDummyGpuResources().m_texture2DSrv.get(), TextureSubresourceDesc::all()));
  238. }
  239. else if(sky->getSkyboxType() == SkyboxType::kImage2D)
  240. {
  241. cmdb.bindSrv(4, 2, TextureView(&sky->getImageResource().getTexture(), TextureSubresourceDesc::all()));
  242. }
  243. else
  244. {
  245. rgraphCtx.bindSrv(4, 2, getRenderer().getGeneratedSky().getEnvironmentMapRt());
  246. }
  247. cmdb.bindSrv(5, 2, BufferView(getDummyGpuResources().m_buffer.get(), 0, sizeof(U32)));
  248. cmdb.bindSrv(6, 2, BufferView(getDummyGpuResources().m_buffer.get(), 0, sizeof(U32)));
  249. rgraphCtx.bindSrv(7, 2, getRenderer().getShadowMapping().getShadowmapRt());
  250. cmdb.bindSampler(0, 2, getRenderer().getSamplers().m_trilinearClamp.get());
  251. cmdb.bindSampler(1, 2, getRenderer().getSamplers().m_trilinearClampShadow.get());
  252. rgraphCtx.bindUav(0, 2, rtResultHandle);
  253. cmdb.bindUav(1, 2, TextureView(getDummyGpuResources().m_texture2DUav.get(), TextureSubresourceDesc::firstSurface()));
  254. const UVec4 consts(clipmap, kRaysPerProbePerFrame, 0, 0);
  255. cmdb.setFastConstants(&consts, sizeof(consts));
  256. const U32 probeCount = U32(m_clipmapInfo[0].m_probeCountsTotal);
  257. cmdb.traceRays(sbtBuffer, m_sbtRecordSize, GpuSceneArrays::RenderableBoundingVolumeRt::getSingleton().getElementCount(), 1,
  258. probeCount * kRaysPerProbePerFrame, 1, 1);
  259. });
  260. }
  261. // Populate caches
  262. {
  263. NonGraphicsRenderPass& pass =
  264. rgraph.newNonGraphicsRenderPass(generateTempPassName("IndirectDiffuseClipmaps: Populate caches #%u", clipmap));
  265. pass.newTextureDependency(rtResultHandle, TextureUsageBit::kSrvCompute);
  266. pass.newTextureDependency(radianceVolumes[clipmap], TextureUsageBit::kUavCompute);
  267. pass.newTextureDependency(probeValidityRts[clipmap], TextureUsageBit::kUavCompute);
  268. pass.newTextureDependency(distanceMomentsVolumes[clipmap], TextureUsageBit::kUavCompute);
  269. pass.setWork([this, &ctx, clipmap, rtResultHandle, radianceVolume = radianceVolumes[clipmap], validityVolume = probeValidityRts[clipmap],
  270. distanceMomentsVolume = distanceMomentsVolumes[clipmap]](RenderPassWorkContext& rgraphCtx) {
  271. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  272. cmdb.bindShaderProgram(m_populateCachesGrProg.get());
  273. rgraphCtx.bindSrv(0, 0, rtResultHandle);
  274. rgraphCtx.bindUav(0, 0, radianceVolume);
  275. rgraphCtx.bindUav(1, 0, distanceMomentsVolume);
  276. rgraphCtx.bindUav(2, 0, validityVolume);
  277. cmdb.bindConstantBuffer(0, 0, ctx.m_globalRenderingConstantsBuffer);
  278. const UVec4 consts(clipmap);
  279. cmdb.setFastConstants(&consts, sizeof(consts));
  280. cmdb.dispatchCompute(m_clipmapInfo[clipmap].m_probeCounts.x(), m_clipmapInfo[clipmap].m_probeCounts.y(),
  281. m_clipmapInfo[clipmap].m_probeCounts.z());
  282. });
  283. }
  284. // Compute irradiance
  285. {
  286. NonGraphicsRenderPass& pass = rgraph.newNonGraphicsRenderPass(generateTempPassName("IndirectDiffuseClipmaps: Irradiance #%u", clipmap));
  287. pass.newTextureDependency(radianceVolumes[clipmap], TextureUsageBit::kSrvCompute);
  288. pass.newTextureDependency(irradianceVolumes[clipmap], TextureUsageBit::kUavCompute);
  289. pass.setWork([this, &ctx, clipmap, radianceVolume = radianceVolumes[clipmap],
  290. irradianceVolume = irradianceVolumes[clipmap]](RenderPassWorkContext& rgraphCtx) {
  291. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  292. cmdb.bindShaderProgram(m_computeIrradianceGrProg.get());
  293. rgraphCtx.bindSrv(0, 0, radianceVolume);
  294. rgraphCtx.bindUav(0, 0, irradianceVolume);
  295. cmdb.bindConstantBuffer(0, 0, ctx.m_globalRenderingConstantsBuffer);
  296. const UVec4 consts(clipmap);
  297. cmdb.setFastConstants(&consts, sizeof(consts));
  298. cmdb.dispatchCompute(m_clipmapInfo[clipmap].m_probeCountsTotal, g_indirectDiffuseClipmapIrradianceOctMapSize,
  299. g_indirectDiffuseClipmapIrradianceOctMapSize);
  300. });
  301. }
  302. }
  303. // Test
  304. {
  305. NonGraphicsRenderPass& pass = rgraph.newNonGraphicsRenderPass("IndirectDiffuseClipmaps composite");
  306. pass.newTextureDependency(getRenderer().getGBuffer().getDepthRt(), TextureUsageBit::kSrvCompute);
  307. pass.newTextureDependency(getRenderer().getGBuffer().getColorRt(2), TextureUsageBit::kSrvCompute);
  308. for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
  309. {
  310. pass.newTextureDependency(irradianceVolumes[i], TextureUsageBit::kSrvCompute);
  311. pass.newTextureDependency(probeValidityRts[i], TextureUsageBit::kSrvCompute);
  312. pass.newTextureDependency(distanceMomentsVolumes[i], TextureUsageBit::kSrvCompute);
  313. }
  314. pass.newTextureDependency(m_runCtx.m_tmpRt, TextureUsageBit::kUavCompute);
  315. pass.setWork([this, &ctx, irradianceVolumes, probeValidityRts, distanceMomentsVolumes](RenderPassWorkContext& rgraphCtx) {
  316. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  317. cmdb.bindShaderProgram(m_tmpVisGrProg.get());
  318. rgraphCtx.bindSrv(0, 0, getRenderer().getGBuffer().getDepthRt());
  319. rgraphCtx.bindSrv(1, 0, getRenderer().getGBuffer().getColorRt(2));
  320. cmdb.bindSrv(2, 0, TextureView(&m_blueNoiseImg->getTexture(), TextureSubresourceDesc::firstSurface()));
  321. U32 srvReg = 3;
  322. for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
  323. {
  324. rgraphCtx.bindSrv(srvReg++, 0, irradianceVolumes[i]);
  325. }
  326. for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
  327. {
  328. rgraphCtx.bindSrv(srvReg++, 0, probeValidityRts[i]);
  329. }
  330. for(U32 i = 0; i < kIndirectDiffuseClipmapCount; ++i)
  331. {
  332. rgraphCtx.bindSrv(srvReg++, 0, distanceMomentsVolumes[i]);
  333. }
  334. rgraphCtx.bindUav(0, 0, m_runCtx.m_tmpRt);
  335. cmdb.bindConstantBuffer(0, 0, ctx.m_globalRenderingConstantsBuffer);
  336. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearRepeat.get());
  337. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y());
  338. });
  339. }
  340. }
  341. void IndirectDiffuseClipmaps::drawDebugProbes(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx) const
  342. {
  343. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  344. const U32 clipmap = 1;
  345. cmdb.bindShaderProgram(m_visProbesGrProg.get());
  346. const UVec4 consts(clipmap);
  347. cmdb.setFastConstants(&consts, sizeof(consts));
  348. cmdb.bindConstantBuffer(0, 0, ctx.m_globalRenderingConstantsBuffer);
  349. Texture* visVolume = m_irradianceVolumes[clipmap].get();
  350. cmdb.bindSrv(0, 0, TextureView(visVolume, TextureSubresourceDesc::all()));
  351. rgraphCtx.bindSrv(1, 0, m_runCtx.m_probeValidityRts[clipmap]);
  352. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearRepeat.get());
  353. cmdb.draw(PrimitiveTopology::kTriangles, 36, m_clipmapInfo[clipmap].m_probeCountsTotal);
  354. }
  355. } // end namespace anki