IndirectDiffuseClipmaps.cpp 20 KB

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