// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Graphics/GPUPipelineStatePermutations.h" #include "RenderList.h" #include "RendererPass.h" #include "Engine/Content/Assets/Shader.h" #include "Engine/Content/Assets/Model.h" #include "Engine/Graphics/RenderTask.h" /// /// Shadows rendering service. /// class ShadowsPass : public RendererPass { private: AssetReference _shader; AssetReference _sphereModel; GPUPipelineState* _psDepthClear = nullptr; GPUPipelineStatePermutationsPs(Quality::MAX) * 2> _psShadowDir; GPUPipelineStatePermutationsPs(Quality::MAX) * 2> _psShadowPoint; GPUPipelineStatePermutationsPs(Quality::MAX) * 2> _psShadowSpot; PixelFormat _shadowMapFormat; // Cached on initialization int32 _maxShadowsQuality = 0; // Cached state for the current frame rendering (setup via Prepare) public: /// /// Setups the shadows rendering for batched scene drawing. Checks which lights will cast a shadow. /// void SetupShadows(RenderContext& renderContext, RenderContextBatch& renderContextBatch); /// /// Renders the shadow maps for all lights (into atlas). /// void RenderShadowMaps(RenderContextBatch& renderContextBatch); /// /// Renders the shadow mask for the given light. /// /// The rendering context batch. /// The light. /// The shadow mask (output). void RenderShadowMask(RenderContextBatch& renderContextBatch, RenderLightData& light, GPUTextureView* shadowMask); /// /// Gets the shadow atlas texture and shadows buffer for shadow projection in shaders. /// /// The render buffers that store frame context. /// The output shadow map atlas texture or null if unused. /// The output shadows buffer or null if unused. static void GetShadowAtlas(const RenderBuffers* renderBuffers, GPUTexture*& shadowMapAtlas, GPUBufferView*& shadowsBuffer); private: void SetupRenderContext(RenderContext& renderContext, RenderContext& shadowContext); void SetupLight(RenderContext& renderContext, RenderContextBatch& renderContextBatch, RenderLightData& light, struct ShadowAtlasLight& atlasLight); void SetupLight(RenderContext& renderContext, RenderContextBatch& renderContextBatch, RenderLocalLightData& light, ShadowAtlasLight& atlasLight); void SetupLight(RenderContext& renderContext, RenderContextBatch& renderContextBatch, RenderDirectionalLightData& light, ShadowAtlasLight& atlasLight); void SetupLight(RenderContext& renderContext, RenderContextBatch& renderContextBatch, RenderPointLightData& light, ShadowAtlasLight& atlasLight); void SetupLight(RenderContext& renderContext, RenderContextBatch& renderContextBatch, RenderSpotLightData& light, ShadowAtlasLight& atlasLight); #if COMPILE_WITH_DEV_ENV void OnShaderReloading(Asset* obj) { _psShadowDir.Release(); _psShadowPoint.Release(); _psShadowSpot.Release(); invalidateResources(); } #endif public: // [RendererPass] String ToString() const override; bool Init() override; void Dispose() override; protected: // [RendererPass] bool setupResources() override; };