TemporalAA.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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/TemporalAA.h>
  6. #include <AnKi/Renderer/Renderer.h>
  7. #include <AnKi/Renderer/GBuffer.h>
  8. #include <AnKi/Renderer/LightShading.h>
  9. #include <AnKi/Renderer/Tonemapping.h>
  10. #include <AnKi/Renderer/MotionVectors.h>
  11. namespace anki
  12. {
  13. TemporalAA::TemporalAA(Renderer* r)
  14. : RendererObject(r)
  15. {
  16. }
  17. TemporalAA::~TemporalAA()
  18. {
  19. }
  20. Error TemporalAA::init(const ConfigSet& config)
  21. {
  22. ANKI_R_LOGI("Initializing TAA");
  23. Error err = initInternal(config);
  24. if(err)
  25. {
  26. ANKI_R_LOGE("Failed to init TAA");
  27. }
  28. return Error::NONE;
  29. }
  30. Error TemporalAA::initInternal(const ConfigSet& config)
  31. {
  32. ANKI_CHECK(m_r->getResourceManager().loadResource("Shaders/TemporalAAResolve.ankiprog", m_prog));
  33. for(U32 i = 0; i < 2; ++i)
  34. {
  35. ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
  36. variantInitInfo.addConstant("VARIANCE_CLIPPING_GAMMA", 2.7f);
  37. variantInitInfo.addConstant("BLEND_FACTOR", 1.0f / 16.0f);
  38. variantInitInfo.addConstant("FB_SIZE", UVec2(m_r->getWidth(), m_r->getHeight()));
  39. variantInitInfo.addMutation("SHARPEN", i + 1);
  40. variantInitInfo.addMutation("VARIANCE_CLIPPING", 1);
  41. variantInitInfo.addMutation("TONEMAP_FIX", 1);
  42. variantInitInfo.addMutation("YCBCR", 0);
  43. const ShaderProgramResourceVariant* variant;
  44. m_prog->getOrCreateVariant(variantInitInfo, variant);
  45. m_grProgs[i] = variant->getProgram();
  46. }
  47. for(U i = 0; i < 2; ++i)
  48. {
  49. TextureInitInfo texinit = m_r->create2DRenderTargetInitInfo(
  50. m_r->getWidth(), m_r->getHeight(), LIGHT_SHADING_COLOR_ATTACHMENT_PIXEL_FORMAT,
  51. TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::SAMPLED_COMPUTE | TextureUsageBit::IMAGE_COMPUTE_WRITE,
  52. "TemporalAA");
  53. texinit.m_initialUsage = TextureUsageBit::SAMPLED_FRAGMENT;
  54. m_rtTextures[i] = m_r->createAndClearRenderTarget(texinit);
  55. }
  56. return Error::NONE;
  57. }
  58. void TemporalAA::run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
  59. {
  60. CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
  61. cmdb->bindShaderProgram(m_grProgs[m_r->getFrameCount() & 1]);
  62. cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
  63. rgraphCtx.bindTexture(0, 1, m_r->getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
  64. rgraphCtx.bindColorTexture(0, 2, m_r->getLightShading().getRt());
  65. rgraphCtx.bindColorTexture(0, 3, m_runCtx.m_historyRt);
  66. rgraphCtx.bindColorTexture(0, 4, m_r->getMotionVectors().getMotionVectorsRt());
  67. rgraphCtx.bindImage(0, 5, m_runCtx.m_renderRt, TextureSubresourceInfo());
  68. rgraphCtx.bindUniformBuffer(0, 6, m_r->getTonemapping().getAverageLuminanceBuffer());
  69. dispatchPPCompute(cmdb, 8, 8, m_r->getWidth(), m_r->getHeight());
  70. }
  71. void TemporalAA::populateRenderGraph(RenderingContext& ctx)
  72. {
  73. m_runCtx.m_ctx = &ctx;
  74. RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
  75. const U32 historyRtIdx = (m_r->getFrameCount() + 1) & 1;
  76. const U32 renderRtIdx = !historyRtIdx;
  77. // Import RTs
  78. if(ANKI_LIKELY(m_rtTexturesImportedOnce[historyRtIdx]))
  79. {
  80. m_runCtx.m_historyRt = rgraph.importRenderTarget(m_rtTextures[historyRtIdx]);
  81. }
  82. else
  83. {
  84. m_runCtx.m_historyRt = rgraph.importRenderTarget(m_rtTextures[historyRtIdx], TextureUsageBit::SAMPLED_FRAGMENT);
  85. m_rtTexturesImportedOnce[historyRtIdx] = true;
  86. }
  87. m_runCtx.m_renderRt = rgraph.importRenderTarget(m_rtTextures[renderRtIdx], TextureUsageBit::NONE);
  88. // Create pass
  89. ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("TemporalAA");
  90. pass.setWork(
  91. [](RenderPassWorkContext& rgraphCtx) {
  92. TemporalAA* const self = static_cast<TemporalAA*>(rgraphCtx.m_userData);
  93. self->run(*self->m_runCtx.m_ctx, rgraphCtx);
  94. },
  95. this, 0);
  96. pass.newDependency({m_runCtx.m_renderRt, TextureUsageBit::IMAGE_COMPUTE_WRITE});
  97. pass.newDependency({m_r->getGBuffer().getDepthRt(), TextureUsageBit::SAMPLED_COMPUTE,
  98. TextureSubresourceInfo(DepthStencilAspectBit::DEPTH)});
  99. pass.newDependency({m_r->getLightShading().getRt(), TextureUsageBit::SAMPLED_COMPUTE});
  100. pass.newDependency({m_runCtx.m_historyRt, TextureUsageBit::SAMPLED_COMPUTE});
  101. pass.newDependency({m_r->getMotionVectors().getMotionVectorsRt(), TextureUsageBit::SAMPLED_COMPUTE});
  102. }
  103. } // end namespace anki