IndirectDiffuse.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. // Copyright (C) 2009-2021, 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/IndirectDiffuse.h>
  6. #include <AnKi/Renderer/Renderer.h>
  7. #include <AnKi/Renderer/DepthDownscale.h>
  8. #include <AnKi/Renderer/GBuffer.h>
  9. #include <AnKi/Renderer/DownscaleBlur.h>
  10. #include <AnKi/Renderer/MotionVectors.h>
  11. #include <AnKi/Renderer/IndirectDiffuseProbes.h>
  12. #include <AnKi/Core/ConfigSet.h>
  13. #include <AnKi/Shaders/Include/IndirectDiffuseTypes.h>
  14. namespace anki {
  15. IndirectDiffuse::~IndirectDiffuse()
  16. {
  17. }
  18. Error IndirectDiffuse::init(const ConfigSet& cfg)
  19. {
  20. const Error err = initInternal(cfg);
  21. if(err)
  22. {
  23. ANKI_R_LOGE("Failed to initialize indirect diffuse pass");
  24. }
  25. return err;
  26. }
  27. Error IndirectDiffuse::initInternal(const ConfigSet& cfg)
  28. {
  29. const UVec2 size = m_r->getInternalResolution() / 2;
  30. ANKI_ASSERT((m_r->getInternalResolution() % 2) == UVec2(0u) && "Needs to be dividable for proper upscaling");
  31. // Init textures
  32. TextureInitInfo texInit = m_r->create2DRenderTargetInitInfo(
  33. size.x(), size.y(), Format::B10G11R11_UFLOAT_PACK32,
  34. TextureUsageBit::IMAGE_COMPUTE_WRITE | TextureUsageBit::ALL_SAMPLED, "IndirectDiffuse #1");
  35. texInit.m_initialUsage = TextureUsageBit::ALL_SAMPLED;
  36. m_rts[0] = m_r->createAndClearRenderTarget(texInit);
  37. texInit.setName("IndirectDiffuse #2");
  38. m_rts[1] = m_r->createAndClearRenderTarget(texInit);
  39. // Init SSGI+probes pass
  40. {
  41. m_main.m_radius = cfg.getNumberF32("r_indirectDiffuseSsgiRadius");
  42. m_main.m_sampleCount = cfg.getNumberU32("r_indirectDiffuseSsgiSamples");
  43. ANKI_CHECK(getResourceManager().loadResource("Shaders/IndirectDiffuse.ankiprog", m_main.m_prog));
  44. const ShaderProgramResourceVariant* variant;
  45. m_main.m_prog->getOrCreateVariant(variant);
  46. m_main.m_grProg = variant->getProgram();
  47. }
  48. // Init denoise
  49. {
  50. m_denoise.m_sampleCount = F32(cfg.getNumberU32("r_indirectDiffuseDenoiseSampleCount"));
  51. m_denoise.m_sampleCount = max(1.0f, std::round(m_denoise.m_sampleCount / 2.0f));
  52. ANKI_CHECK(getResourceManager().loadResource("Shaders/IndirectDiffuseDenoise.ankiprog", m_denoise.m_prog));
  53. ShaderProgramResourceVariantInitInfo variantInit(m_denoise.m_prog);
  54. variantInit.addMutation("BLUR_ORIENTATION", 0);
  55. const ShaderProgramResourceVariant* variant;
  56. m_denoise.m_prog->getOrCreateVariant(variantInit, variant);
  57. m_denoise.m_grProgs[0] = variant->getProgram();
  58. variantInit.addMutation("BLUR_ORIENTATION", 1);
  59. m_denoise.m_prog->getOrCreateVariant(variantInit, variant);
  60. m_denoise.m_grProgs[1] = variant->getProgram();
  61. }
  62. return Error::NONE;
  63. }
  64. void IndirectDiffuse::populateRenderGraph(RenderingContext& ctx)
  65. {
  66. RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
  67. // SSGI+probes
  68. {
  69. // Create RTs
  70. const U32 readRtIdx = m_r->getFrameCount() & 1;
  71. const U32 writeRtIdx = !readRtIdx;
  72. if(ANKI_LIKELY(m_rtsImportedOnce))
  73. {
  74. m_runCtx.m_mainRtHandles[0] = rgraph.importRenderTarget(m_rts[readRtIdx]);
  75. m_runCtx.m_mainRtHandles[1] = rgraph.importRenderTarget(m_rts[writeRtIdx]);
  76. }
  77. else
  78. {
  79. m_runCtx.m_mainRtHandles[0] = rgraph.importRenderTarget(m_rts[readRtIdx], TextureUsageBit::ALL_SAMPLED);
  80. m_runCtx.m_mainRtHandles[1] = rgraph.importRenderTarget(m_rts[writeRtIdx], TextureUsageBit::ALL_SAMPLED);
  81. m_rtsImportedOnce = true;
  82. }
  83. // Create main pass
  84. ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("IndirectDiffuse");
  85. rpass.newDependency(
  86. RenderPassDependency(m_runCtx.m_mainRtHandles[WRITE], TextureUsageBit::IMAGE_COMPUTE_WRITE));
  87. const TextureUsageBit readUsage = TextureUsageBit::SAMPLED_COMPUTE;
  88. m_r->getIndirectDiffuseProbes().setRenderGraphDependencies(ctx, rpass, readUsage);
  89. rpass.newDependency(RenderPassDependency(m_r->getGBuffer().getColorRt(2), readUsage));
  90. TextureSubresourceInfo hizSubresource;
  91. hizSubresource.m_mipmapCount = 1;
  92. rpass.newDependency(RenderPassDependency(m_r->getDepthDownscale().getHiZRt(), readUsage, hizSubresource));
  93. rpass.newDependency(RenderPassDependency(m_r->getDownscaleBlur().getRt(), readUsage));
  94. rpass.newDependency(RenderPassDependency(m_r->getMotionVectors().getMotionVectorsRt(), readUsage));
  95. rpass.newDependency(RenderPassDependency(m_r->getMotionVectors().getRejectionFactorRt(), readUsage));
  96. rpass.newDependency(RenderPassDependency(m_runCtx.m_mainRtHandles[READ], readUsage));
  97. rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
  98. CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
  99. cmdb->bindShaderProgram(m_main.m_grProg);
  100. const ClusteredShadingContext& binning = ctx.m_clusteredShading;
  101. bindUniforms(cmdb, 0, 0, binning.m_clusteredShadingUniformsToken);
  102. m_r->getIndirectDiffuseProbes().bindVolumeTextures(ctx, rgraphCtx, 0, 1);
  103. bindUniforms(cmdb, 0, 2, binning.m_globalIlluminationProbesToken);
  104. bindStorage(cmdb, 0, 3, binning.m_clustersToken);
  105. rgraphCtx.bindImage(0, 4, m_runCtx.m_mainRtHandles[WRITE]);
  106. cmdb->bindSampler(0, 5, m_r->getSamplers().m_trilinearClamp);
  107. rgraphCtx.bindColorTexture(0, 6, m_r->getGBuffer().getColorRt(2));
  108. TextureSubresourceInfo hizSubresource;
  109. hizSubresource.m_mipmapCount = 1;
  110. rgraphCtx.bindTexture(0, 7, m_r->getDepthDownscale().getHiZRt(), hizSubresource);
  111. rgraphCtx.bindColorTexture(0, 8, m_r->getDownscaleBlur().getRt());
  112. rgraphCtx.bindColorTexture(0, 9, m_runCtx.m_mainRtHandles[READ]);
  113. rgraphCtx.bindColorTexture(0, 10, m_r->getMotionVectors().getMotionVectorsRt());
  114. rgraphCtx.bindColorTexture(0, 11, m_r->getMotionVectors().getRejectionFactorRt());
  115. // Bind uniforms
  116. IndirectDiffuseUniforms unis;
  117. unis.m_viewportSize = m_r->getInternalResolution() / 2u;
  118. unis.m_viewportSizef = Vec2(unis.m_viewportSize);
  119. const Mat4& pmat = ctx.m_matrices.m_projection;
  120. unis.m_projectionMat = Vec4(pmat(0, 0), pmat(1, 1), pmat(2, 2), pmat(2, 3));
  121. unis.m_radius = m_main.m_radius;
  122. unis.m_sampleCount = m_main.m_sampleCount;
  123. unis.m_sampleCountf = F32(m_main.m_sampleCount);
  124. unis.m_ssaoBias = m_main.m_ssaoBias;
  125. unis.m_ssaoStrength = m_main.m_ssaoStrength;
  126. cmdb->setPushConstants(&unis, sizeof(unis));
  127. // Dispatch
  128. dispatchPPCompute(cmdb, 8, 8, unis.m_viewportSize.x(), unis.m_viewportSize.y());
  129. });
  130. }
  131. // Denoise
  132. for(U32 dir = 0; dir < 2; ++dir)
  133. {
  134. ComputeRenderPassDescription& rpass =
  135. rgraph.newComputeRenderPass((dir == 0) ? "IndirectDiffuseDenoiseH" : "IndirectDiffuseDenoiseV");
  136. const TextureUsageBit readUsage = TextureUsageBit::SAMPLED_COMPUTE;
  137. const U32 readIdx = (dir == 0) ? WRITE : READ;
  138. rpass.newDependency(RenderPassDependency(m_runCtx.m_mainRtHandles[readIdx], readUsage));
  139. TextureSubresourceInfo hizSubresource;
  140. hizSubresource.m_mipmapCount = 1;
  141. rpass.newDependency(RenderPassDependency(m_r->getDepthDownscale().getHiZRt(), readUsage, hizSubresource));
  142. rpass.newDependency(RenderPassDependency(m_r->getGBuffer().getColorRt(2), readUsage));
  143. rpass.newDependency(
  144. RenderPassDependency(m_runCtx.m_mainRtHandles[!readIdx], TextureUsageBit::IMAGE_COMPUTE_WRITE));
  145. rpass.setWork([this, &ctx, dir, readIdx](RenderPassWorkContext& rgraphCtx) {
  146. CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
  147. cmdb->bindShaderProgram(m_denoise.m_grProgs[dir]);
  148. cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
  149. rgraphCtx.bindColorTexture(0, 1, m_runCtx.m_mainRtHandles[readIdx]);
  150. TextureSubresourceInfo hizSubresource;
  151. hizSubresource.m_mipmapCount = 1;
  152. rgraphCtx.bindTexture(0, 2, m_r->getDepthDownscale().getHiZRt(), hizSubresource);
  153. rgraphCtx.bindColorTexture(0, 3, m_r->getGBuffer().getColorRt(2));
  154. rgraphCtx.bindImage(0, 4, m_runCtx.m_mainRtHandles[!readIdx]);
  155. IndirectDiffuseDenoiseUniforms unis;
  156. unis.m_invertedViewProjectionJitterMat = ctx.m_matrices.m_invertedViewProjectionJitter;
  157. unis.m_viewportSize = m_r->getInternalResolution() / 2u;
  158. unis.m_viewportSizef = Vec2(unis.m_viewportSize);
  159. unis.m_sampleCountDiv2 = m_denoise.m_sampleCount;
  160. cmdb->setPushConstants(&unis, sizeof(unis));
  161. // Dispatch
  162. dispatchPPCompute(cmdb, 8, 8, unis.m_viewportSize.x(), unis.m_viewportSize.y());
  163. });
  164. }
  165. }
  166. } // end namespace anki