TemporalAA.cpp 4.2 KB

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