Files
UnrealEngine/Engine/Source/Runtime/Renderer/Private/VirtualShadowMaps/VirtualShadowMapClipmap.h
2025-05-18 13:04:45 +08:00

184 lines
5.4 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
VirtualShadowMapClipmap.h
=============================================================================*/
#pragma once
#include "CoreMinimal.h"
#include "ConvexVolume.h"
#include "Templates/RefCounting.h"
#include "VirtualShadowMapProjection.h"
struct FViewMatrices;
struct FVirtualShadowMapProjectionShaderData;
class FPrimitiveSceneInfo;
class FVirtualShadowMap;
class FVirtualShadowMapArray;
class FVirtualShadowMapArrayCacheManager;
class FVirtualShadowMapPerLightCacheEntry;
bool IsVirtualShadowMapDirectionalReceiverMaskEnabled();
class FVirtualShadowMapClipmapConfig
{
public:
static FVirtualShadowMapClipmapConfig GetGlobal();
int32 FirstLevel = 8;
int32 LastLevel = 18;
int32 FirstCoarseLevel = -1;
int32 LastCoarseLevel = -1;
uint32 ShadowTypeId = 0u;
float ResolutionLodBias = 0.0f;
float ResolutionLodBiasMoving = 0.0f;
bool bForceInvalidate = false;
bool bIsFirstPersonShadow = false;
bool bCullDynamicTightly = false;
bool bUseReceiverMask = false;
};
class FVirtualShadowMapClipmap : FRefCountedObject
{
public:
FVirtualShadowMapClipmap(
FVirtualShadowMapArray& VirtualShadowMapArray,
const FLightSceneInfo& InLightSceneInfo,
const FViewMatrices& CameraViewMatrices,
FIntPoint CameraViewRectSize,
const FViewInfo* InDependentView,
float LightMobilityFactor,
const FVirtualShadowMapClipmapConfig& Config = FVirtualShadowMapClipmapConfig::GetGlobal()
);
FViewMatrices GetViewMatrices(int32 ClipmapIndex) const;
FVector2f GetDynamicDepthCullRange(int32 ClipmapIndex) const
{
check(ClipmapIndex >= 0 && ClipmapIndex < LevelData.Num());
return LevelData[ClipmapIndex].DynamicDepthCullRange;
}
int32 GetVirtualShadowMapId(int32 ClipmapIndex = 0) const
{
return VirtualShadowMapId + ClipmapIndex;
}
int32 GetLevelCount() const
{
return LevelData.Num();
}
// Get absolute clipmap level from index (0..GetLevelCount())
int32 GetClipmapLevel(int32 ClipmapIndex) const
{
return FirstLevel + ClipmapIndex;
}
FVector GetPreViewTranslation(int32 ClipmapIndex) const
{
return -LevelData[ClipmapIndex].WorldCenter;
}
FMatrix GetViewToClipMatrix(int32 ClipmapIndex) const
{
return LevelData[ClipmapIndex].ViewToClip;
}
FMatrix GetWorldToLightViewRotationMatrix() const
{
return WorldToLightViewRotationMatrix;
}
const FLightSceneInfo& GetLightSceneInfo() const
{
return LightSceneInfo;
}
const FVirtualShadowMapProjectionShaderData& GetProjectionShaderData(int32 ClipmapIndex) const;
FVector GetWorldOrigin() const
{
return WorldOrigin;
}
static float GetLevelRadius(float AbsoluteLevel);
// Returns the max radius the clipmap is guaranteed to cover (i.e. the radius of the last clipmap level)
// Note that this is not a conservative radius of the level projection, which is snapped
float GetMaxRadius() const;
FSphere GetBoundingSphere() const { return BoundingSphere; }
FConvexVolume GetViewFrustumBounds() const { return ViewFrustumBounds; }
const FViewInfo* GetDependentView() const { return DependentView; }
/**
* Called when a primitive passes CPU-culling, note that this applies to non-nanite primitives only. Not thread safe in general.
*/
void OnPrimitiveRendered(const FPrimitiveSceneInfo* PrimitiveSceneInfo);
/**
* Called to push any cache data to cache entry at the end of the frame.
*/
void UpdateCachedFrameData();
TSharedPtr<FVirtualShadowMapPerLightCacheEntry>& GetCacheEntry() { return PerLightCacheEntry; }
/**
* Whether the clipmap is for casting shadow of FirstPersonWorldSpaceRepresentation primitives onto the scene.
*/
bool IsFirstPersonShadow() const { return Config.bIsFirstPersonShadow; }
private:
FVirtualShadowMapProjectionShaderData ComputeProjectionShaderData(int32 ClipmapIndex) const;
void ComputeBoundingVolumes(const FVector CameraOrigin);
FVirtualShadowMapClipmapConfig Config;
const FLightSceneInfo& LightSceneInfo;
/**
* DependentView is the 'main' or visible geometry view that this view-dependent clipmap was created for. Should only be used to
* identify the view during shadow projection (note: this should be refactored to be more explicit instead).
*/
const FViewInfo* DependentView;
/** Origin of the clipmap in world space
* Usually aligns with the camera position from which it was created.
* Note that the centers of each of the levels can be different as they are snapped to page alignment at their respective scales
* */
FVector WorldOrigin;
FVector CameraToViewTarget;
FVector LightDirection;
/** Directional light rotation matrix (no translation) */
FMatrix WorldToLightViewRotationMatrix;
int32 FirstLevel;
float ResolutionLodBias;
struct FLevelData
{
FMatrix ViewToClip;
FVector WorldCenter;
//Offset from (0,0) to clipmap corner, in level radii
FInt64Point CornerOffset;
//Offset from LastLevel-snapped WorldCenter to clipmap corner, in level radii
FIntPoint RelativeCornerOffset;
double WPODistanceDisableThresholdSquared;
FVector2f DynamicDepthCullRange;
};
TArray< FLevelData, TInlineAllocator<32> > LevelData;
FSphere BoundingSphere;
FConvexVolume ViewFrustumBounds;
int32 VirtualShadowMapId = INDEX_NONE; // Base ID; levels are contiguous
TSharedPtr<FVirtualShadowMapPerLightCacheEntry> PerLightCacheEntry;
// Rendered primitives are marked during culling (through OnPrimitiveRendered being called).
TBitArray<> RenderedPrimitives;
};