LightShading.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  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/LightShading.h>
  6. #include <anki/renderer/Renderer.h>
  7. #include <anki/renderer/ShadowMapping.h>
  8. #include <anki/renderer/ProbeReflections.h>
  9. #include <anki/renderer/GBuffer.h>
  10. #include <anki/renderer/RenderQueue.h>
  11. #include <anki/renderer/ForwardShading.h>
  12. #include <anki/renderer/VolumetricFog.h>
  13. #include <anki/renderer/DepthDownscale.h>
  14. #include <anki/renderer/Ssao.h>
  15. #include <anki/renderer/Ssr.h>
  16. #include <anki/renderer/Ssgi.h>
  17. #include <anki/renderer/GlobalIllumination.h>
  18. #include <anki/renderer/ShadowmapsResolve.h>
  19. #include <anki/core/ConfigSet.h>
  20. #include <anki/util/HighRezTimer.h>
  21. namespace anki
  22. {
  23. LightShading::LightShading(Renderer* r)
  24. : RendererObject(r)
  25. {
  26. }
  27. LightShading::~LightShading()
  28. {
  29. }
  30. Error LightShading::init(const ConfigSet& config)
  31. {
  32. ANKI_R_LOGI("Initializing light stage");
  33. Error err = initLightShading(config);
  34. if(!err)
  35. {
  36. err = initApplyFog(config);
  37. }
  38. if(err)
  39. {
  40. ANKI_R_LOGE("Failed to init light stage");
  41. }
  42. return err;
  43. }
  44. Error LightShading::initLightShading(const ConfigSet& config)
  45. {
  46. // Load shaders and programs
  47. ANKI_CHECK(getResourceManager().loadResource("shaders/LightShading.ankiprog", m_lightShading.m_prog));
  48. ShaderProgramResourceVariantInitInfo variantInitInfo(m_lightShading.m_prog);
  49. variantInitInfo.addConstant("CLUSTER_COUNT_X", U32(m_r->getClusterCount()[0]));
  50. variantInitInfo.addConstant("CLUSTER_COUNT_Y", U32(m_r->getClusterCount()[1]));
  51. variantInitInfo.addConstant("CLUSTER_COUNT_Z", U32(m_r->getClusterCount()[2]));
  52. variantInitInfo.addConstant("CLUSTER_COUNT", U32(m_r->getClusterCount()[3]));
  53. variantInitInfo.addConstant("IR_MIPMAP_COUNT", U32(m_r->getProbeReflections().getReflectionTextureMipmapCount()));
  54. const ShaderProgramResourceVariant* variant;
  55. m_lightShading.m_prog->getOrCreateVariant(variantInitInfo, variant);
  56. m_lightShading.m_grProg = variant->getProgram();
  57. // Create RT descr
  58. m_lightShading.m_rtDescr = m_r->create2DRenderTargetDescription(
  59. m_r->getWidth(), m_r->getHeight(), LIGHT_SHADING_COLOR_ATTACHMENT_PIXEL_FORMAT, "Light Shading");
  60. m_lightShading.m_rtDescr.bake();
  61. // Create FB descr
  62. m_lightShading.m_fbDescr.m_colorAttachmentCount = 1;
  63. m_lightShading.m_fbDescr.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::DONT_CARE;
  64. m_lightShading.m_fbDescr.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::LOAD;
  65. m_lightShading.m_fbDescr.m_depthStencilAttachment.m_stencilLoadOperation = AttachmentLoadOperation::DONT_CARE;
  66. m_lightShading.m_fbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::DEPTH;
  67. m_lightShading.m_fbDescr.bake();
  68. return Error::NONE;
  69. }
  70. Error LightShading::initApplyFog(const ConfigSet& config)
  71. {
  72. // Load shaders and programs
  73. ANKI_CHECK(getResourceManager().loadResource("shaders/LightShadingApplyFog.ankiprog", m_applyFog.m_prog));
  74. ShaderProgramResourceVariantInitInfo variantInitInfo(m_applyFog.m_prog);
  75. variantInitInfo.addConstant("FOG_LAST_CLASTER", m_r->getVolumetricFog().getFinalClusterInZ());
  76. const ShaderProgramResourceVariant* variant;
  77. m_applyFog.m_prog->getOrCreateVariant(variantInitInfo, variant);
  78. m_applyFog.m_grProg = variant->getProgram();
  79. return Error::NONE;
  80. }
  81. void LightShading::run(RenderPassWorkContext& rgraphCtx)
  82. {
  83. const RenderingContext& ctx = *m_runCtx.m_ctx;
  84. CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
  85. const ClusterBinOut& rsrc = ctx.m_clusterBinOut;
  86. cmdb->setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
  87. // Do light shading first
  88. if(rgraphCtx.m_currentSecondLevelCommandBufferIndex == 0)
  89. {
  90. cmdb->bindShaderProgram(m_lightShading.m_grProg);
  91. cmdb->setDepthWrite(false);
  92. // Bind all
  93. bindUniforms(cmdb, 0, 0, ctx.m_lightShadingUniformsToken);
  94. bindUniforms(cmdb, 0, 1, rsrc.m_pointLightsToken);
  95. bindUniforms(cmdb, 0, 2, rsrc.m_spotLightsToken);
  96. rgraphCtx.bindColorTexture(0, 3, m_r->getShadowMapping().getShadowmapRt());
  97. bindUniforms(cmdb, 0, 4, rsrc.m_reflectionProbesToken);
  98. rgraphCtx.bindColorTexture(0, 5, m_r->getProbeReflections().getReflectionRt());
  99. cmdb->bindTexture(0, 6, m_r->getProbeReflections().getIntegrationLut(), TextureUsageBit::SAMPLED_FRAGMENT);
  100. m_r->getGlobalIllumination().bindVolumeTextures(ctx, rgraphCtx, 0, 7);
  101. bindUniforms(cmdb, 0, 8, rsrc.m_globalIlluminationProbesToken);
  102. bindStorage(cmdb, 0, 9, rsrc.m_clustersToken);
  103. bindStorage(cmdb, 0, 10, rsrc.m_indicesToken);
  104. cmdb->bindSampler(0, 11, m_r->getSamplers().m_nearestNearestClamp);
  105. cmdb->bindSampler(0, 12, m_r->getSamplers().m_trilinearClamp);
  106. rgraphCtx.bindColorTexture(0, 13, m_r->getGBuffer().getColorRt(0));
  107. rgraphCtx.bindColorTexture(0, 14, m_r->getGBuffer().getColorRt(1));
  108. rgraphCtx.bindColorTexture(0, 15, m_r->getGBuffer().getColorRt(2));
  109. rgraphCtx.bindTexture(0, 16, m_r->getGBuffer().getDepthRt(),
  110. TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
  111. rgraphCtx.bindColorTexture(0, 17, m_r->getSsr().getRt());
  112. rgraphCtx.bindColorTexture(0, 18, m_r->getSsao().getRt());
  113. rgraphCtx.bindColorTexture(0, 19, m_r->getSsgi().getRt());
  114. rgraphCtx.bindColorTexture(0, 20, m_r->getShadowmapsResolve().getRt());
  115. // Draw
  116. drawQuad(cmdb);
  117. }
  118. // Do the fog apply
  119. if(rgraphCtx.m_currentSecondLevelCommandBufferIndex == rgraphCtx.m_secondLevelCommandBufferCount - 1u)
  120. {
  121. cmdb->bindShaderProgram(m_applyFog.m_grProg);
  122. // Bind all
  123. cmdb->bindSampler(0, 0, m_r->getSamplers().m_nearestNearestClamp);
  124. cmdb->bindSampler(0, 1, m_r->getSamplers().m_trilinearClamp);
  125. rgraphCtx.bindTexture(0, 2, m_r->getGBuffer().getDepthRt(),
  126. TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
  127. rgraphCtx.bindColorTexture(0, 3, m_r->getVolumetricFog().getRt());
  128. struct PushConsts
  129. {
  130. ClustererMagicValues m_clustererMagic;
  131. Mat4 m_invViewProjMat;
  132. } regs;
  133. regs.m_clustererMagic = ctx.m_clusterBinOut.m_shaderMagicValues;
  134. regs.m_invViewProjMat = ctx.m_matrices.m_viewProjectionJitter.getInverse();
  135. cmdb->setPushConstants(&regs, sizeof(regs));
  136. // finalPixelColor = pixelWithoutFog * transmitance + inScattering (see the shader)
  137. cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::SRC_ALPHA);
  138. drawQuad(cmdb);
  139. // Reset state
  140. cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ZERO);
  141. }
  142. // Forward shading last
  143. m_r->getForwardShading().run(ctx, rgraphCtx);
  144. }
  145. void LightShading::populateRenderGraph(RenderingContext& ctx)
  146. {
  147. m_runCtx.m_ctx = &ctx;
  148. RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
  149. // Create RT
  150. m_runCtx.m_rt = rgraph.newRenderTarget(m_lightShading.m_rtDescr);
  151. // Create pass
  152. GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("Light&FW Shad.");
  153. pass.setWork(
  154. [](RenderPassWorkContext& rgraphCtx) { static_cast<LightShading*>(rgraphCtx.m_userData)->run(rgraphCtx); },
  155. this, computeNumberOfSecondLevelCommandBuffers(ctx.m_renderQueue->m_forwardShadingRenderables.getSize()));
  156. pass.setFramebufferInfo(m_lightShading.m_fbDescr, {{m_runCtx.m_rt}}, {m_r->getGBuffer().getDepthRt()});
  157. // Light shading
  158. pass.newDependency({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
  159. pass.newDependency({m_r->getGBuffer().getColorRt(0), TextureUsageBit::SAMPLED_FRAGMENT});
  160. pass.newDependency({m_r->getGBuffer().getColorRt(1), TextureUsageBit::SAMPLED_FRAGMENT});
  161. pass.newDependency({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_FRAGMENT});
  162. pass.newDependency({m_r->getGBuffer().getDepthRt(),
  163. TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ,
  164. TextureSubresourceInfo(DepthStencilAspectBit::DEPTH)});
  165. pass.newDependency({m_r->getShadowMapping().getShadowmapRt(), TextureUsageBit::SAMPLED_FRAGMENT});
  166. pass.newDependency({m_r->getSsao().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
  167. pass.newDependency({m_r->getSsgi().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
  168. pass.newDependency({m_r->getShadowmapsResolve().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
  169. // Refl & indirect
  170. pass.newDependency({m_r->getSsr().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
  171. pass.newDependency({m_r->getProbeReflections().getReflectionRt(), TextureUsageBit::SAMPLED_FRAGMENT});
  172. m_r->getGlobalIllumination().setRenderGraphDependencies(ctx, pass, TextureUsageBit::SAMPLED_FRAGMENT);
  173. // Fog
  174. pass.newDependency({m_r->getVolumetricFog().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
  175. // For forward shading
  176. m_r->getForwardShading().setDependencies(ctx, pass);
  177. }
  178. } // end namespace anki