LightShading.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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/LightShading.h>
  6. #include <anki/renderer/Renderer.h>
  7. #include <anki/renderer/ShadowMapping.h>
  8. #include <anki/renderer/Ssao.h>
  9. #include <anki/renderer/Indirect.h>
  10. #include <anki/renderer/GBuffer.h>
  11. #include <anki/renderer/LightBin.h>
  12. #include <anki/renderer/RenderQueue.h>
  13. #include <anki/renderer/ForwardShading.h>
  14. #include <anki/renderer/DepthDownscale.h>
  15. #include <anki/misc/ConfigSet.h>
  16. #include <anki/util/HighRezTimer.h>
  17. namespace anki
  18. {
  19. struct ShaderCommonUniforms
  20. {
  21. Vec4 m_projectionParams;
  22. Vec4 m_rendererSizeTimePad1;
  23. Vec4 m_nearFarClustererMagicPad1;
  24. Mat3x4 m_invViewRotation;
  25. UVec4 m_tileCount;
  26. Mat4 m_invViewProjMat;
  27. Mat4 m_prevViewProjMat;
  28. Mat4 m_invProjMat;
  29. };
  30. LightShading::LightShading(Renderer* r)
  31. : RendererObject(r)
  32. {
  33. }
  34. LightShading::~LightShading()
  35. {
  36. getAllocator().deleteInstance(m_lightBin);
  37. }
  38. Error LightShading::init(const ConfigSet& config)
  39. {
  40. ANKI_R_LOGI("Initializing light stage");
  41. Error err = initInternal(config);
  42. if(err)
  43. {
  44. ANKI_R_LOGE("Failed to init light stage");
  45. }
  46. return err;
  47. }
  48. Error LightShading::initInternal(const ConfigSet& config)
  49. {
  50. m_maxLightIds = config.getNumber("r.maxLightsPerCluster");
  51. if(m_maxLightIds == 0)
  52. {
  53. ANKI_R_LOGE("Incorrect number of max light indices");
  54. return Error::USER_DATA;
  55. }
  56. m_clusterCounts[0] = config.getNumber("r.clusterSizeX");
  57. m_clusterCounts[1] = config.getNumber("r.clusterSizeY");
  58. m_clusterCounts[2] = config.getNumber("r.clusterSizeZ");
  59. m_clusterCount = m_clusterCounts[0] * m_clusterCounts[1] * m_clusterCounts[2];
  60. m_maxLightIds *= m_clusterCount;
  61. m_lightBin = getAllocator().newInstance<LightBin>(getAllocator(),
  62. m_clusterCounts[0],
  63. m_clusterCounts[1],
  64. m_clusterCounts[2],
  65. &m_r->getThreadPool(),
  66. &m_r->getStagingGpuMemoryManager());
  67. // Load shaders and programs
  68. ANKI_CHECK(getResourceManager().loadResource("programs/LightShading.ankiprog", m_prog));
  69. ShaderProgramResourceConstantValueInitList<4> consts(m_prog);
  70. consts.add("CLUSTER_COUNT_X", U32(m_clusterCounts[0]))
  71. .add("CLUSTER_COUNT_Y", U32(m_clusterCounts[1]))
  72. .add("CLUSTER_COUNT", U32(m_clusterCount))
  73. .add("IR_MIPMAP_COUNT", U32(m_r->getIndirect().getReflectionTextureMipmapCount()));
  74. m_prog->getOrCreateVariant(consts.get(), m_progVariant);
  75. // Create RT descr
  76. m_rtDescr = m_r->create2DRenderTargetDescription(m_r->getWidth(),
  77. m_r->getHeight(),
  78. LIGHT_SHADING_COLOR_ATTACHMENT_PIXEL_FORMAT,
  79. TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
  80. SamplingFilter::LINEAR,
  81. "Light Shading");
  82. m_rtDescr.bake();
  83. // Create FB descr
  84. m_fbDescr.m_colorAttachmentCount = 1;
  85. m_fbDescr.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::DONT_CARE;
  86. m_fbDescr.bake();
  87. return Error::NONE;
  88. }
  89. Error LightShading::binLights(RenderingContext& ctx)
  90. {
  91. updateCommonBlock(ctx);
  92. ANKI_CHECK(m_lightBin->bin(ctx.m_renderQueue->m_viewMatrix,
  93. ctx.m_renderQueue->m_projectionMatrix,
  94. ctx.m_renderQueue->m_viewProjectionMatrix,
  95. ctx.m_renderQueue->m_cameraTransform,
  96. *ctx.m_renderQueue,
  97. getFrameAllocator(),
  98. m_maxLightIds,
  99. true,
  100. ctx.m_lightShading.m_pointLightsToken,
  101. ctx.m_lightShading.m_spotLightsToken,
  102. &ctx.m_lightShading.m_probesToken,
  103. ctx.m_lightShading.m_decalsToken,
  104. ctx.m_lightShading.m_clustersToken,
  105. ctx.m_lightShading.m_lightIndicesToken,
  106. ctx.m_lightShading.m_diffDecalTex,
  107. ctx.m_lightShading.m_normRoughnessDecalTex));
  108. return Error::NONE;
  109. }
  110. void LightShading::run(const RenderingContext& ctx, const RenderGraph& rgraph, CommandBufferPtr& cmdb)
  111. {
  112. cmdb->setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
  113. cmdb->bindShaderProgram(m_progVariant->getProgram());
  114. cmdb->bindTexture(1, 0, rgraph.getTexture(m_r->getGBuffer().getColorRt(0)));
  115. cmdb->bindTexture(1, 1, rgraph.getTexture(m_r->getGBuffer().getColorRt(1)));
  116. cmdb->bindTexture(1, 2, rgraph.getTexture(m_r->getGBuffer().getColorRt(2)));
  117. cmdb->bindTexture(1, 3, rgraph.getTexture(m_r->getGBuffer().getDepthRt()), DepthStencilAspectBit::DEPTH);
  118. cmdb->bindTexture(1, 4, rgraph.getTexture(m_r->getSsao().getRt()));
  119. cmdb->bindTexture(0, 0, rgraph.getTexture(m_r->getShadowMapping().getShadowmapRt()));
  120. cmdb->bindTexture(0, 1, rgraph.getTexture(m_r->getIndirect().getReflectionRt()));
  121. cmdb->bindTexture(0, 2, rgraph.getTexture(m_r->getIndirect().getIrradianceRt()));
  122. cmdb->bindTextureAndSampler(
  123. 0, 3, m_r->getIndirect().getIntegrationLut(), m_r->getIndirect().getIntegrationLutSampler());
  124. cmdb->bindTexture(
  125. 0, 4, (ctx.m_lightShading.m_diffDecalTex) ? ctx.m_lightShading.m_diffDecalTex : m_r->getDummyTexture());
  126. cmdb->bindTexture(0,
  127. 5,
  128. (ctx.m_lightShading.m_normRoughnessDecalTex) ? ctx.m_lightShading.m_normRoughnessDecalTex
  129. : m_r->getDummyTexture());
  130. bindUniforms(cmdb, 0, 0, ctx.m_lightShading.m_commonToken);
  131. bindUniforms(cmdb, 0, 1, ctx.m_lightShading.m_pointLightsToken);
  132. bindUniforms(cmdb, 0, 2, ctx.m_lightShading.m_spotLightsToken);
  133. bindUniforms(cmdb, 0, 3, ctx.m_lightShading.m_probesToken);
  134. bindUniforms(cmdb, 0, 4, ctx.m_lightShading.m_decalsToken);
  135. bindStorage(cmdb, 0, 0, ctx.m_lightShading.m_clustersToken);
  136. bindStorage(cmdb, 0, 1, ctx.m_lightShading.m_lightIndicesToken);
  137. cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 3);
  138. // Apply the forward shading result
  139. m_r->getForwardShading().drawUpscale(ctx, rgraph, cmdb);
  140. }
  141. void LightShading::updateCommonBlock(RenderingContext& ctx)
  142. {
  143. ShaderCommonUniforms* blk =
  144. allocateUniforms<ShaderCommonUniforms*>(sizeof(ShaderCommonUniforms), ctx.m_lightShading.m_commonToken);
  145. // Start writing
  146. blk->m_projectionParams = ctx.m_unprojParams;
  147. blk->m_nearFarClustererMagicPad1 = Vec4(ctx.m_renderQueue->m_cameraNear,
  148. ctx.m_renderQueue->m_cameraFar,
  149. m_lightBin->getClusterer().getShaderMagicValue(),
  150. 0.0);
  151. blk->m_invViewRotation = Mat3x4(ctx.m_renderQueue->m_viewMatrix.getInverse().getRotationPart());
  152. blk->m_rendererSizeTimePad1 = Vec4(m_r->getWidth(), m_r->getHeight(), HighRezTimer::getCurrentTime(), 0.0);
  153. blk->m_tileCount = UVec4(m_clusterCounts[0], m_clusterCounts[1], m_clusterCounts[2], m_clusterCount);
  154. blk->m_invViewProjMat = ctx.m_viewProjMatJitter.getInverse();
  155. blk->m_prevViewProjMat = ctx.m_prevViewProjMat;
  156. blk->m_invProjMat = ctx.m_projMatJitter.getInverse();
  157. }
  158. void LightShading::populateRenderGraph(RenderingContext& ctx)
  159. {
  160. m_runCtx.m_ctx = &ctx;
  161. RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
  162. // Create RT
  163. m_runCtx.m_rt = rgraph.newRenderTarget(m_rtDescr);
  164. // Create pass
  165. GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("Light Shading");
  166. pass.setWork(runCallback, this, 0);
  167. pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_rt}}, {});
  168. pass.newConsumer({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
  169. pass.newConsumer({m_r->getGBuffer().getColorRt(0), TextureUsageBit::SAMPLED_FRAGMENT});
  170. pass.newConsumer({m_r->getGBuffer().getColorRt(1), TextureUsageBit::SAMPLED_FRAGMENT});
  171. pass.newConsumer({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_FRAGMENT});
  172. pass.newConsumer({m_r->getGBuffer().getDepthRt(), TextureUsageBit::SAMPLED_FRAGMENT});
  173. pass.newConsumer({m_r->getSsao().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
  174. pass.newConsumer({m_r->getShadowMapping().getShadowmapRt(), TextureUsageBit::SAMPLED_FRAGMENT});
  175. pass.newConsumer({m_r->getIndirect().getReflectionRt(), TextureUsageBit::SAMPLED_FRAGMENT});
  176. pass.newConsumer({m_r->getIndirect().getIrradianceRt(), TextureUsageBit::SAMPLED_FRAGMENT});
  177. pass.newConsumer({m_r->getDepthDownscale().getHalfDepthColorRt(), TextureUsageBit::SAMPLED_FRAGMENT});
  178. pass.newConsumer({m_r->getForwardShading().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
  179. pass.newProducer({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
  180. }
  181. } // end namespace anki