LightShading.cpp 14 KB

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