TraditionalDeferredShading.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // Copyright (C) 2009-present, 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/Utils/TraditionalDeferredShading.h>
  6. #include <AnKi/Renderer/Renderer.h>
  7. #include <AnKi/Resource/ResourceManager.h>
  8. #include <AnKi/Resource/MeshResource.h>
  9. #include <AnKi/Resource/ImageResource.h>
  10. #include <AnKi/Shaders/Include/TraditionalDeferredShadingTypes.h>
  11. #include <AnKi/Scene/SceneGraph.h>
  12. #include <AnKi/Scene/Components/SkyboxComponent.h>
  13. #include <AnKi/Scene/Components/LightComponent.h>
  14. namespace anki {
  15. Error TraditionalDeferredLightShading::init()
  16. {
  17. // Init progs
  18. for(MutatorValue specular = 0; specular <= 1; ++specular)
  19. {
  20. for(MutatorValue applyIndirectDiffuse = 0; applyIndirectDiffuse <= 1; ++applyIndirectDiffuse)
  21. {
  22. ANKI_CHECK(loadShaderProgram("ShaderBinaries/TraditionalDeferredShading.ankiprogbin",
  23. {{"SPECULAR", specular}, {"INDIRECT_DIFFUSE", applyIndirectDiffuse}}, m_lightProg,
  24. m_lightGrProg[specular][applyIndirectDiffuse]));
  25. }
  26. }
  27. // Shadow sampler
  28. {
  29. SamplerInitInfo inf;
  30. inf.m_compareOperation = CompareOperation::kLessEqual;
  31. inf.m_addressing = SamplingAddressing::kClamp;
  32. inf.m_mipmapFilter = SamplingFilter::kNearest;
  33. inf.m_minMagFilter = SamplingFilter::kLinear;
  34. m_shadowSampler = GrManager::getSingleton().newSampler(inf);
  35. }
  36. // Skybox
  37. for(MutatorValue i = 0; i < m_skyboxGrProgs.getSize(); ++i)
  38. {
  39. ANKI_CHECK(
  40. loadShaderProgram("ShaderBinaries/TraditionalDeferredShadingSkybox.ankiprogbin", {{"METHOD", i}}, m_skyboxProg, m_skyboxGrProgs[i]));
  41. }
  42. return Error::kNone;
  43. }
  44. void TraditionalDeferredLightShading::drawLights(TraditionalDeferredLightShadingDrawInfo& info)
  45. {
  46. CommandBuffer& cmdb = *info.m_renderpassContext->m_commandBuffer;
  47. RenderPassWorkContext& rgraphCtx = *info.m_renderpassContext;
  48. // Set common state for all
  49. cmdb.setViewport(info.m_viewport.x(), info.m_viewport.y(), info.m_viewport.z(), info.m_viewport.w());
  50. // Skybox first
  51. const SkyboxComponent* skyc = SceneGraph::getSingleton().getSkybox();
  52. const LightComponent* dirLightc = SceneGraph::getSingleton().getDirectionalLight();
  53. if(skyc && !(skyc->getSkyboxType() == SkyboxType::kGenerated && !dirLightc))
  54. {
  55. cmdb.bindShaderProgram(m_skyboxGrProgs[skyc->getSkyboxType()].get());
  56. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_nearestNearestClamp.get());
  57. rgraphCtx.bindSrv(0, 0, info.m_gbufferDepthRenderTarget, info.m_gbufferDepthRenderTargetSubresource);
  58. TraditionalDeferredSkyboxConstants consts = {};
  59. consts.m_invertedViewProjectionMat = info.m_invViewProjectionMatrix;
  60. consts.m_cameraPos = info.m_cameraPosWSpace.xyz();
  61. consts.m_scale = skyc->getImageScale();
  62. consts.m_bias = skyc->getImageBias();
  63. if(skyc->getSkyboxType() == SkyboxType::kSolidColor)
  64. {
  65. consts.m_solidColor = skyc->getSolidColor();
  66. }
  67. else if(skyc->getSkyboxType() == SkyboxType::kImage2D)
  68. {
  69. cmdb.bindSampler(1, 0, getRenderer().getSamplers().m_trilinearRepeatAniso.get());
  70. cmdb.bindSrv(1, 0, TextureView(&skyc->getImageResource().getTexture(), TextureSubresourceDesc::all()));
  71. }
  72. else
  73. {
  74. cmdb.bindSampler(1, 0, getRenderer().getSamplers().m_trilinearClamp.get());
  75. rgraphCtx.bindSrv(1, 0, info.m_skyLutRenderTarget);
  76. }
  77. cmdb.bindConstantBuffer(0, 0, info.m_globalRendererConsts);
  78. cmdb.setFastConstants(&consts, sizeof(consts));
  79. drawQuad(cmdb);
  80. }
  81. // Light shading
  82. {
  83. TraditionalDeferredShadingConstants* consts = allocateAndBindConstants<TraditionalDeferredShadingConstants>(cmdb, 0, 0);
  84. consts->m_invViewProjMat = info.m_invViewProjectionMatrix;
  85. consts->m_cameraPos = info.m_cameraPosWSpace.xyz();
  86. if(dirLightc)
  87. {
  88. consts->m_dirLight.m_effectiveShadowDistance = info.m_effectiveShadowDistance;
  89. consts->m_dirLight.m_lightMatrix = info.m_dirLightMatrix;
  90. }
  91. cmdb.bindSrv(0, 0, info.m_visibleLightsBuffer);
  92. if(GpuSceneArrays::Light::getSingleton().getElementCount() > 0)
  93. {
  94. cmdb.bindSrv(1, 0, GpuSceneArrays::Light::getSingleton().getBufferView());
  95. }
  96. else
  97. {
  98. // Set something random
  99. cmdb.bindSrv(1, 0, GpuSceneBuffer::getSingleton().getBufferView());
  100. }
  101. // NOTE: Use nearest sampler because we don't want the result to sample the near tiles
  102. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_nearestNearestClamp.get());
  103. rgraphCtx.bindSrv(2, 0, info.m_gbufferRenderTargets[0], info.m_gbufferRenderTargetSubresource[0]);
  104. rgraphCtx.bindSrv(3, 0, info.m_gbufferRenderTargets[1], info.m_gbufferRenderTargetSubresource[1]);
  105. rgraphCtx.bindSrv(4, 0, info.m_gbufferRenderTargets[2], info.m_gbufferRenderTargetSubresource[2]);
  106. rgraphCtx.bindSrv(5, 0, info.m_gbufferDepthRenderTarget, info.m_gbufferDepthRenderTargetSubresource);
  107. cmdb.bindSampler(1, 0, m_shadowSampler.get());
  108. if(dirLightc && dirLightc->getShadowEnabled())
  109. {
  110. ANKI_ASSERT(info.m_directionalLightShadowmapRenderTarget.isValid());
  111. rgraphCtx.bindSrv(6, 0, info.m_directionalLightShadowmapRenderTarget, info.m_directionalLightShadowmapRenderTargetSubresource);
  112. }
  113. else
  114. {
  115. // No shadows for the dir light, bind a random depth texture (need depth because validation complains)
  116. rgraphCtx.bindSrv(6, 0, info.m_gbufferDepthRenderTarget, info.m_gbufferDepthRenderTargetSubresource);
  117. }
  118. const Bool indirectDiffuse = info.m_applyIndirectDiffuse && GpuSceneArrays::GlobalIlluminationProbe::getSingleton().getElementCount();
  119. if(indirectDiffuse)
  120. {
  121. cmdb.bindSrv(7, 0, GpuSceneArrays::GlobalIlluminationProbe::getSingleton().getBufferView());
  122. cmdb.bindSampler(2, 0, getRenderer().getSamplers().m_trilinearClamp.get());
  123. }
  124. cmdb.bindConstantBuffer(1, 0, info.m_globalRendererConsts);
  125. cmdb.bindShaderProgram(m_lightGrProg[info.m_computeSpecular][indirectDiffuse].get());
  126. drawQuad(cmdb);
  127. }
  128. }
  129. } // end namespace anki