ForwardShading.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. // Copyright (C) 2009-2017, 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. namespace anki
  14. {
  15. ForwardShading::~ForwardShading()
  16. {
  17. }
  18. Error ForwardShading::init(const ConfigSet& cfg)
  19. {
  20. ANKI_R_LOGI("Initializing forward shading");
  21. Error err = initInternal(cfg);
  22. if(err)
  23. {
  24. ANKI_R_LOGE("Failed to initialize forward shading");
  25. }
  26. return err;
  27. }
  28. Error ForwardShading::initInternal(const ConfigSet&)
  29. {
  30. m_width = m_r->getWidth() / FS_FRACTION;
  31. m_height = m_r->getHeight() / FS_FRACTION;
  32. // Create RT
  33. m_rt = m_r->createAndClearRenderTarget(m_r->create2DRenderTargetInitInfo(m_width,
  34. m_height,
  35. FORWARD_SHADING_COLOR_ATTACHMENT_PIXEL_FORMAT,
  36. TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
  37. SamplingFilter::LINEAR,
  38. 1,
  39. "forward"));
  40. FramebufferInitInfo fbInit("forward");
  41. fbInit.m_colorAttachmentCount = 1;
  42. fbInit.m_colorAttachments[0].m_texture = m_rt;
  43. fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::CLEAR;
  44. fbInit.m_colorAttachments[0].m_clearValue.m_colorf = {{0.0, 0.0, 0.0, 1.0}};
  45. fbInit.m_depthStencilAttachment.m_texture = m_r->getDepthDownscale().m_hd.m_depthRt;
  46. fbInit.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::LOAD;
  47. fbInit.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::DEPTH;
  48. m_fb = getGrManager().newInstance<Framebuffer>(fbInit);
  49. ANKI_CHECK(initVol());
  50. ANKI_CHECK(initUpscale());
  51. return Error::NONE;
  52. }
  53. Error ForwardShading::initVol()
  54. {
  55. ANKI_CHECK(getResourceManager().loadResource("engine_data/BlueNoiseLdrRgb64x64.ankitex", m_vol.m_noiseTex));
  56. ANKI_CHECK(getResourceManager().loadResource("programs/ForwardShadingVolumetricUpscale.ankiprog", m_vol.m_prog));
  57. ShaderProgramResourceConstantValueInitList<3> consts(m_vol.m_prog);
  58. consts.add("NOISE_TEX_SIZE", U32(m_vol.m_noiseTex->getWidth()))
  59. .add("SRC_SIZE", Vec2(m_r->getWidth() / VOLUMETRIC_FRACTION, m_r->getHeight() / VOLUMETRIC_FRACTION))
  60. .add("FB_SIZE", Vec2(m_width, m_height));
  61. const ShaderProgramResourceVariant* variant;
  62. m_vol.m_prog->getOrCreateVariant(consts.get(), variant);
  63. m_vol.m_grProg = variant->getProgram();
  64. return Error::NONE;
  65. }
  66. Error ForwardShading::initUpscale()
  67. {
  68. ANKI_CHECK(getResourceManager().loadResource("engine_data/BlueNoiseLdrRgb64x64.ankitex", m_upscale.m_noiseTex));
  69. // Shader
  70. ANKI_CHECK(getResourceManager().loadResource("programs/ForwardShadingUpscale.ankiprog", m_upscale.m_prog));
  71. ShaderProgramResourceConstantValueInitList<3> consts(m_upscale.m_prog);
  72. consts.add("NOISE_TEX_SIZE", U32(m_upscale.m_noiseTex->getWidth()))
  73. .add("SRC_SIZE", Vec2(m_r->getWidth() / FS_FRACTION, m_r->getHeight() / FS_FRACTION))
  74. .add("FB_SIZE", Vec2(m_r->getWidth(), m_r->getWidth()));
  75. const ShaderProgramResourceVariant* variant;
  76. m_upscale.m_prog->getOrCreateVariant(consts.get(), variant);
  77. m_upscale.m_grProg = variant->getProgram();
  78. return Error::NONE;
  79. }
  80. void ForwardShading::drawVolumetric(RenderingContext& ctx, CommandBufferPtr cmdb)
  81. {
  82. cmdb->bindShaderProgram(m_vol.m_grProg);
  83. cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ONE);
  84. cmdb->setDepthWrite(false);
  85. cmdb->setDepthCompareOperation(CompareOperation::ALWAYS);
  86. Vec4* unis = allocateAndBindUniforms<Vec4*>(sizeof(Vec4), cmdb, 0, 0);
  87. computeLinearizeDepthOptimal(ctx.m_renderQueue->m_cameraNear, ctx.m_renderQueue->m_cameraFar, unis->x(), unis->y());
  88. cmdb->informTextureSurfaceCurrentUsage(
  89. m_r->getVolumetric().m_main.getRt(), TextureSurfaceInfo(0, 0, 0, 0), TextureUsageBit::SAMPLED_FRAGMENT);
  90. cmdb->bindTextureAndSampler(0, 0, m_r->getDepthDownscale().m_hd.m_colorRt, m_r->getNearestSampler());
  91. cmdb->bindTextureAndSampler(0, 1, m_r->getDepthDownscale().m_qd.m_colorRt, m_r->getNearestSampler());
  92. cmdb->bindTexture(0, 2, m_r->getVolumetric().m_main.getRt());
  93. cmdb->bindTexture(0, 3, m_vol.m_noiseTex->getGrTexture());
  94. m_r->drawQuad(cmdb);
  95. // Restore state
  96. cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ZERO);
  97. cmdb->setDepthWrite(true);
  98. cmdb->setDepthCompareOperation(CompareOperation::LESS);
  99. }
  100. void ForwardShading::drawUpscale(RenderingContext& ctx)
  101. {
  102. CommandBufferPtr& cmdb = ctx.m_commandBuffer;
  103. Vec4* linearDepth = allocateAndBindUniforms<Vec4*>(sizeof(Vec4), cmdb, 0, 0);
  104. computeLinearizeDepthOptimal(
  105. ctx.m_renderQueue->m_cameraNear, ctx.m_renderQueue->m_cameraFar, linearDepth->x(), linearDepth->y());
  106. cmdb->bindTexture(0, 0, m_r->getGBuffer().m_depthRt);
  107. cmdb->bindTextureAndSampler(0, 1, m_r->getDepthDownscale().m_hd.m_colorRt, m_r->getNearestSampler());
  108. cmdb->bindTexture(0, 2, m_rt);
  109. cmdb->bindTexture(0, 3, m_upscale.m_noiseTex->getGrTexture());
  110. cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::SRC_ALPHA);
  111. cmdb->bindShaderProgram(m_upscale.m_grProg);
  112. cmdb->setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
  113. m_r->drawQuad(cmdb);
  114. // Restore state
  115. cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ZERO);
  116. }
  117. void ForwardShading::buildCommandBuffers(RenderingContext& ctx, U threadId, U threadCount) const
  118. {
  119. const U problemSize = ctx.m_renderQueue->m_forwardShadingRenderables.getSize();
  120. PtrSize start, end;
  121. ThreadPoolTask::choseStartEnd(threadId, threadCount, problemSize, start, end);
  122. if(start == end)
  123. {
  124. // Early exit
  125. return;
  126. }
  127. // Create the command buffer and set some state
  128. CommandBufferInitInfo cinf;
  129. cinf.m_flags = CommandBufferFlag::SECOND_LEVEL | CommandBufferFlag::GRAPHICS_WORK;
  130. if(end - start < COMMAND_BUFFER_SMALL_BATCH_MAX_COMMANDS)
  131. {
  132. cinf.m_flags |= CommandBufferFlag::SMALL_BATCH;
  133. }
  134. cinf.m_framebuffer = m_fb;
  135. CommandBufferPtr cmdb = m_r->getGrManager().newInstance<CommandBuffer>(cinf);
  136. ctx.m_forwardShading.m_commandBuffers[threadId] = cmdb;
  137. cmdb->informTextureCurrentUsage(m_r->getDepthDownscale().m_qd.m_colorRt, TextureUsageBit::SAMPLED_FRAGMENT);
  138. cmdb->informTextureSurfaceCurrentUsage(
  139. m_r->getDepthDownscale().m_hd.m_colorRt, TextureSurfaceInfo(0, 0, 0, 0), TextureUsageBit::SAMPLED_FRAGMENT);
  140. cmdb->informTextureSurfaceCurrentUsage(m_r->getDepthDownscale().m_hd.m_depthRt,
  141. TextureSurfaceInfo(0, 0, 0, 0),
  142. TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ);
  143. cmdb->informTextureCurrentUsage(m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE);
  144. cmdb->informTextureCurrentUsage(m_r->getShadowMapping().m_shadowAtlas, TextureUsageBit::SAMPLED_FRAGMENT);
  145. cmdb->bindTexture(0, 0, m_r->getDepthDownscale().m_qd.m_colorRt);
  146. cmdb->bindTexture(0, 1, m_r->getShadowMapping().m_shadowAtlas);
  147. bindUniforms(cmdb, 0, 0, ctx.m_lightShading.m_commonToken);
  148. bindUniforms(cmdb, 0, 1, ctx.m_lightShading.m_pointLightsToken);
  149. bindUniforms(cmdb, 0, 2, ctx.m_lightShading.m_spotLightsToken);
  150. bindStorage(cmdb, 0, 0, ctx.m_lightShading.m_clustersToken);
  151. bindStorage(cmdb, 0, 1, ctx.m_lightShading.m_lightIndicesToken);
  152. cmdb->setViewport(0, 0, m_width, m_height);
  153. cmdb->setBlendFactors(
  154. 0, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendFactor::SRC_ALPHA, BlendFactor::DST_ALPHA, BlendFactor::ZERO);
  155. cmdb->setBlendOperation(0, BlendOperation::ADD);
  156. cmdb->setDepthWrite(false);
  157. // Start drawing
  158. m_r->getSceneDrawer().drawRange(Pass::GB_FS,
  159. ctx.m_renderQueue->m_viewMatrix,
  160. ctx.m_viewProjMatJitter,
  161. cmdb,
  162. ctx.m_renderQueue->m_forwardShadingRenderables.getBegin() + start,
  163. ctx.m_renderQueue->m_forwardShadingRenderables.getBegin() + end);
  164. }
  165. void ForwardShading::setPreRunBarriers(RenderingContext& ctx)
  166. {
  167. ctx.m_commandBuffer->setTextureSurfaceBarrier(m_rt,
  168. TextureUsageBit::NONE,
  169. TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
  170. TextureSurfaceInfo(0, 0, 0, 0));
  171. }
  172. void ForwardShading::setPostRunBarriers(RenderingContext& ctx)
  173. {
  174. ctx.m_commandBuffer->setTextureSurfaceBarrier(m_rt,
  175. TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
  176. TextureUsageBit::SAMPLED_FRAGMENT,
  177. TextureSurfaceInfo(0, 0, 0, 0));
  178. }
  179. void ForwardShading::run(RenderingContext& ctx)
  180. {
  181. CommandBufferPtr& cmdb = ctx.m_commandBuffer;
  182. cmdb->beginRenderPass(m_fb);
  183. cmdb->setViewport(0, 0, m_width, m_height);
  184. for(U i = 0; i < m_r->getThreadPool().getThreadsCount(); ++i)
  185. {
  186. if(ctx.m_forwardShading.m_commandBuffers[i].isCreated())
  187. {
  188. cmdb->pushSecondLevelCommandBuffer(ctx.m_forwardShading.m_commandBuffers[i]);
  189. }
  190. }
  191. cmdb->endRenderPass();
  192. }
  193. } // end namespace anki