Files
UnrealEngine/Engine/Plugins/Runtime/nDisplay/Source/DisplayClusterLightCardEditorShaders/Public/DisplayClusterMeshProjectionRenderer.h
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

308 lines
13 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "SceneView.h"
class AActor;
class UPrimitiveComponent;
class FHitProxyConsumer;
class FSceneView;
class FViewInfo;
class FPrimitiveDrawInterface;
class FPrimitiveSceneProxy;
class FRDGBuilder;
class FSimpleElementCollector;
class FMeshProjectionPassParameters;
struct FEngineShowFlags;
/** Indicates which kind of projection is used by the renderer */
enum EDisplayClusterMeshProjectionType
{
/** Default linear projection */
Linear,
/** Non-linear spherical projection based on the azimuthal equidistant map projection */
Azimuthal,
/** Projection that positions vertices based on their UV coordinates */
UV
};
/** Indicates the quantity that is output to the canvas by the renderer */
enum EDisplayClusterMeshProjectionOutput
{
/** Outputs the emissive color of the rendered primitives */
Color,
/** Outputs the normals and depth of the rendered primitives */
Normals
};
/** A filter that allows specific primitive components to be filtered from a render pass */
class FDisplayClusterMeshProjectionPrimitiveFilter
{
public:
DECLARE_DELEGATE_RetVal_OneParam(bool, FPrimitiveFilter, const UPrimitiveComponent*);
/** A delegate that returns true if the primitive component should be included in the render pass */
FPrimitiveFilter ShouldRenderPrimitiveDelegate;
/** A delegate that returns true if the primitive component should be rendered using the render pass's projection type */
FPrimitiveFilter ShouldApplyProjectionDelegate;
/** Gets whether a primitive component should be filtered out of the render pass or not */
DISPLAYCLUSTERLIGHTCARDEDITORSHADERS_API bool ShouldRenderPrimitive(const UPrimitiveComponent* InPrimitiveComponent) const;
/** Gets whether a primitive component should be rendered using the current projection type or not */
DISPLAYCLUSTERLIGHTCARDEDITORSHADERS_API bool ShouldApplyProjection(const UPrimitiveComponent* InPrimitiveComponent) const;
};
/** Settings for specific mesh projection types */
struct FDisplayClusterMeshProjectionTypeSettings
{
/** The index of the UV to use when performing a UV projection */
uint32 UVProjectionIndex = 0;
/** The size of the plane the UVs are projected to, in view space */
float UVProjectionPlaneSize = 100.0f;
/** The distance from the view point of the plane the UVs are projected to, in view space */
float UVProjectionPlaneDistance = 100.0f;
/** A translation offset for the UV projection plane */
FVector UVProjectionPlaneOffset = FVector::ZeroVector;
};
/** Settings for producing a single render. */
struct FDisplayClusterMeshProjectionRenderSettings
{
/** Camera setup options for the render. */
FSceneViewInitOptions ViewInitOptions;
/**
* Flags controlling renderer features to enable/disable for this preview.
* Only flags supported by FDisplayClusterMeshProjectionRenderer will have an impact on the render output.
*/
FEngineShowFlags EngineShowFlags = FEngineShowFlags(ESFIM_Editor);
/** Type of projection to use for the renderer. */
EDisplayClusterMeshProjectionType ProjectionType = EDisplayClusterMeshProjectionType::Azimuthal;
/** Settings used by the projection type when rendering */
FDisplayClusterMeshProjectionTypeSettings ProjectionTypeSettings;
/** The output type to use for the renderer. */
EDisplayClusterMeshProjectionOutput RenderType = EDisplayClusterMeshProjectionOutput::Color;
/** A matrix used to rotate the normals in order to account for the root actor's rotation. */
FMatrix44f NormalCorrectionMatrix = FMatrix44f::Identity;
/**
* Optional filter to prevent specific primitives from being rendered.
* This only applies when RenderType is ERenderType::Normals.
*/
FDisplayClusterMeshProjectionPrimitiveFilter PrimitiveFilter;
};
/** A transform that can be passed around to project and unprojection positions for a specific projection type */
class FDisplayClusterMeshProjectionTransform
{
public:
FDisplayClusterMeshProjectionTransform()
: FDisplayClusterMeshProjectionTransform(EDisplayClusterMeshProjectionType::Linear, FMatrix::Identity)
{ }
FDisplayClusterMeshProjectionTransform(EDisplayClusterMeshProjectionType InProjection, const FMatrix& InViewMatrix)
: Projection(InProjection)
, ViewMatrix(InViewMatrix)
, InvViewMatrix(InViewMatrix.Inverse())
{ }
DISPLAYCLUSTERLIGHTCARDEDITORSHADERS_API FVector ProjectPosition(const FVector& WorldPosition) const;
DISPLAYCLUSTERLIGHTCARDEDITORSHADERS_API FVector UnprojectPosition(const FVector& ProjectedPosition) const;
private:
EDisplayClusterMeshProjectionType Projection;
FMatrix ViewMatrix;
FMatrix InvViewMatrix;
};
/** A renderer that projects meshes to screen space using non-linear projection methods */
class FDisplayClusterMeshProjectionRenderer
{
public:
/** Clean up any references to the renderer. */
DISPLAYCLUSTERLIGHTCARDEDITORSHADERS_API ~FDisplayClusterMeshProjectionRenderer();
/** Projects a position in view coordinates into the projected view space of the specified projection type */
DISPLAYCLUSTERLIGHTCARDEDITORSHADERS_API static FVector ProjectViewPosition(const FVector& ViewPosition, EDisplayClusterMeshProjectionType ProjectionType);
/** Projects a position in the projected view space of the specified projection type to ordinary view coordinates */
DISPLAYCLUSTERLIGHTCARDEDITORSHADERS_API static FVector UnprojectViewPosition(const FVector& ProjectedViewPosition, EDisplayClusterMeshProjectionType ProjectionType);
/** Adds an actor's primitive components to the list of primitives to render */
DISPLAYCLUSTERLIGHTCARDEDITORSHADERS_API void AddActor(AActor* Actor);
/** Adds an actor's primitive components to the list of primitives to render, filtering which primitive components get rendered using the specified callback */
DISPLAYCLUSTERLIGHTCARDEDITORSHADERS_API void AddActor(AActor* Actor, const TFunctionRef<bool(const UPrimitiveComponent*)>& PrimitiveFilter);
/** Removes an actor's primitive components from the list of primitives to render */
DISPLAYCLUSTERLIGHTCARDEDITORSHADERS_API void RemoveActor(AActor* Actor);
/** Clears the list of primitives to render */
DISPLAYCLUSTERLIGHTCARDEDITORSHADERS_API void ClearScene();
/**
* Renders its list of primitive components to the specified canvas using the desired projection type. Can be called from either the game thread or the rendering thread.
*/
DISPLAYCLUSTERLIGHTCARDEDITORSHADERS_API void Render(FCanvas* Canvas, FSceneInterface* Scene, const FDisplayClusterMeshProjectionRenderSettings& RenderSettings);
/**
* Renders its list of primitive components to the specified canvas using the desired projection type. Can be called from either the game thread or the rendering thread.
* Render scene by scene
*/
DISPLAYCLUSTERLIGHTCARDEDITORSHADERS_API void RenderScenes(FCanvas* Canvas, const TArray<FSceneInterface*>& Scenes, const FDisplayClusterMeshProjectionRenderSettings& RenderSettings);
private:
/** Constructs the necessary render passes for the default output of the rendered primitives */
void RenderColorOutput(FRDGBuilder& GraphBuilder,
const FSceneView* View,
const FDisplayClusterMeshProjectionRenderSettings& RenderSettings,
FRenderTargetBinding& OutputRenderTargetBinding);
/** Constructs the necessary render passes for the default output of the rendered primitives */
void RenderColorOutputs(FRDGBuilder& GraphBuilder,
const TArray<const FSceneView*>& Views,
const FDisplayClusterMeshProjectionRenderSettings& RenderSettings,
FRenderTargetBinding& OutputRenderTargetBinding);
/** Constructs the necessary render passes for the hit proxy output of the rendered primitives */
void RenderHitProxyOutput(FRDGBuilder& GraphBuilder,
const FSceneView* View,
const FDisplayClusterMeshProjectionRenderSettings& RenderSettings,
FRenderTargetBinding& OutputRenderTargetBinding,
FHitProxyConsumer* HitProxyConsumer);
/** Constructs the necessary render passes for the normals/depth output of the rendered primitives */
void RenderNormalsOutput(FRDGBuilder& GraphBuilder,
const FSceneView* View,
const FDisplayClusterMeshProjectionRenderSettings& RenderSettings,
FRenderTargetBinding& OutputRenderTargetBinding);
/** Adds a pass to perform the base render for the mesh projection. */
void AddBaseRenderPass(FRDGBuilder& GraphBuilder,
const FSceneView* View,
const FDisplayClusterMeshProjectionRenderSettings& RenderSettings,
FRenderTargetBinding& OutputRenderTargetBinding,
FDepthStencilBinding& OutputDepthStencilBinding);
/** Adds a pass to perform the translucency render for the mesh projection. */
void AddTranslucencyRenderPass(FRDGBuilder& GraphBuilder,
const FSceneView* View,
const FDisplayClusterMeshProjectionRenderSettings& RenderSettings,
FRenderTargetBinding& OutputRenderTargetBinding,
FDepthStencilBinding& OutputDepthStencilBinding);
/** Adds a pass to perform the hit proxy render for the mesh projection */
void AddHitProxyRenderPass(FRDGBuilder& GraphBuilder,
const FSceneView* View,
const FDisplayClusterMeshProjectionRenderSettings& RenderSettings,
FRenderTargetBinding& OutputRenderTargetBinding,
FDepthStencilBinding& OutputDepthStencilBinding);
/** Adds a pass to perform a render of the primitives' normals for the mesh projection */
void AddNormalsRenderPass(FRDGBuilder& GraphBuilder,
const FSceneView* View,
const FDisplayClusterMeshProjectionRenderSettings& RenderSettings,
FRenderTargetBinding& OutputRenderTargetBinding,
FDepthStencilBinding& OutputDepthStencilBinding);
/** Adds a pass to filter the output normal map for the mesh projection, dilating and blurring it
* to obtain a continuous normal map from primitives into empty space */
void AddNormalsFilterPass(FRDGBuilder& GraphBuilder,
const FSceneView* View,
FRenderTargetBinding& OutputRenderTargetBinding,
FRDGTexture* SceneColor,
FRDGTexture* SceneDepth,
const FMatrix44f& NormalCorrectionMatrix);
#if WITH_EDITOR
/** Adds a pass to perform the depth render for any selected primitives for the mesh projection */
void AddSelectionDepthRenderPass(FRDGBuilder& GraphBuilder,
const FSceneView* View,
const FDisplayClusterMeshProjectionRenderSettings& RenderSettings,
FDepthStencilBinding& OutputDepthStencilBinding);
/** Adds a pass to perform the post process selection outline for the mesh projection */
void AddSelectionOutlineScreenPass(FRDGBuilder& GraphBuilder,
const FSceneView* View,
FRenderTargetBinding& OutputRenderTargetBinding,
FRDGTexture* SceneColor,
FRDGTexture* SceneDepth,
FRDGTexture* SelectionDepth);
#endif
/** Adds a pass that renders any elements added to the PDI through the renderer's RenderSimpleElements callback */
void AddSimpleElementPass(FRDGBuilder& GraphBuilder,
const FSceneView* View,
FRenderTargetBinding& OutputRenderTargetBinding,
FSimpleElementCollector& ElementCollector);
/** Renders the list of primitive components using the appropriate mesh pass processor given by the template parameter */
template<EDisplayClusterMeshProjectionType ProjectionType>
void RenderPrimitives_RenderThread(const FSceneView* View,
FRHICommandList& RHICmdList,
const FDisplayClusterMeshProjectionRenderSettings& RenderSettings,
bool bTranslucencyPass);
/** Renders the hit proxies of the list of primitive components using the appropriate mesh pass processor given by the template parameter */
template<EDisplayClusterMeshProjectionType ProjectionType>
void RenderHitProxies_RenderThread(const FSceneView* View,
FRHICommandList& RHICmdList,
const FDisplayClusterMeshProjectionRenderSettings& RenderSettings);
/** Renders the normals of the list of primitive components using the appropriate mesh pass processor given by the template parameter */
template<EDisplayClusterMeshProjectionType ProjectionType>
void RenderNormals_RenderThread(const FSceneView* View,
FRHICommandList& RHICmdList,
const FDisplayClusterMeshProjectionRenderSettings& RenderSettings);
#if WITH_EDITOR
/** Renders the list of primitive components using the appropriate mesh pass processor given by the template parameter */
template<EDisplayClusterMeshProjectionType ProjectionType>
void RenderSelection_RenderThread(const FSceneView* View,
FRHICommandList& RHICmdList,
const FDisplayClusterMeshProjectionRenderSettings& RenderSettings);
#endif
/** Callback used to determine if a primitive component should be rendered with a selection outline */
bool IsPrimitiveComponentSelected(const UPrimitiveComponent* InPrimitiveComponent);
/** Data struct that contains the scene proxy and the render configuration needed to render the scene's primitive components */
struct FSceneProxyElement
{
FPrimitiveSceneProxy* PrimitiveSceneProxy;
bool bApplyProjection;
};
/** Collects all valid scene proxies to be rendered from the scene's primitive componets */
void GetSceneProxies(TArray<FSceneProxyElement>& OutSceneProxyElements,
const FDisplayClusterMeshProjectionRenderSettings& RenderSettings,
const TFunctionRef<bool(const UPrimitiveComponent*)> PrimitiveFilter = [](const UPrimitiveComponent*) { return true; });
public:
/** Delegate to determine if an actor should be rendered as selected */
DECLARE_DELEGATE_RetVal_OneParam(bool, FSelection, const AActor*);
FSelection ActorSelectedDelegate;
/** Delegate raised during a render pass allowing simple elements ro be rendered to the viewport after meshes are projected to it */
DECLARE_DELEGATE_TwoParams(FSimpleElementPass, const FSceneView*, FPrimitiveDrawInterface*);
FSimpleElementPass RenderSimpleElementsDelegate;
private:
/** The list of primitive components to render */
TArray<TWeakObjectPtr<UPrimitiveComponent>> PrimitiveComponents;
};