MotionVectors.cpp 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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/MotionVectors.h>
  6. #include <AnKi/Renderer/Renderer.h>
  7. #include <AnKi/Renderer/GBuffer.h>
  8. #include <AnKi/Renderer/RenderQueue.h>
  9. namespace anki
  10. {
  11. MotionVectors::~MotionVectors()
  12. {
  13. }
  14. Error MotionVectors::init(const ConfigSet& config)
  15. {
  16. ANKI_R_LOGI("Initializing motion vectors");
  17. // Prog
  18. ANKI_CHECK(getResourceManager().loadResource("Shaders/MotionVectors.ankiprog", m_prog));
  19. ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
  20. variantInitInfo.addConstant("FB_SIZE", UVec2(m_r->getWidth(), m_r->getHeight()));
  21. const ShaderProgramResourceVariant* variant;
  22. m_prog->getOrCreateVariant(variantInitInfo, variant);
  23. m_grProg = variant->getProgram();
  24. // RTs
  25. m_motionVectorsRtDescr = m_r->create2DRenderTargetDescription(m_r->getWidth(), m_r->getHeight(),
  26. Format::R16G16_SFLOAT, "Motion vectors");
  27. m_motionVectorsRtDescr.bake();
  28. m_rejectionFactorRtDescr =
  29. m_r->create2DRenderTargetDescription(m_r->getWidth(), m_r->getHeight(), Format::R8_UNORM, "Motion vectors rej");
  30. m_rejectionFactorRtDescr.bake();
  31. return Error::NONE;
  32. }
  33. void MotionVectors::populateRenderGraph(RenderingContext& ctx)
  34. {
  35. m_runCtx.m_ctx = &ctx;
  36. RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
  37. m_runCtx.m_motionVectorsRtHandle = rgraph.newRenderTarget(m_motionVectorsRtDescr);
  38. m_runCtx.m_rejectionFactorRtHandle = rgraph.newRenderTarget(m_rejectionFactorRtDescr);
  39. ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("Motion vectors");
  40. auto callback = [](RenderPassWorkContext& rgraphCtx) -> void {
  41. static_cast<MotionVectors*>(rgraphCtx.m_userData)->run(rgraphCtx);
  42. };
  43. pass.setWork(callback, this, 0);
  44. pass.newDependency({m_runCtx.m_motionVectorsRtHandle, TextureUsageBit::IMAGE_COMPUTE_WRITE});
  45. pass.newDependency({m_runCtx.m_rejectionFactorRtHandle, TextureUsageBit::IMAGE_COMPUTE_WRITE});
  46. pass.newDependency({m_r->getGBuffer().getColorRt(3), TextureUsageBit::SAMPLED_COMPUTE});
  47. pass.newDependency({m_r->getGBuffer().getDepthRt(), TextureUsageBit::SAMPLED_COMPUTE});
  48. pass.newDependency({m_r->getGBuffer().getPreviousFrameDepthRt(), TextureUsageBit::SAMPLED_COMPUTE});
  49. }
  50. void MotionVectors::run(RenderPassWorkContext& rgraphCtx)
  51. {
  52. RenderingContext& ctx = *m_runCtx.m_ctx;
  53. CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
  54. cmdb->bindShaderProgram(m_grProg);
  55. cmdb->bindSampler(0, 0, m_r->getSamplers().m_nearestNearestClamp);
  56. rgraphCtx.bindTexture(0, 1, m_r->getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
  57. rgraphCtx.bindTexture(0, 2, m_r->getGBuffer().getPreviousFrameDepthRt(),
  58. TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
  59. rgraphCtx.bindColorTexture(0, 3, m_r->getGBuffer().getColorRt(3));
  60. rgraphCtx.bindImage(0, 4, m_runCtx.m_motionVectorsRtHandle, TextureSubresourceInfo());
  61. rgraphCtx.bindImage(0, 5, m_runCtx.m_rejectionFactorRtHandle, TextureSubresourceInfo());
  62. class PC
  63. {
  64. public:
  65. Mat4 m_reprojectionMat;
  66. Mat4 m_prevViewProjectionInvMat;
  67. } pc;
  68. // This reprojection is not enterely correct. It first unprojects the current depth to world space, all fine here.
  69. // Then it projects it to the previous frame but assumes identity jitter. Then it jitters using current frame's
  70. // jitter. The last multiplication I don't get but it works perfectly for sampling the TAA history buffer.
  71. pc.m_reprojectionMat = ctx.m_matrices.m_jitter * ctx.m_prevMatrices.m_viewProjection
  72. * ctx.m_matrices.m_viewProjectionJitter.getInverse();
  73. pc.m_prevViewProjectionInvMat = ctx.m_prevMatrices.m_viewProjectionJitter.getInverse();
  74. cmdb->setPushConstants(&pc, sizeof(pc));
  75. dispatchPPCompute(cmdb, 8, 8, m_r->getWidth(), m_r->getHeight());
  76. }
  77. } // end namespace anki