ForwardShading.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. // Copyright (C) 2009-2018, 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/ForwardShading.h>
  6. #include <anki/renderer/Renderer.h>
  7. #include <anki/renderer/RenderQueue.h>
  8. #include <anki/renderer/GBuffer.h>
  9. #include <anki/renderer/LightShading.h>
  10. #include <anki/renderer/ShadowMapping.h>
  11. #include <anki/renderer/Volumetric.h>
  12. #include <anki/renderer/DepthDownscale.h>
  13. #include <anki/renderer/LensFlare.h>
  14. namespace anki
  15. {
  16. ForwardShading::~ForwardShading()
  17. {
  18. }
  19. Error ForwardShading::init(const ConfigSet& cfg)
  20. {
  21. ANKI_R_LOGI("Initializing forward shading");
  22. Error err = initInternal(cfg);
  23. if(err)
  24. {
  25. ANKI_R_LOGE("Failed to initialize forward shading");
  26. }
  27. return err;
  28. }
  29. Error ForwardShading::initInternal(const ConfigSet&)
  30. {
  31. m_width = m_r->getWidth() / FS_FRACTION;
  32. m_height = m_r->getHeight() / FS_FRACTION;
  33. // Create RT descr
  34. m_rtDescr = m_r->create2DRenderTargetDescription(
  35. m_width, m_height, FORWARD_SHADING_COLOR_ATTACHMENT_PIXEL_FORMAT, "forward");
  36. m_rtDescr.bake();
  37. // Create FB descr
  38. m_fbDescr.m_colorAttachmentCount = 1;
  39. m_fbDescr.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::CLEAR;
  40. m_fbDescr.m_colorAttachments[0].m_clearValue.m_colorf = {{0.0, 0.0, 0.0, 1.0}};
  41. m_fbDescr.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::LOAD;
  42. m_fbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::DEPTH;
  43. m_fbDescr.bake();
  44. ANKI_CHECK(initVol());
  45. ANKI_CHECK(initUpscale());
  46. return Error::NONE;
  47. }
  48. Error ForwardShading::initVol()
  49. {
  50. ANKI_CHECK(getResourceManager().loadResource("engine_data/BlueNoiseLdrRgb64x64.ankitex", m_vol.m_noiseTex));
  51. ANKI_CHECK(getResourceManager().loadResource("programs/ForwardShadingVolumetricUpscale.ankiprog", m_vol.m_prog));
  52. ShaderProgramResourceConstantValueInitList<3> consts(m_vol.m_prog);
  53. consts.add("NOISE_TEX_SIZE", U32(m_vol.m_noiseTex->getWidth()))
  54. .add("SRC_SIZE", Vec2(m_r->getWidth() / VOLUMETRIC_FRACTION, m_r->getHeight() / VOLUMETRIC_FRACTION))
  55. .add("FB_SIZE", Vec2(m_width, m_height));
  56. const ShaderProgramResourceVariant* variant;
  57. m_vol.m_prog->getOrCreateVariant(consts.get(), variant);
  58. m_vol.m_grProg = variant->getProgram();
  59. return Error::NONE;
  60. }
  61. Error ForwardShading::initUpscale()
  62. {
  63. ANKI_CHECK(getResourceManager().loadResource("engine_data/BlueNoiseLdrRgb64x64.ankitex", m_upscale.m_noiseTex));
  64. // Shader
  65. ANKI_CHECK(getResourceManager().loadResource("programs/ForwardShadingUpscale.ankiprog", m_upscale.m_prog));
  66. ShaderProgramResourceConstantValueInitList<3> consts(m_upscale.m_prog);
  67. consts.add("NOISE_TEX_SIZE", U32(m_upscale.m_noiseTex->getWidth()))
  68. .add("SRC_SIZE", Vec2(m_r->getWidth() / FS_FRACTION, m_r->getHeight() / FS_FRACTION))
  69. .add("FB_SIZE", Vec2(m_r->getWidth(), m_r->getWidth()));
  70. const ShaderProgramResourceVariant* variant;
  71. m_upscale.m_prog->getOrCreateVariant(consts.get(), variant);
  72. m_upscale.m_grProg = variant->getProgram();
  73. return Error::NONE;
  74. }
  75. void ForwardShading::drawVolumetric(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
  76. {
  77. CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
  78. cmdb->setViewport(0, 0, m_width, m_height);
  79. cmdb->bindShaderProgram(m_vol.m_grProg);
  80. cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ONE);
  81. cmdb->setDepthWrite(false);
  82. cmdb->setDepthCompareOperation(CompareOperation::ALWAYS);
  83. Vec4* unis = allocateAndBindUniforms<Vec4*>(sizeof(Vec4), cmdb, 0, 0);
  84. computeLinearizeDepthOptimal(ctx.m_renderQueue->m_cameraNear, ctx.m_renderQueue->m_cameraFar, unis->x(), unis->y());
  85. rgraphCtx.bindTextureAndSampler(
  86. 0, 0, m_r->getDepthDownscale().getHiZRt(), HIZ_HALF_DEPTH, m_r->getNearestSampler());
  87. rgraphCtx.bindTextureAndSampler(
  88. 0, 1, m_r->getDepthDownscale().getHiZRt(), HIZ_QUARTER_DEPTH, m_r->getNearestSampler());
  89. rgraphCtx.bindColorTextureAndSampler(0, 2, m_r->getVolumetric().getRt(), m_r->getLinearSampler());
  90. cmdb->bindTextureAndSampler(0,
  91. 3,
  92. m_vol.m_noiseTex->getGrTextureView(),
  93. m_r->getTrilinearRepeatSampler(),
  94. TextureUsageBit::SAMPLED_FRAGMENT);
  95. drawQuad(cmdb);
  96. // Restore state
  97. cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ZERO);
  98. cmdb->setDepthWrite(true);
  99. cmdb->setDepthCompareOperation(CompareOperation::LESS);
  100. }
  101. void ForwardShading::drawUpscale(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
  102. {
  103. return;
  104. CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
  105. // **WARNING** Remember to update the consumers of the render pass that calls this method
  106. Vec4* linearDepth = allocateAndBindUniforms<Vec4*>(sizeof(Vec4), cmdb, 0, 0);
  107. computeLinearizeDepthOptimal(
  108. ctx.m_renderQueue->m_cameraNear, ctx.m_renderQueue->m_cameraFar, linearDepth->x(), linearDepth->y());
  109. rgraphCtx.bindTextureAndSampler(0,
  110. 0,
  111. m_r->getGBuffer().getDepthRt(),
  112. TextureSubresourceInfo(DepthStencilAspectBit::DEPTH),
  113. m_r->getNearestSampler());
  114. rgraphCtx.bindTextureAndSampler(
  115. 0, 1, m_r->getDepthDownscale().getHiZRt(), HIZ_HALF_DEPTH, m_r->getNearestSampler());
  116. rgraphCtx.bindColorTextureAndSampler(0, 2, m_runCtx.m_rt, m_r->getLinearSampler());
  117. cmdb->bindTextureAndSampler(0,
  118. 3,
  119. m_upscale.m_noiseTex->getGrTextureView(),
  120. m_r->getTrilinearRepeatSampler(),
  121. TextureUsageBit::SAMPLED_FRAGMENT);
  122. cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::SRC_ALPHA);
  123. cmdb->bindShaderProgram(m_upscale.m_grProg);
  124. cmdb->setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
  125. drawQuad(cmdb);
  126. // Restore state
  127. cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ZERO);
  128. }
  129. void ForwardShading::run(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
  130. {
  131. CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
  132. const U threadId = rgraphCtx.m_currentSecondLevelCommandBufferIndex;
  133. const U threadCount = rgraphCtx.m_secondLevelCommandBufferCount;
  134. const U problemSize = ctx.m_renderQueue->m_forwardShadingRenderables.getSize();
  135. PtrSize start, end;
  136. ThreadPoolTask::choseStartEnd(threadId, threadCount, problemSize, start, end);
  137. if(start != end)
  138. {
  139. const LightShadingResources& rsrc = m_r->getLightShading().getResources();
  140. rgraphCtx.bindTextureAndSampler(
  141. 0, 0, m_r->getDepthDownscale().getHiZRt(), HIZ_HALF_DEPTH, m_r->getLinearSampler());
  142. rgraphCtx.bindColorTextureAndSampler(0, 1, m_r->getShadowMapping().getShadowmapRt(), m_r->getLinearSampler());
  143. bindUniforms(cmdb, 0, 0, rsrc.m_commonUniformsToken);
  144. bindUniforms(cmdb, 0, 1, rsrc.m_pointLightsToken);
  145. bindUniforms(cmdb, 0, 2, rsrc.m_spotLightsToken);
  146. bindStorage(cmdb, 0, 0, rsrc.m_clustersToken);
  147. bindStorage(cmdb, 0, 1, rsrc.m_lightIndicesToken);
  148. cmdb->setViewport(0, 0, m_width, m_height);
  149. cmdb->setBlendFactors(
  150. 0, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendFactor::SRC_ALPHA, BlendFactor::DST_ALPHA, BlendFactor::ZERO);
  151. cmdb->setBlendOperation(0, BlendOperation::ADD);
  152. cmdb->setDepthWrite(false);
  153. // Start drawing
  154. m_r->getSceneDrawer().drawRange(Pass::GB_FS,
  155. ctx.m_renderQueue->m_viewMatrix,
  156. ctx.m_viewProjMatJitter,
  157. cmdb,
  158. ctx.m_renderQueue->m_forwardShadingRenderables.getBegin() + start,
  159. ctx.m_renderQueue->m_forwardShadingRenderables.getBegin() + end);
  160. }
  161. if(threadId == threadCount - 1)
  162. {
  163. drawVolumetric(ctx, rgraphCtx);
  164. if(ctx.m_renderQueue->m_lensFlares.getSize())
  165. {
  166. m_r->getLensFlare().runDrawFlares(ctx, cmdb);
  167. }
  168. }
  169. }
  170. void ForwardShading::populateRenderGraph(RenderingContext& ctx)
  171. {
  172. RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
  173. m_runCtx.m_ctx = &ctx;
  174. // Create RT
  175. m_runCtx.m_rt = rgraph.newRenderTarget(m_rtDescr);
  176. // Create pass
  177. GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("Forward shading");
  178. pass.setWork(runCallback,
  179. this,
  180. computeNumberOfSecondLevelCommandBuffers(ctx.m_renderQueue->m_forwardShadingRenderables.getSize()));
  181. pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_rt}}, m_r->getDepthDownscale().getHalfDepthRt());
  182. pass.newConsumer({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE});
  183. pass.newConsumer({m_r->getDepthDownscale().getHalfDepthRt(),
  184. TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ,
  185. TextureSubresourceInfo(DepthStencilAspectBit::DEPTH)});
  186. pass.newConsumer({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_HALF_DEPTH});
  187. pass.newConsumer({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_QUARTER_DEPTH});
  188. pass.newConsumer({m_r->getVolumetric().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
  189. pass.newConsumer({m_r->getShadowMapping().getShadowmapRt(), TextureUsageBit::SAMPLED_FRAGMENT});
  190. if(ctx.m_renderQueue->m_lensFlares.getSize())
  191. {
  192. pass.newConsumer({m_r->getLensFlare().getIndirectDrawBuffer(), BufferUsageBit::INDIRECT});
  193. }
  194. pass.newProducer({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE});
  195. }
  196. } // end namespace anki