LightShading.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. // Copyright (C) 2009-2022, 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/IndirectSpecular.h>
  15. #include <AnKi/Renderer/ShadowmapsResolve.h>
  16. #include <AnKi/Renderer/RtShadows.h>
  17. #include <AnKi/Renderer/IndirectDiffuse.h>
  18. #include <AnKi/Renderer/VrsSriGeneration.h>
  19. #include <AnKi/Core/ConfigSet.h>
  20. namespace anki {
  21. LightShading::LightShading(Renderer* r)
  22. : RendererObject(r)
  23. {
  24. registerDebugRenderTarget("LightShading");
  25. }
  26. LightShading::~LightShading()
  27. {
  28. }
  29. Error LightShading::init()
  30. {
  31. ANKI_R_LOGV("Initializing light shading");
  32. Error err = initLightShading();
  33. if(!err)
  34. {
  35. err = initSkybox();
  36. }
  37. if(!err)
  38. {
  39. err = initApplyFog();
  40. }
  41. if(!err)
  42. {
  43. err = initApplyIndirect();
  44. }
  45. if(err)
  46. {
  47. ANKI_R_LOGE("Failed to init light stage");
  48. }
  49. return err;
  50. }
  51. Error LightShading::initLightShading()
  52. {
  53. // Load shaders and programs
  54. ANKI_CHECK(getResourceManager().loadResource("ShaderBinaries/LightShading.ankiprogbin", m_lightShading.m_prog));
  55. ShaderProgramResourceVariantInitInfo variantInitInfo(m_lightShading.m_prog);
  56. variantInitInfo.addConstant("TILE_COUNTS", m_r->getTileCounts());
  57. variantInitInfo.addConstant("Z_SPLIT_COUNT", m_r->getZSplitCount());
  58. variantInitInfo.addConstant("TILE_SIZE", m_r->getTileSize());
  59. const ShaderProgramResourceVariant* variant;
  60. variantInitInfo.addMutation("USE_SHADOW_LAYERS", 0);
  61. m_lightShading.m_prog->getOrCreateVariant(variantInitInfo, variant);
  62. m_lightShading.m_grProg[0] = variant->getProgram();
  63. variantInitInfo.addMutation("USE_SHADOW_LAYERS", 1);
  64. m_lightShading.m_prog->getOrCreateVariant(variantInitInfo, variant);
  65. m_lightShading.m_grProg[1] = variant->getProgram();
  66. // Create RT descr
  67. m_lightShading.m_rtDescr = m_r->create2DRenderTargetDescription(
  68. m_r->getInternalResolution().x(), m_r->getInternalResolution().y(), m_r->getHdrFormat(), "Light Shading");
  69. m_lightShading.m_rtDescr.bake();
  70. // Create FB descr
  71. m_lightShading.m_fbDescr.m_colorAttachmentCount = 1;
  72. m_lightShading.m_fbDescr.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::LOAD;
  73. m_lightShading.m_fbDescr.m_depthStencilAttachment.m_stencilLoadOperation = AttachmentLoadOperation::DONT_CARE;
  74. m_lightShading.m_fbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::DEPTH;
  75. if(getGrManager().getDeviceCapabilities().m_vrs && getConfig().getRVrs())
  76. {
  77. m_lightShading.m_fbDescr.m_shadingRateAttachmentTexelWidth = m_r->getVrsSriGeneration().getSriTexelDimension();
  78. m_lightShading.m_fbDescr.m_shadingRateAttachmentTexelHeight = m_r->getVrsSriGeneration().getSriTexelDimension();
  79. }
  80. m_lightShading.m_fbDescr.bake();
  81. // Debug visualization
  82. ANKI_CHECK(
  83. getResourceManager().loadResource("ShaderBinaries/VisualizeHdrRenderTarget.ankiprogbin", m_visualizeRtProg));
  84. m_visualizeRtProg->getOrCreateVariant(variant);
  85. m_visualizeRtGrProg = variant->getProgram();
  86. return Error::NONE;
  87. }
  88. Error LightShading::initSkybox()
  89. {
  90. ANKI_CHECK(getResourceManager().loadResource("ShaderBinaries/LightShadingSkybox.ankiprogbin", m_skybox.m_prog));
  91. for(U32 method = 0; method < 2; ++method)
  92. {
  93. ShaderProgramResourceVariantInitInfo variantInitInfo(m_skybox.m_prog);
  94. variantInitInfo.addMutation("METHOD", method);
  95. const ShaderProgramResourceVariant* variant;
  96. m_skybox.m_prog->getOrCreateVariant(variantInitInfo, variant);
  97. m_skybox.m_grProgs[method] = variant->getProgram();
  98. }
  99. return Error::NONE;
  100. }
  101. Error LightShading::initApplyFog()
  102. {
  103. // Load shaders and programs
  104. ANKI_CHECK(getResourceManager().loadResource("ShaderBinaries/LightShadingApplyFog.ankiprogbin", m_applyFog.m_prog));
  105. ShaderProgramResourceVariantInitInfo variantInitInfo(m_applyFog.m_prog);
  106. variantInitInfo.addConstant("Z_SPLIT_COUNT", m_r->getZSplitCount());
  107. variantInitInfo.addConstant("FINAL_Z_SPLIT", m_r->getVolumetricFog().getFinalClusterInZ());
  108. const ShaderProgramResourceVariant* variant;
  109. m_applyFog.m_prog->getOrCreateVariant(variantInitInfo, variant);
  110. m_applyFog.m_grProg = variant->getProgram();
  111. return Error::NONE;
  112. }
  113. Error LightShading::initApplyIndirect()
  114. {
  115. ANKI_CHECK(getResourceManager().loadResource("ShaderBinaries/LightShadingApplyIndirect.ankiprogbin",
  116. m_applyIndirect.m_prog));
  117. const ShaderProgramResourceVariant* variant;
  118. m_applyIndirect.m_prog->getOrCreateVariant(variant);
  119. m_applyIndirect.m_grProg = variant->getProgram();
  120. return Error::NONE;
  121. }
  122. void LightShading::run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
  123. {
  124. CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
  125. cmdb->setViewport(0, 0, m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
  126. const Bool enableVrs = getGrManager().getDeviceCapabilities().m_vrs && getConfig().getRVrs();
  127. if(enableVrs)
  128. {
  129. // Just set some low value, the attachment will take over
  130. cmdb->setVrsRate(VrsRate::_1x1);
  131. }
  132. // Do light shading first
  133. if(rgraphCtx.m_currentSecondLevelCommandBufferIndex == 0)
  134. {
  135. cmdb->bindShaderProgram(m_lightShading.m_grProg[m_r->getRtShadowsEnabled()]);
  136. cmdb->setDepthWrite(false);
  137. // Bind all
  138. const ClusteredShadingContext& binning = ctx.m_clusteredShading;
  139. bindUniforms(cmdb, 0, 0, binning.m_clusteredShadingUniformsToken);
  140. bindUniforms(cmdb, 0, 1, binning.m_pointLightsToken);
  141. bindUniforms(cmdb, 0, 2, binning.m_spotLightsToken);
  142. rgraphCtx.bindColorTexture(0, 3, m_r->getShadowMapping().getShadowmapRt());
  143. bindStorage(cmdb, 0, 4, binning.m_clustersToken);
  144. cmdb->bindSampler(0, 5, m_r->getSamplers().m_nearestNearestClamp);
  145. cmdb->bindSampler(0, 6, m_r->getSamplers().m_trilinearClamp);
  146. rgraphCtx.bindColorTexture(0, 7, m_r->getGBuffer().getColorRt(0));
  147. rgraphCtx.bindColorTexture(0, 8, m_r->getGBuffer().getColorRt(1));
  148. rgraphCtx.bindColorTexture(0, 9, m_r->getGBuffer().getColorRt(2));
  149. rgraphCtx.bindTexture(0, 10, m_r->getGBuffer().getDepthRt(),
  150. TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
  151. if(m_r->getRtShadowsEnabled())
  152. {
  153. rgraphCtx.bindColorTexture(0, 11, m_r->getRtShadows().getRt());
  154. }
  155. else
  156. {
  157. rgraphCtx.bindColorTexture(0, 12, m_r->getShadowmapsResolve().getRt());
  158. }
  159. // Draw
  160. drawQuad(cmdb);
  161. }
  162. // Apply indirect
  163. if(rgraphCtx.m_currentSecondLevelCommandBufferIndex == 0)
  164. {
  165. cmdb->setDepthWrite(false);
  166. cmdb->bindShaderProgram(m_applyIndirect.m_grProg);
  167. cmdb->bindSampler(0, 0, m_r->getSamplers().m_nearestNearestClamp);
  168. cmdb->bindSampler(0, 1, m_r->getSamplers().m_trilinearClamp);
  169. rgraphCtx.bindColorTexture(0, 2, m_r->getIndirectDiffuse().getRt());
  170. rgraphCtx.bindColorTexture(0, 3, m_r->getIndirectSpecular().getRt());
  171. rgraphCtx.bindColorTexture(0, 4, m_r->getDepthDownscale().getHiZRt());
  172. rgraphCtx.bindTexture(0, 5, m_r->getGBuffer().getDepthRt(),
  173. TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
  174. rgraphCtx.bindColorTexture(0, 6, m_r->getGBuffer().getColorRt(0));
  175. rgraphCtx.bindColorTexture(0, 7, m_r->getGBuffer().getColorRt(1));
  176. rgraphCtx.bindColorTexture(0, 8, m_r->getGBuffer().getColorRt(2));
  177. cmdb->bindTexture(0, 9, m_r->getProbeReflections().getIntegrationLut());
  178. const ClusteredShadingContext& binning = ctx.m_clusteredShading;
  179. bindUniforms(cmdb, 0, 10, binning.m_clusteredShadingUniformsToken);
  180. const Vec4 pc(ctx.m_renderQueue->m_cameraNear, ctx.m_renderQueue->m_cameraFar, 0.0f, 0.0f);
  181. cmdb->setPushConstants(&pc, sizeof(pc));
  182. cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ONE);
  183. drawQuad(cmdb);
  184. // Restore state
  185. cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ZERO);
  186. }
  187. // Skybox
  188. if(rgraphCtx.m_currentSecondLevelCommandBufferIndex == 0)
  189. {
  190. cmdb->setDepthCompareOperation(CompareOperation::EQUAL);
  191. const Bool isSolidColor = ctx.m_renderQueue->m_skybox.m_skyboxTexture == nullptr;
  192. if(isSolidColor)
  193. {
  194. cmdb->bindShaderProgram(m_skybox.m_grProgs[0]);
  195. const Vec4 color(ctx.m_renderQueue->m_skybox.m_solidColor, 0.0);
  196. cmdb->setPushConstants(&color, sizeof(color));
  197. }
  198. else
  199. {
  200. cmdb->bindShaderProgram(m_skybox.m_grProgs[1]);
  201. class
  202. {
  203. public:
  204. Mat4 m_invertedViewProjectionJitter;
  205. Vec3 m_cameraPos;
  206. F32 m_padding = 0.0;
  207. } pc;
  208. pc.m_invertedViewProjectionJitter = ctx.m_matrices.m_invertedViewProjectionJitter;
  209. pc.m_cameraPos = ctx.m_matrices.m_cameraTransform.getTranslationPart().xyz();
  210. cmdb->setPushConstants(&pc, sizeof(pc));
  211. cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearRepeatAnisoResolutionScalingBias);
  212. cmdb->bindTexture(0, 1,
  213. TextureViewPtr(const_cast<TextureView*>(ctx.m_renderQueue->m_skybox.m_skyboxTexture)));
  214. }
  215. drawQuad(cmdb);
  216. // Restore state
  217. cmdb->setDepthCompareOperation(CompareOperation::LESS);
  218. }
  219. // Do the fog apply
  220. if(rgraphCtx.m_currentSecondLevelCommandBufferIndex == rgraphCtx.m_secondLevelCommandBufferCount - 1u)
  221. {
  222. cmdb->bindShaderProgram(m_applyFog.m_grProg);
  223. // Bind all
  224. cmdb->bindSampler(0, 0, m_r->getSamplers().m_nearestNearestClamp);
  225. cmdb->bindSampler(0, 1, m_r->getSamplers().m_trilinearClamp);
  226. rgraphCtx.bindTexture(0, 2, m_r->getGBuffer().getDepthRt(),
  227. TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
  228. rgraphCtx.bindColorTexture(0, 3, m_r->getVolumetricFog().getRt());
  229. class PushConsts
  230. {
  231. public:
  232. Vec2 m_padding;
  233. F32 m_near;
  234. F32 m_far;
  235. } regs;
  236. regs.m_near = ctx.m_renderQueue->m_cameraNear;
  237. regs.m_far = ctx.m_renderQueue->m_cameraFar;
  238. cmdb->setPushConstants(&regs, sizeof(regs));
  239. // finalPixelColor = pixelWithoutFog * transmitance + inScattering (see the shader)
  240. cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::SRC_ALPHA);
  241. drawQuad(cmdb);
  242. // Reset state
  243. cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ZERO);
  244. }
  245. // Forward shading last
  246. if(enableVrs)
  247. {
  248. cmdb->setVrsRate(VrsRate::_2x2);
  249. }
  250. m_r->getForwardShading().run(ctx, rgraphCtx);
  251. if(enableVrs)
  252. {
  253. // Restore
  254. cmdb->setVrsRate(VrsRate::_1x1);
  255. }
  256. }
  257. void LightShading::populateRenderGraph(RenderingContext& ctx)
  258. {
  259. RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
  260. const Bool enableVrs = getGrManager().getDeviceCapabilities().m_vrs && getConfig().getRVrs();
  261. const Bool fbDescrHasVrs = m_lightShading.m_fbDescr.m_shadingRateAttachmentTexelWidth > 0;
  262. if(enableVrs != fbDescrHasVrs)
  263. {
  264. // Re-bake the FB descriptor if the VRS state has changed
  265. if(enableVrs)
  266. {
  267. m_lightShading.m_fbDescr.m_shadingRateAttachmentTexelWidth =
  268. m_r->getVrsSriGeneration().getSriTexelDimension();
  269. m_lightShading.m_fbDescr.m_shadingRateAttachmentTexelHeight =
  270. m_r->getVrsSriGeneration().getSriTexelDimension();
  271. }
  272. else
  273. {
  274. m_lightShading.m_fbDescr.m_shadingRateAttachmentTexelWidth = 0;
  275. m_lightShading.m_fbDescr.m_shadingRateAttachmentTexelHeight = 0;
  276. }
  277. m_lightShading.m_fbDescr.bake();
  278. }
  279. // Create RT
  280. m_runCtx.m_rt = rgraph.newRenderTarget(m_lightShading.m_rtDescr);
  281. RenderTargetHandle sriRt;
  282. if(enableVrs)
  283. {
  284. sriRt = m_r->getVrsSriGeneration().getSriRt();
  285. }
  286. // Create pass
  287. GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("Light&FW Shad");
  288. pass.setWork(computeNumberOfSecondLevelCommandBuffers(ctx.m_renderQueue->m_forwardShadingRenderables.getSize()),
  289. [this, &ctx](RenderPassWorkContext& rgraphCtx) {
  290. run(ctx, rgraphCtx);
  291. });
  292. pass.setFramebufferInfo(m_lightShading.m_fbDescr, {m_runCtx.m_rt}, m_r->getGBuffer().getDepthRt(), sriRt);
  293. const TextureUsageBit readUsage = TextureUsageBit::SAMPLED_FRAGMENT;
  294. // All
  295. if(enableVrs)
  296. {
  297. pass.newDependency(RenderPassDependency(sriRt, TextureUsageBit::FRAMEBUFFER_SHADING_RATE));
  298. }
  299. // Light shading
  300. pass.newDependency(RenderPassDependency(m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE));
  301. pass.newDependency(RenderPassDependency(m_r->getGBuffer().getColorRt(0), readUsage));
  302. pass.newDependency(RenderPassDependency(m_r->getGBuffer().getColorRt(1), readUsage));
  303. pass.newDependency(RenderPassDependency(m_r->getGBuffer().getColorRt(2), readUsage));
  304. pass.newDependency(
  305. RenderPassDependency(m_r->getGBuffer().getDepthRt(),
  306. TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ,
  307. TextureSubresourceInfo(DepthStencilAspectBit::DEPTH)));
  308. pass.newDependency(RenderPassDependency(m_r->getShadowMapping().getShadowmapRt(), readUsage));
  309. if(m_r->getRtShadowsEnabled())
  310. {
  311. pass.newDependency(RenderPassDependency(m_r->getRtShadows().getRt(), readUsage));
  312. }
  313. else
  314. {
  315. pass.newDependency(RenderPassDependency(m_r->getShadowmapsResolve().getRt(), readUsage));
  316. }
  317. pass.newDependency(
  318. RenderPassDependency(ctx.m_clusteredShading.m_clustersBufferHandle, BufferUsageBit::STORAGE_FRAGMENT_READ));
  319. // Apply indirect
  320. pass.newDependency(RenderPassDependency(m_r->getIndirectDiffuse().getRt(), readUsage));
  321. pass.newDependency(RenderPassDependency(m_r->getDepthDownscale().getHiZRt(), readUsage));
  322. pass.newDependency(RenderPassDependency(m_r->getIndirectSpecular().getRt(), readUsage));
  323. // Fog
  324. pass.newDependency(RenderPassDependency(m_r->getVolumetricFog().getRt(), readUsage));
  325. // For forward shading
  326. m_r->getForwardShading().setDependencies(ctx, pass);
  327. }
  328. void LightShading::getDebugRenderTarget([[maybe_unused]] CString rtName,
  329. Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
  330. ShaderProgramPtr& optionalShaderProgram) const
  331. {
  332. ANKI_ASSERT(rtName == "LightShading");
  333. handles[0] = m_runCtx.m_rt;
  334. optionalShaderProgram = m_visualizeRtGrProg;
  335. }
  336. } // end namespace anki