// 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 /// @{ /// Shadowmapping pass class ShadowMapping : public RendererObject { public: ShadowMapping(Renderer* r) : RendererObject(r) { } ~ShadowMapping(); ANKI_USE_RESULT Error init(const ConfigSet& initializer); /// Populate the rendergraph. void populateRenderGraph(RenderingContext& ctx); RenderTargetHandle getShadowmapRt() const { return m_atlas.m_rt; } private: using Viewport = Array; /// @name Atlas stuff /// @{ class Atlas { public: class ResolveWorkItem; TileAllocator m_tileAlloc; TexturePtr m_tex; ///< Size (m_tileResolution*m_tileCountBothAxis)^2 RenderTargetHandle m_rt; U32 m_tileResolution = 0; ///< Tile resolution. U32 m_tileCountBothAxis = 0; ShaderProgramResourcePtr m_resolveProg; ShaderProgramPtr m_resolveGrProg; WeakArray m_resolveWorkItems; } m_atlas; ANKI_USE_RESULT Error initAtlas(const ConfigSet& cfg); inline Mat4 createSpotLightTextureMatrix(const Viewport& viewport) const; void runAtlas(RenderPassWorkContext& rgraphCtx); /// @} /// @name Scratch buffer stuff /// @{ class Scratch { public: class WorkItem; class LightToRenderToScratchInfo; TileAllocator m_tileAlloc; RenderTargetHandle m_rt; ///< Size of the RT is (m_tileSize * m_tileCount, m_tileSize). FramebufferDescription m_fbDescr; ///< FB info. RenderTargetDescription m_rtDescr; ///< Render target. U32 m_tileCountX = 0; U32 m_tileCountY = 0; U32 m_tileResolution = 0; WeakArray m_workItems; U32 m_maxViewportWidth = 0; U32 m_maxViewportHeight = 0; } m_scratch; ANKI_USE_RESULT Error initScratch(const ConfigSet& cfg); void runShadowMapping(RenderPassWorkContext& rgraphCtx); /// @} /// @name Misc & common /// @{ static constexpr U32 m_pointLightsMaxLod = 1; Array m_lodDistances; /// Find the lod of the light void chooseLod(const Vec4& cameraOrigin, const PointLightQueueElement& light, Bool& blurAtlas, U32& tileBufferLod, U32& renderQueueElementsLod) const; /// Find the lod of the light void chooseLod(const Vec4& cameraOrigin, const SpotLightQueueElement& light, Bool& blurAtlas, U32& tileBufferLod, U32& renderQueueElementsLod) const; /// Try to allocate a number of scratch tiles and regular tiles. TileAllocatorResult allocateTilesAndScratchTiles(U64 lightUuid, U32 faceCount, const U64* faceTimestamps, const U32* faceIndices, const U32* drawcallsCount, const U32* lods, Viewport* atlasTileViewports, Viewport* scratchTileViewports, TileAllocatorResult* subResults); /// Add new work to render to scratch buffer and atlas buffer. void newScratchAndAtlasResloveRenderWorkItems( const Viewport& atlasViewport, const Viewport& scratchVewport, Bool blurAtlas, RenderQueue* lightRenderQueue, U32 renderQueueElementsLod, DynamicArrayAuto& scratchWorkItem, DynamicArrayAuto& atlasResolveWorkItem, U32& drawcallCount) const; /// Iterate lights and create work items. void processLights(RenderingContext& ctx, U32& threadCountForScratchPass); ANKI_USE_RESULT Error initInternal(const ConfigSet& config); /// @} }; /// @} } // end namespace anki