Ssgi.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. // Copyright (C) 2009-2020, 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/Ssgi.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/core/ConfigSet.h>
  11. #include <anki/shaders/include/SsgiTypes.h>
  12. namespace anki
  13. {
  14. static constexpr U32 WRITE = 0;
  15. static constexpr U32 READ = 1;
  16. Ssgi::~Ssgi()
  17. {
  18. }
  19. Error Ssgi::init(const ConfigSet& cfg)
  20. {
  21. const Error err = initInternal(cfg);
  22. if(err)
  23. {
  24. ANKI_R_LOGE("Failed to initialize SSGI pass");
  25. }
  26. return err;
  27. }
  28. Error Ssgi::initInternal(const ConfigSet& cfg)
  29. {
  30. const U32 width = m_r->getWidth();
  31. const U32 height = m_r->getHeight();
  32. ANKI_ASSERT((width % 2) == 0 && (height % 2) == 0 && "The algorithms won't work");
  33. ANKI_R_LOGI("Initializing SSGI pass");
  34. m_main.m_maxSteps = cfg.getNumberU32("r_ssgiMaxSteps");
  35. m_main.m_depthLod = min(cfg.getNumberU32("r_ssgiDepthLod"), m_r->getDepthDownscale().getMipmapCount() - 1);
  36. m_main.m_firstStepPixels = 32;
  37. ANKI_CHECK(getResourceManager().loadResource("engine_data/BlueNoiseRgb816x16.png", m_main.m_noiseTex));
  38. // Init main
  39. {
  40. m_main.m_rtDescr =
  41. m_r->create2DRenderTargetDescription(width / 2, height / 2, Format::B10G11R11_UFLOAT_PACK32, "SSGI_tmp");
  42. m_main.m_rtDescr.bake();
  43. ANKI_CHECK(getResourceManager().loadResource("shaders/Ssgi.ankiprog", m_main.m_prog));
  44. ShaderProgramResourceVariantInitInfo variantInitInfo(m_main.m_prog);
  45. for(U32 i = 0; i < 4; ++i)
  46. {
  47. variantInitInfo.addMutation("VARIANT", i);
  48. const ShaderProgramResourceVariant* variant;
  49. m_main.m_prog->getOrCreateVariant(variantInitInfo, variant);
  50. m_main.m_grProg[i] = variant->getProgram();
  51. }
  52. }
  53. // Init denoise
  54. {
  55. ANKI_CHECK(getResourceManager().loadResource("shaders/SsgiDenoise.ankiprog", m_denoise.m_prog));
  56. ShaderProgramResourceVariantInitInfo variantInitInfo(m_denoise.m_prog);
  57. const ShaderProgramResourceVariant* variant;
  58. variantInitInfo.addConstant("IN_TEXTURE_SIZE", UVec2(width / 2, height / 2));
  59. for(U32 i = 0; i < 4; ++i)
  60. {
  61. variantInitInfo.addMutation("VARIANT", i);
  62. variantInitInfo.addMutation("SAMPLE_COUNT", 11);
  63. variantInitInfo.addMutation("ORIENTATION", 0);
  64. m_denoise.m_prog->getOrCreateVariant(variantInitInfo, variant);
  65. m_denoise.m_grProg[0][i] = variant->getProgram();
  66. variantInitInfo.addMutation("SAMPLE_COUNT", 15);
  67. variantInitInfo.addMutation("ORIENTATION", 1);
  68. m_denoise.m_prog->getOrCreateVariant(variantInitInfo, variant);
  69. m_denoise.m_grProg[1][i] = variant->getProgram();
  70. }
  71. }
  72. // Init reconstruction
  73. {
  74. ANKI_CHECK(getResourceManager().loadResource("shaders/SsgiReconstruct.ankiprog", m_recontruction.m_prog));
  75. ShaderProgramResourceVariantInitInfo variantInitInfo(m_recontruction.m_prog);
  76. variantInitInfo.addConstant("FB_SIZE", UVec2(m_r->getWidth(), m_r->getHeight()));
  77. const ShaderProgramResourceVariant* variant;
  78. for(U32 i = 0; i < 4; ++i)
  79. {
  80. variantInitInfo.addMutation("VARIANT", i);
  81. m_recontruction.m_prog->getOrCreateVariant(variantInitInfo, variant);
  82. m_recontruction.m_grProg[i] = variant->getProgram();
  83. }
  84. TextureInitInfo initInfo = m_r->create2DRenderTargetInitInfo(
  85. width, height, Format::B10G11R11_UFLOAT_PACK32,
  86. TextureUsageBit::ALL_SAMPLED | TextureUsageBit::IMAGE_COMPUTE_WRITE, "SSGI");
  87. initInfo.m_initialUsage = TextureUsageBit::SAMPLED_FRAGMENT;
  88. m_recontruction.m_rt = m_r->createAndClearRenderTarget(initInfo);
  89. }
  90. return Error::NONE;
  91. }
  92. void Ssgi::populateRenderGraph(RenderingContext& ctx)
  93. {
  94. RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
  95. m_runCtx.m_ctx = &ctx;
  96. // Main pass
  97. {
  98. // Create RTs
  99. if(ANKI_LIKELY(m_recontruction.m_rtImportedOnce))
  100. {
  101. m_runCtx.m_finalRt = rgraph.importRenderTarget(m_recontruction.m_rt);
  102. }
  103. else
  104. {
  105. m_runCtx.m_finalRt = rgraph.importRenderTarget(m_recontruction.m_rt, TextureUsageBit::SAMPLED_FRAGMENT);
  106. m_recontruction.m_rtImportedOnce = true;
  107. }
  108. m_runCtx.m_intermediateRts[WRITE] = rgraph.newRenderTarget(m_main.m_rtDescr);
  109. m_runCtx.m_intermediateRts[READ] = rgraph.newRenderTarget(m_main.m_rtDescr);
  110. // Create pass
  111. ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("SSGI");
  112. rpass.setWork(
  113. [](RenderPassWorkContext& rgraphCtx) { static_cast<Ssgi*>(rgraphCtx.m_userData)->run(rgraphCtx); }, this,
  114. 0);
  115. rpass.newDependency({m_runCtx.m_intermediateRts[WRITE], TextureUsageBit::IMAGE_COMPUTE_WRITE});
  116. rpass.newDependency({m_runCtx.m_finalRt, TextureUsageBit::SAMPLED_COMPUTE});
  117. TextureSubresourceInfo hizSubresource;
  118. hizSubresource.m_firstMipmap = m_main.m_depthLod;
  119. rpass.newDependency({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_COMPUTE, hizSubresource});
  120. rpass.newDependency({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_COMPUTE});
  121. rpass.newDependency({m_r->getDownscaleBlur().getRt(), TextureUsageBit::SAMPLED_COMPUTE});
  122. }
  123. // Blur vertical
  124. {
  125. ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("SSGI_blur_v");
  126. rpass.newDependency({m_runCtx.m_intermediateRts[WRITE], TextureUsageBit::SAMPLED_COMPUTE});
  127. rpass.newDependency({m_runCtx.m_intermediateRts[READ], TextureUsageBit::IMAGE_COMPUTE_WRITE});
  128. rpass.newDependency({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_COMPUTE});
  129. rpass.newDependency({m_r->getGBuffer().getDepthRt(), TextureUsageBit::SAMPLED_COMPUTE});
  130. rpass.setWork(
  131. [](RenderPassWorkContext& rgraphCtx) { static_cast<Ssgi*>(rgraphCtx.m_userData)->runVBlur(rgraphCtx); },
  132. this, 0);
  133. }
  134. // Blur horizontal
  135. {
  136. ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("SSGI_blur_h");
  137. rpass.newDependency({m_runCtx.m_intermediateRts[READ], TextureUsageBit::SAMPLED_COMPUTE});
  138. rpass.newDependency({m_runCtx.m_intermediateRts[WRITE], TextureUsageBit::IMAGE_COMPUTE_WRITE});
  139. rpass.newDependency({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_COMPUTE});
  140. rpass.newDependency({m_r->getGBuffer().getDepthRt(), TextureUsageBit::SAMPLED_COMPUTE});
  141. rpass.setWork(
  142. [](RenderPassWorkContext& rgraphCtx) { static_cast<Ssgi*>(rgraphCtx.m_userData)->runHBlur(rgraphCtx); },
  143. this, 0);
  144. }
  145. // Reconstruction
  146. {
  147. ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("SSGI_recon");
  148. rpass.newDependency({m_runCtx.m_intermediateRts[WRITE], TextureUsageBit::SAMPLED_COMPUTE});
  149. rpass.newDependency({m_runCtx.m_finalRt, TextureUsageBit::IMAGE_COMPUTE_WRITE});
  150. rpass.newDependency({m_r->getGBuffer().getDepthRt(), TextureUsageBit::SAMPLED_COMPUTE});
  151. rpass.newDependency({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_COMPUTE});
  152. rpass.setWork(
  153. [](RenderPassWorkContext& rgraphCtx) {
  154. static_cast<Ssgi*>(rgraphCtx.m_userData)->runRecontruct(rgraphCtx);
  155. },
  156. this, 0);
  157. }
  158. }
  159. void Ssgi::run(RenderPassWorkContext& rgraphCtx)
  160. {
  161. RenderingContext& ctx = *m_runCtx.m_ctx;
  162. CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
  163. cmdb->bindShaderProgram(m_main.m_grProg[m_r->getFrameCount() % 4]);
  164. rgraphCtx.bindImage(0, 0, m_runCtx.m_intermediateRts[WRITE], TextureSubresourceInfo());
  165. // Bind uniforms
  166. SsgiUniforms* unis = allocateAndBindUniforms<SsgiUniforms*>(sizeof(SsgiUniforms), cmdb, 0, 1);
  167. unis->m_depthBufferSize = UVec2(m_r->getWidth(), m_r->getHeight()) >> (m_main.m_depthLod + 1);
  168. unis->m_framebufferSize = UVec2(m_r->getWidth(), m_r->getHeight());
  169. unis->m_invProjMat = ctx.m_matrices.m_projectionJitter.getInverse();
  170. unis->m_projMat = ctx.m_matrices.m_projectionJitter;
  171. unis->m_prevViewProjMatMulInvViewProjMat =
  172. ctx.m_prevMatrices.m_viewProjection * ctx.m_matrices.m_viewProjectionJitter.getInverse();
  173. unis->m_normalMat = Mat3x4(Vec3(0.0f), ctx.m_matrices.m_view.getRotationPart());
  174. unis->m_frameCount = m_r->getFrameCount() & MAX_U32;
  175. unis->m_maxSteps = m_main.m_maxSteps;
  176. unis->m_firstStepPixels = m_main.m_firstStepPixels;
  177. cmdb->bindSampler(0, 2, m_r->getSamplers().m_trilinearClamp);
  178. rgraphCtx.bindColorTexture(0, 3, m_r->getGBuffer().getColorRt(2));
  179. TextureSubresourceInfo hizSubresource;
  180. hizSubresource.m_firstMipmap = m_main.m_depthLod;
  181. rgraphCtx.bindTexture(0, 4, m_r->getDepthDownscale().getHiZRt(), hizSubresource);
  182. rgraphCtx.bindColorTexture(0, 5, m_r->getDownscaleBlur().getRt());
  183. rgraphCtx.bindColorTexture(0, 6, m_runCtx.m_finalRt);
  184. // Dispatch
  185. dispatchPPCompute(cmdb, 16, 16, m_r->getWidth() / 2, m_r->getHeight() / 2);
  186. }
  187. void Ssgi::runVBlur(RenderPassWorkContext& rgraphCtx)
  188. {
  189. CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
  190. cmdb->bindShaderProgram(m_denoise.m_grProg[0][m_r->getFrameCount() % 4]);
  191. cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
  192. rgraphCtx.bindColorTexture(0, 1, m_runCtx.m_intermediateRts[WRITE]);
  193. rgraphCtx.bindTexture(0, 2, m_r->getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
  194. rgraphCtx.bindColorTexture(0, 3, m_r->getGBuffer().getColorRt(2));
  195. rgraphCtx.bindImage(0, 4, m_runCtx.m_intermediateRts[READ], TextureSubresourceInfo());
  196. const Mat4 mat = m_runCtx.m_ctx->m_matrices.m_viewProjectionJitter.getInverse();
  197. cmdb->setPushConstants(&mat, sizeof(mat));
  198. dispatchPPCompute(cmdb, 8, 8, m_r->getWidth() / 2, m_r->getHeight() / 2);
  199. }
  200. void Ssgi::runHBlur(RenderPassWorkContext& rgraphCtx)
  201. {
  202. CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
  203. cmdb->bindShaderProgram(m_denoise.m_grProg[1][m_r->getFrameCount() % 4]);
  204. cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
  205. rgraphCtx.bindColorTexture(0, 1, m_runCtx.m_intermediateRts[READ]);
  206. rgraphCtx.bindTexture(0, 2, m_r->getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
  207. rgraphCtx.bindColorTexture(0, 3, m_r->getGBuffer().getColorRt(2));
  208. rgraphCtx.bindImage(0, 4, m_runCtx.m_intermediateRts[WRITE], TextureSubresourceInfo());
  209. const Mat4 mat = m_runCtx.m_ctx->m_matrices.m_viewProjectionJitter.getInverse();
  210. cmdb->setPushConstants(&mat, sizeof(mat));
  211. dispatchPPCompute(cmdb, 8, 8, m_r->getWidth() / 2, m_r->getHeight() / 2);
  212. }
  213. void Ssgi::runRecontruct(RenderPassWorkContext& rgraphCtx)
  214. {
  215. CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
  216. cmdb->bindShaderProgram(m_recontruction.m_grProg[m_r->getFrameCount() % 4]);
  217. cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
  218. rgraphCtx.bindColorTexture(0, 1, m_runCtx.m_intermediateRts[WRITE]);
  219. rgraphCtx.bindTexture(0, 2, m_r->getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
  220. rgraphCtx.bindImage(0, 3, m_runCtx.m_finalRt, TextureSubresourceInfo());
  221. dispatchPPCompute(cmdb, 16, 16, m_r->getWidth(), m_r->getHeight());
  222. }
  223. } // end namespace anki