ForwardShading.cpp 8.8 KB

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