// Copyright (c) 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; GPUPipelineState* _psDepthCopy = nullptr; GPUPipelineStatePermutationsPs _psShadowDir; GPUPipelineStatePermutationsPs _psShadowPoint; GPUPipelineStatePermutationsPs _psShadowPointInside; GPUPipelineStatePermutationsPs _psShadowSpot; GPUPipelineStatePermutationsPs _psShadowSpotInside; PixelFormat _shadowMapFormat; // Cached on initialization 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: static void SetupRenderContext(RenderContext& renderContext, RenderContext& shadowContext, struct ShadowAtlasLight* atlasLight = nullptr, RenderContext* dynamicContext = nullptr); static void SetupLight(class ShadowsCustomBuffer& shadows, RenderContext& renderContext, RenderContextBatch& renderContextBatch, RenderLightData& light, ShadowAtlasLight& atlasLight); static bool SetupLight(ShadowsCustomBuffer& shadows, RenderContext& renderContext, RenderContextBatch& renderContextBatch, RenderLocalLightData& light, ShadowAtlasLight& atlasLight); static void SetupLight(ShadowsCustomBuffer& shadows, RenderContext& renderContext, RenderContextBatch& renderContextBatch, RenderDirectionalLightData& light, ShadowAtlasLight& atlasLight); static void SetupLight(ShadowsCustomBuffer& shadows, RenderContext& renderContext, RenderContextBatch& renderContextBatch, RenderPointLightData& light, ShadowAtlasLight& atlasLight); static void SetupLight(ShadowsCustomBuffer& shadows, RenderContext& renderContext, RenderContextBatch& renderContextBatch, RenderSpotLightData& light, ShadowAtlasLight& atlasLight); void ClearShadowMapTile(GPUContext* context, GPUConstantBuffer* quadShaderCB, struct QuadShaderData& quadShaderData) const; void CopyShadowMapTile(GPUContext* context, GPUConstantBuffer* quadShaderCB, struct QuadShaderData& quadShaderData, const GPUTexture* srcShadowMap, const struct ShadowsAtlasRectTile* srcTile) const; #if COMPILE_WITH_DEV_ENV void OnShaderReloading(Asset* obj) { _psShadowDir.Release(); _psShadowPoint.Release(); _psShadowPointInside.Release(); _psShadowSpot.Release(); _psShadowSpotInside.Release(); invalidateResources(); } #endif public: // [RendererPass] String ToString() const override; bool Init() override; void Dispose() override; protected: // [RendererPass] bool setupResources() override; };