// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "RendererInterface.h" #include "DecalRenderingCommon.h" class FDeferredDecalProxy; class FMaterial; class FMaterialRenderProxy; class FScene; class FViewInfo; class FDecalVisibilityTaskData; class FShader; class FShaderMapPointerTable; template class TShaderRefBase; template using TShaderRef = TShaderRefBase; /** * Compact deferred decal data for rendering. */ struct FVisibleDecal { FVisibleDecal(const FDeferredDecalProxy& InDecalProxy, float InConservativeRadius, float InFadeAlpha, EShaderPlatform ShaderPlatform, ERHIFeatureLevel::Type FeatureLevel); const FMaterialRenderProxy* MaterialProxy; uintptr_t Component; uint32 SortOrder; FDecalBlendDesc BlendDesc; float ConservativeRadius; float FadeAlpha; float InvFadeDuration; float InvFadeInDuration; float FadeStartDelayNormalized; float FadeInStartDelayNormalized; FLinearColor DecalColor; FTransform ComponentTrans; FBox BoxBounds; }; using FVisibleDecalList = TArray; using FRelevantDecalList = TArray; class FDecalVisibilityViewPacket { public: FDecalVisibilityViewPacket(const FDecalVisibilityTaskData& InTaskData, const FScene& Scene, const FViewInfo& InView); ~FDecalVisibilityViewPacket() { check(bFinishCalled); check(AllTasksEvent.IsCompleted()); } TConstArrayView FinishVisibleDecals(); TConstArrayView FinishRelevantDecals(EDecalRenderStage Stage); void Finish() { bFinishCalled = true; AllTasksEvent.Trigger(); AllTasksEvent.Wait(); } bool HasStage(EDecalRenderStage Stage) const { return RelevantDecalsMap.Contains(Stage); } private: const FDecalVisibilityTaskData& TaskData; const FViewInfo& View; struct FVisibleDecals { FVisibleDecalList List; UE::Tasks::FTask Task; } VisibleDecals; struct FRelevantDecals { FRelevantDecalList List; UE::Tasks::FTask Task; }; TMap RelevantDecalsMap; UE::Tasks::FTaskEvent AllTasksEvent{ UE_SOURCE_LOCATION }; bool bFinishCalled = false; }; class FDecalVisibilityTaskData { public: static FDecalVisibilityTaskData* Launch(FRDGBuilder& GraphBuilder, const FScene& Scene, TConstArrayView Views); TConstArrayView FinishVisibleDecals(int32 ViewIndex) { return ViewPackets[ViewIndex].FinishVisibleDecals(); } TConstArrayView FinishRelevantDecals(int32 ViewIndex, EDecalRenderStage Stage) { return ViewPackets[ViewIndex].FinishRelevantDecals(Stage); } bool HasStage(int32 ViewIndex, EDecalRenderStage Stage) const { return ViewPackets[ViewIndex].HasStage(Stage); } void Finish() { for (FDecalVisibilityViewPacket& ViewPacket : ViewPackets) { ViewPacket.Finish(); } } bool IsDBufferEnabled() const { return bDBufferEnabled; } bool IsGBufferEnabled() const { return bGBufferEnabled; } private: FDecalVisibilityTaskData(const FScene& Scene, TConstArrayView Views, bool bInDBufferEnabled, bool bInGBufferEnabled); const bool bDBufferEnabled; const bool bGBufferEnabled; TArray ViewPackets; friend class FDecalVisibilityViewPacket; RDG_FRIEND_ALLOCATOR_FRIEND(FDecalVisibilityTaskData); }; /** * Shared deferred decal functionality. */ namespace DecalRendering { float GetDecalFadeScreenSizeMultiplier(); float CalculateDecalFadeAlpha(float DecalFadeScreenSize, const FMatrix& ComponentToWorldMatrix, const FViewInfo& View, float FadeMultiplier); FMatrix ComputeComponentToClipMatrix(const FViewInfo& View, const FMatrix& DecalComponentToWorld); void SetVertexShaderOnly(FRHICommandList& RHICmdList, FGraphicsPipelineStateInitializer& GraphicsPSOInit, const FViewInfo& View, const FMatrix& FrustumComponentToClip); void SortDecalList(FRelevantDecalList& Decals); FVisibleDecalList BuildVisibleDecalList(TConstArrayView Decals, const FViewInfo& View); FRelevantDecalList BuildRelevantDecalList(TConstArrayView Decals, EDecalRenderStage DecalRenderStage); bool HasRelevantDecals(TConstArrayView Decals, EDecalRenderStage DecalRenderStage); bool GetShaders(ERHIFeatureLevel::Type FeatureLevel, const FMaterial& Material, EDecalRenderStage DecalRenderStage, TShaderRef& OutVertexShader, TShaderRef& OutPixelShader); bool SetupShaderState(ERHIFeatureLevel::Type FeatureLevel, const FMaterial& Material, EDecalRenderStage DecalRenderStage, FBoundShaderStateInput& OutBoundShaderState); void SetShader(FRHICommandList& RHICmdList, FGraphicsPipelineStateInitializer& GraphicsPSOInit, uint32 StencilRef, const FViewInfo& View, const FVisibleDecal& DecalData, EDecalRenderStage DecalRenderStage, const FMatrix& FrustumComponentToClip, const FScene* Scene = nullptr); };