IndirectDiffuseClipmaps.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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. #pragma once
  6. #include <AnKi/Renderer/RendererObject.h>
  7. #include <AnKi/Renderer/Utils/TraditionalDeferredShading.h>
  8. #include <AnKi/Collision/Forward.h>
  9. namespace anki {
  10. /// @addtogroup renderer
  11. /// @{
  12. ANKI_CVAR(BoolCVar, Render, Idc, true, "Enable ray traced indirect diffuse clipmaps")
  13. ANKI_CVAR2(BoolCVar, Render, Idc, InlineRt, false, "Use a cheap and less accurate path with inline RT");
  14. ANKI_CVAR2(BoolCVar, Render, Idc, UseSHL2, !ANKI_PLATFORM_MOBILE, "Use L2 SH for calculations. Else use L1");
  15. constexpr U32 kDefaultClipmapProbeCountXZ = 32;
  16. constexpr U32 kDefaultClipmapProbeCountY = 12;
  17. constexpr F32 kDefaultClipmap0ProbeSize = 1.5f;
  18. constexpr F32 kDefaultClipmap1ProbeSize = 3.0f;
  19. constexpr F32 kDefaultClipmap2ProbeSize = 6.0f;
  20. constexpr U32 kDefaultRadianceOctMapSize = 10;
  21. constexpr U32 kDefaultRayCountPerTexelOfNewProbe = 4;
  22. /// As if you are updating 25% of the probes each frame.
  23. constexpr U32 kDefaultProbeRayBudget =
  24. (kIndirectDiffuseClipmapCount * square(kDefaultClipmapProbeCountXZ) * kDefaultClipmapProbeCountY * square(kDefaultRadianceOctMapSize)) * 25 / 100;
  25. ANKI_CVAR2(NumericCVar<U32>, Render, Idc, ProbesXZ, kDefaultClipmapProbeCountXZ, 10, 100, "The cell count of each dimension of 1st clipmap")
  26. ANKI_CVAR2(NumericCVar<U32>, Render, Idc, ProbesY, kDefaultClipmapProbeCountY, 4, 100, "The cell count of each dimension of 1st clipmap")
  27. ANKI_CVAR2(NumericCVar<F32>, Render, Idc, Clipmap0XZSize, F32(kDefaultClipmapProbeCountXZ) * kDefaultClipmap0ProbeSize, 10.0, 1000.0,
  28. "The clipmap size in meters")
  29. ANKI_CVAR2(NumericCVar<F32>, Render, Idc, Clipmap0YSize, F32(kDefaultClipmapProbeCountY) * kDefaultClipmap0ProbeSize, 10.0, 1000.0,
  30. "The clipmap size in meters")
  31. ANKI_CVAR2(NumericCVar<F32>, Render, Idc, Clipmap1XZSize, F32(kDefaultClipmapProbeCountXZ) * kDefaultClipmap1ProbeSize, 10.0, 1000.0,
  32. "The clipmap size in meters")
  33. ANKI_CVAR2(NumericCVar<F32>, Render, Idc, Clipmap1YSize, F32(kDefaultClipmapProbeCountY) * kDefaultClipmap1ProbeSize, 10.0, 1000.0,
  34. "The clipmap size in meters")
  35. ANKI_CVAR2(NumericCVar<F32>, Render, Idc, Clipmap2XZSize, F32(kDefaultClipmapProbeCountXZ) * kDefaultClipmap2ProbeSize, 10.0, 1000.0,
  36. "The clipmap size in meters")
  37. ANKI_CVAR2(NumericCVar<F32>, Render, Idc, Clipmap2YSize, F32(kDefaultClipmapProbeCountY) * kDefaultClipmap2ProbeSize, 10.0, 1000.0,
  38. "The clipmap size in meters")
  39. ANKI_CVAR2(
  40. NumericCVar<U32>, Render, Idc, RadianceOctMapSize, kDefaultRadianceOctMapSize,
  41. [](U32 val) {
  42. return val >= 4 && val <= 30 && val % 2 == 0;
  43. },
  44. "Size of the octahedral for the light cache")
  45. ANKI_CVAR2(NumericCVar<U32>, Render, Idc, IrradianceOctMapSize, 5, 4, 20, "Size of the octahedral for the irradiance")
  46. ANKI_CVAR2(NumericCVar<F32>, Render, Idc, FirstBounceRayDistance, (ANKI_PLATFORM_MOBILE) ? 0.0f : 10.0f, 0.0f, 10000.0f,
  47. "For the 1st bounce shoot rays instead of sampling the clipmaps")
  48. ANKI_CVAR2(BoolCVar, Render, Idc, ApplyHighQuality, false, "If true use 1/2 resolution else use 1/4")
  49. ANKI_CVAR2(NumericCVar<U8>, Render, Idc, RayCountPerTexelOfNewProbe, kDefaultRayCountPerTexelOfNewProbe, 1, 16,
  50. "The number of rays for a single texel of the oct map that will be cast for probes that are seen for the 1st time")
  51. ANKI_CVAR2(NumericCVar<U32>, Render, Idc, ProbeRayBudget, kDefaultProbeRayBudget, 1024, 100 * 1024 * 1024,
  52. "The number of rays for a single texel of the oct map that will be cast for probes that are seen for the 1st time")
  53. /// @memberof IndirectDiffuseClipmaps
  54. class IndirectDiffuseClipmapsRenderTargetHandles
  55. {
  56. public:
  57. RenderTargetHandle m_appliedIrradiance;
  58. Array<RenderTargetHandle, kIndirectDiffuseClipmapCount> m_radianceVolumes;
  59. Array<RenderTargetHandle, kIndirectDiffuseClipmapCount> m_irradianceVolumes;
  60. Array<RenderTargetHandle, kIndirectDiffuseClipmapCount> m_distanceMomentsVolumes;
  61. Array<RenderTargetHandle, kIndirectDiffuseClipmapCount> m_probeValidityVolumes;
  62. Array<RenderTargetHandle, kIndirectDiffuseClipmapCount> m_avgIrradianceVolumes;
  63. };
  64. /// Indirect diffuse based on clipmaps of probes.
  65. class IndirectDiffuseClipmaps : public RtMaterialFetchRendererObject
  66. {
  67. public:
  68. IndirectDiffuseClipmaps()
  69. {
  70. registerDebugRenderTarget("IndirectDiffuseClipmaps");
  71. }
  72. Error init();
  73. void populateRenderGraph(RenderingContext& ctx);
  74. void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
  75. [[maybe_unused]] DebugRenderTargetDrawStyle& drawStyle) const override
  76. {
  77. handles[0] = m_runCtx.m_handles.m_appliedIrradiance;
  78. drawStyle = DebugRenderTargetDrawStyle::kTonemap;
  79. }
  80. const IndirectDiffuseClipmapConstants& getClipmapConsts() const
  81. {
  82. return m_consts;
  83. }
  84. void drawDebugProbes(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx) const;
  85. const IndirectDiffuseClipmapsRenderTargetHandles& getRts() const
  86. {
  87. return m_runCtx.m_handles;
  88. }
  89. /// Output of IndirectDiffuseClipmaps is hidden and bindless so have this function to set dependencies
  90. void setDependencies(RenderPassBase& pass, TextureUsageBit usage) const
  91. {
  92. ANKI_ASSERT(!(usage & ~TextureUsageBit::kAllSrv) && "Only SRV allowed");
  93. // Cheat and only wait for the final RT. The rest will have been waited anyway
  94. pass.newTextureDependency(m_runCtx.m_handles.m_appliedIrradiance, usage);
  95. }
  96. private:
  97. Array<TexturePtr, kIndirectDiffuseClipmapCount> m_radianceVolumes;
  98. Array<TexturePtr, kIndirectDiffuseClipmapCount> m_irradianceVolumes;
  99. Array<TexturePtr, kIndirectDiffuseClipmapCount> m_distanceMomentsVolumes;
  100. Array<TexturePtr, kIndirectDiffuseClipmapCount> m_probeValidityVolumes;
  101. Array<TexturePtr, kIndirectDiffuseClipmapCount> m_avgIrradianceVolumes;
  102. RenderTargetDesc m_rtResultRtDesc;
  103. RenderTargetDesc m_lowRezRtDesc;
  104. RenderTargetDesc m_fullRtDesc;
  105. Array<TexturePtr, 2> m_irradianceRts;
  106. IndirectDiffuseClipmapConstants m_consts;
  107. ShaderProgramResourcePtr m_prog;
  108. ShaderProgramResourcePtr m_missProg;
  109. ShaderProgramPtr m_rtLibraryGrProg;
  110. ShaderProgramPtr m_rtMaterialFetchInlineRtGrProg;
  111. ShaderProgramPtr m_populateCachesGrProg;
  112. ShaderProgramPtr m_computeIrradianceGrProg;
  113. ShaderProgramPtr m_applyGiGrProg;
  114. ShaderProgramPtr m_applyGiUsingInlineRtGrProg;
  115. ShaderProgramPtr m_visProbesGrProg;
  116. ShaderProgramPtr m_temporalDenoiseGrProg;
  117. ShaderProgramPtr m_spatialReconstructGrProg;
  118. ShaderProgramPtr m_bilateralDenoiseGrProg;
  119. ImageResourcePtr m_blueNoiseImg;
  120. U32 m_sbtRecordSize = 0;
  121. Array<U32, 2> m_rayGenShaderGroupIndices = {kMaxU32, kMaxU32};
  122. U32 m_missShaderGroupIdx = kMaxU32;
  123. Bool m_texturesImportedOnce = false;
  124. class
  125. {
  126. public:
  127. IndirectDiffuseClipmapsRenderTargetHandles m_handles;
  128. } m_runCtx;
  129. };
  130. /// @}
  131. } // end namespace anki