FinalComposite.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // Copyright (C) 2009-present, 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/FinalComposite.h>
  6. #include <AnKi/Renderer/Renderer.h>
  7. #include <AnKi/Renderer/Bloom.h>
  8. #include <AnKi/Renderer/Scale.h>
  9. #include <AnKi/Renderer/Tonemapping.h>
  10. #include <AnKi/Renderer/LightShading.h>
  11. #include <AnKi/Renderer/GBuffer.h>
  12. #include <AnKi/Renderer/Dbg.h>
  13. #include <AnKi/Renderer/UiStage.h>
  14. #include <AnKi/Renderer/MotionVectors.h>
  15. #include <AnKi/Util/Logger.h>
  16. #include <AnKi/Util/Tracer.h>
  17. #include <AnKi/Util/CVarSet.h>
  18. namespace anki {
  19. Error FinalComposite::initInternal()
  20. {
  21. ANKI_R_LOGV("Initializing final composite");
  22. ANKI_CHECK(loadColorGradingTextureImage("EngineAssets/DefaultLut.ankitex"));
  23. // Progs
  24. for(MutatorValue dbg = 0; dbg < 2; ++dbg)
  25. {
  26. ANKI_CHECK(loadShaderProgram("ShaderBinaries/FinalComposite.ankiprogbin",
  27. {{"FILM_GRAIN", (g_filmGrainStrengthCVar > 0.0) ? 1 : 0}, {"BLOOM_ENABLED", 1}, {"DBG_ENABLED", dbg}}, m_prog,
  28. m_grProgs[dbg]));
  29. }
  30. ANKI_CHECK(loadShaderProgram("ShaderBinaries/VisualizeRenderTarget.ankiprogbin", m_defaultVisualizeRenderTargetProg,
  31. m_defaultVisualizeRenderTargetGrProg));
  32. if(getRenderer().getSwapchainResolution() != getRenderer().getPostProcessResolution())
  33. {
  34. m_rtDesc = getRenderer().create2DRenderTargetDescription(
  35. getRenderer().getPostProcessResolution().x(), getRenderer().getPostProcessResolution().y(),
  36. (GrManager::getSingleton().getDeviceCapabilities().m_unalignedBbpTextureFormats) ? Format::kR8G8B8_Unorm : Format::kR8G8B8A8_Unorm,
  37. "Final Composite");
  38. m_rtDesc.bake();
  39. }
  40. return Error::kNone;
  41. }
  42. Error FinalComposite::init()
  43. {
  44. const Error err = initInternal();
  45. if(err)
  46. {
  47. ANKI_R_LOGE("Failed to init final composite");
  48. }
  49. return err;
  50. }
  51. Error FinalComposite::loadColorGradingTextureImage(CString filename)
  52. {
  53. m_lut.reset(nullptr);
  54. ANKI_CHECK(ResourceManager::getSingleton().loadResource(filename, m_lut));
  55. ANKI_ASSERT(m_lut->getWidth() == m_lut->getHeight());
  56. ANKI_ASSERT(m_lut->getWidth() == m_lut->getDepth());
  57. return Error::kNone;
  58. }
  59. void FinalComposite::populateRenderGraph(RenderingContext& ctx)
  60. {
  61. ANKI_TRACE_SCOPED_EVENT(RFinalComposite);
  62. RenderGraphBuilder& rgraph = ctx.m_renderGraphDescr;
  63. // Create the pass
  64. GraphicsRenderPass& pass = rgraph.newGraphicsRenderPass("Final Composite");
  65. const Bool bRendersToSwapchain = getRenderer().getSwapchainResolution() == getRenderer().getPostProcessResolution();
  66. const RenderTargetHandle outRt = (!bRendersToSwapchain) ? rgraph.newRenderTarget(m_rtDesc) : ctx.m_swapchainRenderTarget;
  67. if(!bRendersToSwapchain)
  68. {
  69. m_runCtx.m_rt = outRt;
  70. }
  71. pass.setRenderpassInfo({GraphicsRenderPassTargetDesc(outRt)});
  72. pass.newTextureDependency(outRt, TextureUsageBit::kRtvDsvWrite);
  73. if(g_dbgCVar)
  74. {
  75. pass.newTextureDependency(getRenderer().getDbg().getRt(), TextureUsageBit::kSrvPixel);
  76. }
  77. pass.newTextureDependency(getRenderer().getScale().getTonemappedRt(), TextureUsageBit::kSrvPixel);
  78. pass.newTextureDependency(getRenderer().getBloom().getBloomRt(), TextureUsageBit::kSrvPixel);
  79. pass.newTextureDependency(getRenderer().getMotionVectors().getMotionVectorsRt(), TextureUsageBit::kSrvPixel);
  80. pass.newTextureDependency(getRenderer().getGBuffer().getDepthRt(), TextureUsageBit::kSrvPixel);
  81. Array<RenderTargetHandle, kMaxDebugRenderTargets> dbgRts;
  82. ShaderProgramPtr debugProgram;
  83. const Bool hasDebugRt = getRenderer().getCurrentDebugRenderTarget(dbgRts, debugProgram);
  84. if(hasDebugRt)
  85. {
  86. for(const RenderTargetHandle& handle : dbgRts)
  87. {
  88. if(handle.isValid())
  89. {
  90. pass.newTextureDependency(handle, TextureUsageBit::kSrvPixel);
  91. }
  92. }
  93. }
  94. pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
  95. ANKI_TRACE_SCOPED_EVENT(FinalComposite);
  96. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  97. const Bool dbgEnabled = g_dbgCVar;
  98. Array<RenderTargetHandle, kMaxDebugRenderTargets> dbgRts;
  99. ShaderProgramPtr optionalDebugProgram;
  100. const Bool hasDebugRt = getRenderer().getCurrentDebugRenderTarget(dbgRts, optionalDebugProgram);
  101. // Bind program
  102. if(hasDebugRt && optionalDebugProgram.isCreated())
  103. {
  104. cmdb.bindShaderProgram(optionalDebugProgram.get());
  105. }
  106. else if(hasDebugRt)
  107. {
  108. cmdb.bindShaderProgram(m_defaultVisualizeRenderTargetGrProg.get());
  109. }
  110. else
  111. {
  112. cmdb.bindShaderProgram(m_grProgs[dbgEnabled].get());
  113. }
  114. // Bind stuff
  115. if(!hasDebugRt)
  116. {
  117. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_nearestNearestClamp.get());
  118. cmdb.bindSampler(1, 0, getRenderer().getSamplers().m_trilinearClamp.get());
  119. cmdb.bindSampler(2, 0, getRenderer().getSamplers().m_trilinearRepeat.get());
  120. rgraphCtx.bindSrv(0, 0, getRenderer().getScale().getTonemappedRt());
  121. rgraphCtx.bindSrv(1, 0, getRenderer().getBloom().getBloomRt());
  122. cmdb.bindSrv(2, 0, TextureView(&m_lut->getTexture(), TextureSubresourceDesc::all()));
  123. rgraphCtx.bindSrv(3, 0, getRenderer().getMotionVectors().getMotionVectorsRt());
  124. rgraphCtx.bindSrv(4, 0, getRenderer().getGBuffer().getDepthRt());
  125. if(dbgEnabled)
  126. {
  127. rgraphCtx.bindSrv(5, 0, getRenderer().getDbg().getRt());
  128. }
  129. const UVec4 pc(g_motionBlurSamplesCVar, floatBitsToUint(g_filmGrainStrengthCVar), getRenderer().getFrameCount() & kMaxU32, 0);
  130. cmdb.setFastConstants(&pc, sizeof(pc));
  131. }
  132. else
  133. {
  134. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_nearestNearestClamp.get());
  135. U32 count = 0;
  136. for(const RenderTargetHandle& handle : dbgRts)
  137. {
  138. if(handle.isValid())
  139. {
  140. rgraphCtx.bindSrv(count++, 0, handle);
  141. }
  142. }
  143. }
  144. cmdb.setViewport(0, 0, getRenderer().getPostProcessResolution().x(), getRenderer().getPostProcessResolution().y());
  145. drawQuad(cmdb);
  146. // Draw UI
  147. const Bool bRendersToSwapchain = getRenderer().getSwapchainResolution() == getRenderer().getPostProcessResolution();
  148. if(bRendersToSwapchain)
  149. {
  150. getRenderer().getUiStage().draw(getRenderer().getPostProcessResolution().x(), getRenderer().getPostProcessResolution().y(), cmdb);
  151. }
  152. });
  153. }
  154. } // end namespace anki