// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #include "RendererPass.h" #include "Engine/Core/Math/Vector3.h" /// /// Global Sign Distance Field (SDF) rendering pass. Composites scene geometry into series of 3D volume textures that cover the world around the camera for global distance field sampling. /// class FLAXENGINE_API GlobalSignDistanceFieldPass : public RendererPass { public: // Constant buffer data for Global SDF access on a GPU. PACK_STRUCT(struct ConstantsData { Float4 CascadePosDistance[4]; Float4 CascadeVoxelSize; Float2 Padding; uint32 CascadesCount; float Resolution; }); // Binding data for the GPU. struct BindingData { GPUTexture* Texture; GPUTexture* TextureMip; ConstantsData Constants; }; private: bool _supported = false; AssetReference _shader; GPUPipelineState* _psDebug = nullptr; GPUShaderProgramCS* _csRasterizeModel0 = nullptr; GPUShaderProgramCS* _csRasterizeModel1 = nullptr; GPUShaderProgramCS* _csRasterizeHeightfield = nullptr; GPUShaderProgramCS* _csClearChunk = nullptr; GPUShaderProgramCS* _csGenerateMip = nullptr; GPUConstantBuffer* _cb0 = nullptr; GPUConstantBuffer* _cb1 = nullptr; // Rasterization cache class DynamicStructuredBuffer* _objectsBuffer = nullptr; Array _objectsTextures; uint16 _objectsBufferCount; int32 _cascadeIndex; float _voxelSize, _chunkSize; BoundingBox _cascadeBounds; BoundingBox _cascadeCullingBounds; class GlobalSignDistanceFieldCustomBuffer* _sdfData; Vector3 _sdfDataOriginMin; Vector3 _sdfDataOriginMax; public: /// /// Gets the Global SDF (only if enabled in Graphics Settings). /// /// The rendering context buffers. /// The result Global SDF data for binding to the shaders. /// True if there is no valid Global SDF rendered during this frame, otherwise false. bool Get(const RenderBuffers* buffers, BindingData& result); /// /// Renders the Global SDF. /// /// The rendering context. /// The GPU context. /// The result Global SDF data for binding to the shaders. /// True if failed to render (platform doesn't support it, out of video memory, disabled feature or effect is not ready), otherwise false. bool Render(RenderContext& renderContext, GPUContext* context, BindingData& result); /// /// Renders the debug view. /// /// The rendering context. /// The GPU context. /// The output buffer. void RenderDebug(RenderContext& renderContext, GPUContext* context, GPUTexture* output); void GetCullingData(BoundingBox& bounds) const { bounds = _cascadeCullingBounds; } // Rasterize Model SDF into the Global SDF. Call it from actor Draw() method during DrawPass::GlobalSDF. void RasterizeModelSDF(Actor* actor, const ModelBase::SDFData& sdf, const Transform& localToWorld, const BoundingBox& objectBounds); void RasterizeHeightfield(Actor* actor, GPUTexture* heightfield, const Transform& localToWorld, const BoundingBox& objectBounds, const Float4& localToUV); private: #if COMPILE_WITH_DEV_ENV void OnShaderReloading(Asset* obj); #endif public: // [RendererPass] String ToString() const override; bool Init() override; void Dispose() override; protected: // [RendererPass] bool setupResources() override; };