// Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors. // All rights reserved. // Code licensed under the BSD License. // http://www.anki3d.org/LICENSE #pragma once #include #include #include #include namespace anki { /// @addtogroup renderer /// @{ /// Probe reflections. class ProbeReflections : public RendererObject { friend class IrTask; public: ProbeReflections(Renderer* r); ~ProbeReflections(); ANKI_USE_RESULT Error init(const ConfigSet& cfg); /// Populate the rendergraph. void populateRenderGraph(RenderingContext& ctx); U getReflectionTextureMipmapCount() const { return m_lightShading.m_mipCount; } TextureViewPtr getIntegrationLut() const { return m_integrationLut->getTextureView(); } SamplerPtr getIntegrationLutSampler() const { return m_integrationLutSampler; } RenderTargetHandle getReflectionRt() const { return m_ctx.m_lightShadingRt; } private: class { public: U32 m_tileSize = 0; Array m_colorRtDescrs; RenderTargetDescription m_depthRtDescr; FramebufferDescription m_fbDescr; } m_gbuffer; ///< G-buffer pass. class LS { public: U32 m_tileSize = 0; U32 m_mipCount = 0; TexturePtr m_cubeArr; TraditionalDeferredLightShading m_deferred; LS(Renderer* r) : m_deferred(r) { } } m_lightShading; ///< Light shading. class { public: ShaderProgramResourcePtr m_prog; ShaderProgramPtr m_grProg; BufferPtr m_diceValuesBuff; U32 m_workgroupSize = 16; } m_irradiance; ///< Irradiance. class { public: ShaderProgramResourcePtr m_prog; ShaderProgramPtr m_grProg; } m_irradianceToRefl; ///< Apply irradiance back to the reflection. class { public: RenderTargetDescription m_rtDescr; FramebufferDescription m_fbDescr; SamplerPtr m_shadowSampler; } m_shadowMapping; class CacheEntry { public: U64 m_uuid; ///< Probe UUID. Timestamp m_lastUsedTimestamp = 0; ///< When it was last seen by the renderer. Array m_lightShadingFbDescrs; }; DynamicArray m_cacheEntries; HashMap m_probeUuidToCacheEntryIdx; // Other ImageResourcePtr m_integrationLut; SamplerPtr m_integrationLutSampler; class { public: const ReflectionProbeQueueElement* m_probe = nullptr; U32 m_cacheEntryIdx = MAX_U32; Array m_gbufferColorRts; RenderTargetHandle m_gbufferDepthRt; RenderTargetHandle m_lightShadingRt; BufferHandle m_irradianceDiceValuesBuffHandle; RenderTargetHandle m_shadowMapRt; U32 m_gbufferRenderableCount = 0; U32 m_shadowRenderableCount = 0; } m_ctx; ///< Runtime context. ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg); ANKI_USE_RESULT Error initGBuffer(const ConfigSet& cfg); ANKI_USE_RESULT Error initLightShading(const ConfigSet& cfg); ANKI_USE_RESULT Error initIrradiance(const ConfigSet& cfg); ANKI_USE_RESULT Error initIrradianceToRefl(const ConfigSet& cfg); ANKI_USE_RESULT Error initShadowMapping(const ConfigSet& cfg); /// Lazily init the cache entry void initCacheEntry(U32 cacheEntryIdx); void prepareProbes(RenderingContext& ctx, ReflectionProbeQueueElement*& probeToUpdate, U32& probeToUpdateCacheEntryIdx); void runGBuffer(RenderPassWorkContext& rgraphCtx); void runShadowMapping(RenderPassWorkContext& rgraphCtx); void runLightShading(U32 faceIdx, RenderPassWorkContext& rgraphCtx); void runMipmappingOfLightShading(U32 faceIdx, RenderPassWorkContext& rgraphCtx); void runIrradiance(RenderPassWorkContext& rgraphCtx); void runIrradianceToRefl(RenderPassWorkContext& rgraphCtx); // A RenderPassWorkCallback for the light shading pass into a single face. template static void runLightShadingCallback(RenderPassWorkContext& rgraphCtx) { ProbeReflections* const self = static_cast(rgraphCtx.m_userData); self->runLightShading(faceIdx, rgraphCtx); } // A RenderPassWorkCallback for the mipmapping of light shading result. template static void runMipmappingOfLightShadingCallback(RenderPassWorkContext& rgraphCtx) { ProbeReflections* const self = static_cast(rgraphCtx.m_userData); self->runMipmappingOfLightShading(faceIdx, rgraphCtx); } }; /// @} } // end namespace anki