FinalComposite.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // Copyright (C) 2009-2023, 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/DownscaleBlur.h>
  14. #include <AnKi/Renderer/UiStage.h>
  15. #include <AnKi/Renderer/MotionVectors.h>
  16. #include <AnKi/Util/Logger.h>
  17. #include <AnKi/Util/Tracer.h>
  18. #include <AnKi/Core/ConfigSet.h>
  19. namespace anki {
  20. static NumericCVar<U32> g_motionBlurSamplesCVar(CVarSubsystem::kRenderer, "MotionBlurSamples", 32, 0, 2048, "Max motion blur samples");
  21. static NumericCVar<F32> g_filmGrainStrengthCVar(CVarSubsystem::kRenderer, "FilmGrainStrength", 16.0f, 0.0f, 250.0f, "Film grain strength");
  22. Error FinalComposite::initInternal()
  23. {
  24. ANKI_R_LOGV("Initializing final composite");
  25. ANKI_CHECK(loadColorGradingTextureImage("EngineAssets/DefaultLut.ankitex"));
  26. m_fbDescr.m_colorAttachmentCount = 1;
  27. m_fbDescr.bake();
  28. // Progs
  29. ANKI_CHECK(ResourceManager::getSingleton().loadResource("ShaderBinaries/FinalComposite.ankiprogbin", m_prog));
  30. ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
  31. variantInitInfo.addMutation("FILM_GRAIN", (g_filmGrainStrengthCVar.get() > 0.0) ? 1 : 0);
  32. variantInitInfo.addMutation("BLOOM_ENABLED", 1);
  33. variantInitInfo.addConstant("kLutSize", U32(kLutSize));
  34. variantInitInfo.addConstant("kFramebufferSize", getRenderer().getPostProcessResolution());
  35. variantInitInfo.addConstant("kMotionBlurSamples", g_motionBlurSamplesCVar.get());
  36. for(U32 dbg = 0; dbg < 2; ++dbg)
  37. {
  38. const ShaderProgramResourceVariant* variant;
  39. variantInitInfo.addMutation("DBG_ENABLED", dbg);
  40. m_prog->getOrCreateVariant(variantInitInfo, variant);
  41. m_grProgs[dbg].reset(&variant->getProgram());
  42. }
  43. ANKI_CHECK(ResourceManager::getSingleton().loadResource("ShaderBinaries/VisualizeRenderTarget.ankiprogbin", m_defaultVisualizeRenderTargetProg));
  44. const ShaderProgramResourceVariant* variant;
  45. m_defaultVisualizeRenderTargetProg->getOrCreateVariant(variant);
  46. m_defaultVisualizeRenderTargetGrProg.reset(&variant->getProgram());
  47. return Error::kNone;
  48. }
  49. Error FinalComposite::init()
  50. {
  51. const Error err = initInternal();
  52. if(err)
  53. {
  54. ANKI_R_LOGE("Failed to init final composite");
  55. }
  56. return err;
  57. }
  58. Error FinalComposite::loadColorGradingTextureImage(CString filename)
  59. {
  60. m_lut.reset(nullptr);
  61. ANKI_CHECK(ResourceManager::getSingleton().loadResource(filename, m_lut));
  62. ANKI_ASSERT(m_lut->getWidth() == kLutSize);
  63. ANKI_ASSERT(m_lut->getHeight() == kLutSize);
  64. ANKI_ASSERT(m_lut->getDepth() == kLutSize);
  65. return Error::kNone;
  66. }
  67. void FinalComposite::populateRenderGraph(RenderingContext& ctx)
  68. {
  69. ANKI_TRACE_SCOPED_EVENT(RFinalComposite);
  70. RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
  71. // Create the pass
  72. GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("Final Composite");
  73. pass.setWork(1, [this, &ctx](RenderPassWorkContext& rgraphCtx) {
  74. run(ctx, rgraphCtx);
  75. });
  76. pass.setFramebufferInfo(m_fbDescr, {ctx.m_outRenderTarget});
  77. pass.newTextureDependency(ctx.m_outRenderTarget, TextureUsageBit::kFramebufferWrite);
  78. if(g_dbgCVar.get())
  79. {
  80. pass.newTextureDependency(getRenderer().getDbg().getRt(), TextureUsageBit::kSampledFragment);
  81. }
  82. pass.newTextureDependency(getRenderer().getScale().getTonemappedRt(), TextureUsageBit::kSampledFragment);
  83. pass.newTextureDependency(getRenderer().getBloom().getRt(), TextureUsageBit::kSampledFragment);
  84. pass.newTextureDependency(getRenderer().getMotionVectors().getMotionVectorsRt(), TextureUsageBit::kSampledFragment);
  85. pass.newTextureDependency(getRenderer().getGBuffer().getDepthRt(), TextureUsageBit::kSampledFragment);
  86. Array<RenderTargetHandle, kMaxDebugRenderTargets> dbgRts;
  87. ShaderProgramPtr debugProgram;
  88. const Bool hasDebugRt = getRenderer().getCurrentDebugRenderTarget(dbgRts, debugProgram);
  89. if(hasDebugRt)
  90. {
  91. for(const RenderTargetHandle& handle : dbgRts)
  92. {
  93. if(handle.isValid())
  94. {
  95. pass.newTextureDependency(handle, TextureUsageBit::kSampledFragment);
  96. }
  97. }
  98. }
  99. }
  100. void FinalComposite::run(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
  101. {
  102. ANKI_TRACE_SCOPED_EVENT(RFinalComposite);
  103. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  104. const Bool dbgEnabled = g_dbgCVar.get();
  105. Array<RenderTargetHandle, kMaxDebugRenderTargets> dbgRts;
  106. ShaderProgramPtr optionalDebugProgram;
  107. const Bool hasDebugRt = getRenderer().getCurrentDebugRenderTarget(dbgRts, optionalDebugProgram);
  108. // Bind program
  109. if(hasDebugRt && optionalDebugProgram.isCreated())
  110. {
  111. cmdb.bindShaderProgram(optionalDebugProgram.get());
  112. }
  113. else if(hasDebugRt)
  114. {
  115. cmdb.bindShaderProgram(m_defaultVisualizeRenderTargetGrProg.get());
  116. }
  117. else
  118. {
  119. cmdb.bindShaderProgram(m_grProgs[dbgEnabled].get());
  120. }
  121. // Bind stuff
  122. if(!hasDebugRt)
  123. {
  124. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_nearestNearestClamp.get());
  125. cmdb.bindSampler(0, 1, getRenderer().getSamplers().m_trilinearClamp.get());
  126. cmdb.bindSampler(0, 2, getRenderer().getSamplers().m_trilinearRepeat.get());
  127. rgraphCtx.bindColorTexture(0, 3, getRenderer().getScale().getTonemappedRt());
  128. rgraphCtx.bindColorTexture(0, 4, getRenderer().getBloom().getRt());
  129. cmdb.bindTexture(0, 5, &m_lut->getTextureView());
  130. rgraphCtx.bindColorTexture(0, 6, getRenderer().getMotionVectors().getMotionVectorsRt());
  131. rgraphCtx.bindTexture(0, 7, getRenderer().getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
  132. if(dbgEnabled)
  133. {
  134. rgraphCtx.bindColorTexture(0, 8, getRenderer().getDbg().getRt());
  135. }
  136. const UVec4 pc(0, 0, floatBitsToUint(g_filmGrainStrengthCVar.get()), getRenderer().getFrameCount() & kMaxU32);
  137. cmdb.setPushConstants(&pc, sizeof(pc));
  138. }
  139. else
  140. {
  141. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_nearestNearestClamp.get());
  142. U32 count = 1;
  143. for(const RenderTargetHandle& handle : dbgRts)
  144. {
  145. if(handle.isValid())
  146. {
  147. rgraphCtx.bindColorTexture(0, count++, handle);
  148. }
  149. }
  150. }
  151. cmdb.setViewport(0, 0, getRenderer().getPostProcessResolution().x(), getRenderer().getPostProcessResolution().y());
  152. drawQuad(cmdb);
  153. // Draw UI
  154. getRenderer().getUiStage().draw(getRenderer().getPostProcessResolution().x(), getRenderer().getPostProcessResolution().y(), ctx, cmdb);
  155. }
  156. } // end namespace anki