UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
SceneCulling.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreMinimal.h"
6#include "SpanAllocator.h"
7#include "ConvexVolume.h"
9#include "Tasks/Task.h"
10#include "RendererInterface.h"
12#include "PrimitiveSceneInfo.h"
13
14#include "SceneCullingDefinitions.h"
17#include "SceneExtensions.h"
18
21class FScene;
22struct FPrimitiveBounds;
23
28{
29 // Negative translation to add to the tested location prior to testing the ConvexVolume.
32 // Bounding sphere in world space, if radius is zero OR the footprint is <= r.SceneCulling.SmallFootprintSideThreshold, the ConvexVolume is used
34};
35
36
38
40{
42public:
44
46
52 {
54 public:
55
57
58 virtual void PreSceneUpdate(FRDGBuilder& GraphBuilder, const FScenePreUpdateChangeSet& ChangeSet, FSceneUniformBuffer& SceneUniforms) override;
59 virtual void PostSceneUpdate(FRDGBuilder& GraphBuilder, const FScenePostUpdateChangeSet& ChangeSet) override;
60
61 ~FUpdater();
62
63 private:
64 friend class FSceneCulling;
65
66 UE::Tasks::FTask PreUpdateTaskHandle;
67
68 FSceneCullingBuilder *Implementation = nullptr;
69 FSceneCulling& SceneCulling;
70
71#if DO_CHECK
72 std::atomic<int32> DebugTaskCounter = 0;
73#endif
74 };
75 // ISceneExtension API
79
80 // end ISceneExtension
81
86 void EndUpdate(FRDGBuilder& GraphBuilder, FSceneUniformBuffer& SceneUniformBuffer, bool bPublishStats);
87
89
90 bool IsEnabled() const { return bIsEnabled; }
91
92 void PublishStats();
93
94#if 0
95 // This implementation is not currently used (and the data structures have changed somewhat) but is kept for reference.
97#endif
98 template <typename ResultConsumerType>
100
101 struct alignas(16) FBlockLocAligned
102 {
104
106 : Data(int32(InLoc.Coord.X), int32(InLoc.Coord.Y), int32(InLoc.Coord.Z), int32(InLoc.Level))
107 {
108 }
109
111 {
112 return Data == BlockLocAligned.Data;
113 }
114
119 FORCEINLINE int32 GetLevel() const { return Data.W; }
120
122
128
130 {
131 using UIntType = std::make_unsigned_t<FIntVector4::IntType>;
132
133 // TODO: Vectorize? Maybe convert to float vector & use dot product? Maybe not? (mul is easy, dot maybe not?)
134 return uint32((UIntType)Data.X * 1150168907 + (UIntType)Data.Y * 1235029793 + (UIntType)Data.Z * 1282581571 + (UIntType)Data.W * 1264559321);
135 }
136
138 };
139
141
143 {
144 static constexpr int32 CellBlockDimLog2 = 3; // (8x8x8)
146
147 // The FBlockLocAligned represents the block locations as 32-bit ints.
149 // The cell coordinate may be larger by the block dimension and still can fit into a signed 32-bit integer
151 };
152
154
158
162private:
163
164 bool IsSmallCullingVolume(const FCullingVolume& CullingVolume) const;
165
166 void FinalizeUpdateAndClear(FRDGBuilder& GraphBuilder, FSceneUniformBuffer& SceneUniformBuffer, bool bPublishStats);
167
171 bool BeginUpdate(FRDGBuilder& GraphBuilder, bool bAnySceneUpdatesExpected);
172
173 void ValidateAllInstanceAllocations();
174
175 void Empty();
176
180 struct FCellIndexCacheEntry
181 {
182 static constexpr uint32 SingleInstanceMask = 1u << 31;
183 static constexpr uint32 CellIndexMask = (1u << 31) - 1u;
184 static constexpr uint32 CellIndexMax = 1u << 31;
185
191
192 inline void Add(int32 CellIndex, int32 NumInstances)
193 {
194 check(uint32(CellIndex) < CellIndexMax);
195 check(!bSingleInstanceOnly || NumInstances == 1);
196
197 if (NumInstances > 1)
198 {
199 // Add RLE entry
200 Items.Add(CellIndex);
201 Items.Add(NumInstances);
202 }
203 else
204 {
205 // Mark as single-istance
206 Items.Add(uint32(CellIndex) | SingleInstanceMask);
207 }
208 }
209
213 inline void Set(int32 Index, int32 CellIndex)
214 {
215 check(bSingleInstanceOnly);
216 check(uint32(CellIndex) < CellIndexMax);
217
218 Items[Index] = uint32(CellIndex) | SingleInstanceMask;
219 }
220
221 FORCEINLINE void Reset()
222 {
223 Items.Reset();
224 }
225
226
230 FItem LoadAndStepItem(int32 &InOutItemIndex) const
231 {
232 FItem Result;
234 Result.CellIndex = int32(PackedCellIndex & FCellIndexCacheEntry::CellIndexMask);
235 Result.NumInstances = 1;
236 if ((PackedCellIndex & FCellIndexCacheEntry::SingleInstanceMask) == 0u)
237 {
238 Result.NumInstances = int32(Items[++InOutItemIndex]);
239 }
240 return Result;
241 }
242
243 bool bSingleInstanceOnly = false;
244 TArray<uint32> Items;
245 };
246
250 struct FPrimitiveState
251 {
252 static constexpr int32 PayloadBits = 28;
253 static constexpr uint32 InvalidPayload = (1u << PayloadBits) - 1u;
254 FPrimitiveState()
255 : InstanceDataOffset(-1)
256 , NumInstances(0)
257 , State(Unknown)
258 , bDynamic(false)
259 , Payload(InvalidPayload)
260 {
261 }
262
263 enum EState : uint32
264 {
265 Unknown,
266 SingleCell,
267 Precomputed,
268 UnCullable,
269 Dynamic,
270 Cached,
271 };
272
273 inline bool IsCachedState() const { return State == Cached || State == Dynamic; }
274
275 int32 InstanceDataOffset;
276 int32 NumInstances;
277 EState State : 3;
278 // The bDynamic flag is used to record whether a primitive has been seen to be updated. This can happen, for example for a stationary primitive, if this happens it is transitioned to Dynamic.
279 bool bDynamic : 1;
280 // For SingleCell primitives the payload represents the cell index directly, whereas for cached, it is the offset into the CellIndexCache
281 uint32 Payload :28;
282
283 const FString &ToString() const;
284
286 };
287
288 TArray<FPrimitiveState> PrimitiveStates;
290 int32 TotalCellIndexCacheItems = 0;
291
292 int32 NumDynamicInstances = 0;
293 int32 NumStaticInstances = 0;
294
295
298
299 bool bIsEnabled = false;
300 bool bForceFullExplictBoundsBuild = false;
301
302 FSpatialHash SpatialHash;
303
304 // Kept in the class for now, since we only want one active at a time.
305 TPimplPtr<FSceneCullingBuilder> ActiveUpdaterImplementation;
306
307 // A cell stores references to a list of chunks, that, in turn, reference units of 64 instances.
308 // This enables storing compressed chunks directly in the indirection, as well as simplifying allocation and movement of instance data lists.
309 TArray<uint32> PackedCellChunkData;
310 FSpanAllocator CellChunkIdAllocator;
311 TArray<uint32> PackedCellData;
312 TArray<uint32> FreeChunks;
313 TArray<FPackedCellHeader> CellHeaders;
314 TBitArray<> CellOccupancyMask;
315 TBitArray<> BlockLevelOccupancyMask;
316 // Bit marking each chunk ID as in use or not, complements the CellChunkIdAllocator.
317 TBitArray<> UsedChunkIdMask;
318
319 TArray<FCellBlockData> CellBlockData;
320 TArray<FPersistentPrimitiveIndex> UnCullablePrimitives;
321 int32 UncullableItemChunksOffset = INDEX_NONE;
322 int32 UncullableNumItemChunks = 0;
323 // Largest dimension length, in cells, at the finest level under which a footprint is considered "small" and should go down the direct footprint path
324 int32 SmallFootprintCellSideThreshold = 16;
325 bool bTestCellVsQueryBounds = true;
326 bool bUseAsyncUpdate = true;
327 bool bUseAsyncQuery = true;
328 bool bPackedCellDataLocked = false;
329
330 inline uint32 AllocateChunk();
331 inline void FreeChunk(uint32 ChunkId);
332 inline uint32* LockChunkCellData(uint32 ChunkId, int32 NumSlackChunksNeeded);
333 inline void UnLockChunkCellData(uint32 ChunkId);
334 inline int32 CellIndexToBlockId(int32 CellIndex);
335 inline FLocation64 GetCellLoc(int32 CellIndex);
336 inline bool IsUncullable(const FPrimitiveBounds& Bounds, FPrimitiveSceneInfo* PrimitiveSceneInfo);
337
338 // Persistent GPU-representation
341 TPersistentStructuredBuffer<uint32> InstanceIdsBuffer;
343 // explicit chunk bounds, packed and quantized
345 // parallel to the chunk bounds, stores ID of the cell they belong to.
346 TPersistentStructuredBuffer<uint32> ExplicitChunkCellIdsBuffer;
347 TRefCountPtr<FRDGPooledBuffer> UsedChunkIdMaskBuffer;
348
349 UE::Tasks::FTask PostUpdateTaskHandle;
350};
#define FORCEINLINE
Definition AndroidPlatform.h:140
#define check(expr)
Definition AssertionMacros.h:314
@ INDEX_NONE
Definition CoreMiscDefines.h:150
@ ForceInit
Definition CoreMiscDefines.h:155
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define X(Name, Desc)
Definition FormatStringSan.h:47
UE::Math::TIntVector3< int32 > FIntVector3
Definition MathFwd.h:92
UE::Math::TSphere< double > FSphere
Definition MathFwd.h:54
UE::Math::TVector< double > FVector3d
Definition MathFwd.h:60
#define MAX_int32
Definition NumericLimits.h:25
#define DECLARE_SCENE_EXTENSION_UPDATER(ClassName, SceneExtensionClassName)
Definition SceneExtensions.h:390
#define DECLARE_SCENE_EXTENSION(ModuleExport, ClassName)
Definition SceneExtensions.h:384
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition PrimitiveSceneInfo.h:266
Definition RenderGraphBuilder.h:49
Definition SceneCulling.cpp:810
Definition SceneCullingRenderer.h:33
Definition SceneCulling.h:52
virtual void PostSceneUpdate(FRDGBuilder &GraphBuilder, const FScenePostUpdateChangeSet &ChangeSet) override
Definition SceneCulling.cpp:2719
virtual void PreSceneUpdate(FRDGBuilder &GraphBuilder, const FScenePreUpdateChangeSet &ChangeSet, FSceneUniformBuffer &SceneUniforms) override
Definition SceneCulling.cpp:2682
~FUpdater()
Definition SceneCulling.cpp:2647
FUpdater(FSceneCulling &InSceneCulling)
Definition SceneCulling.h:56
Definition SceneCulling.h:40
static bool ShouldCreateExtension(FScene &Scene)
Definition SceneCulling.cpp:275
void PublishStats()
Definition SceneCulling.cpp:2594
virtual ISceneExtensionRenderer * CreateRenderer(FSceneRendererBase &InSceneRenderer, const FEngineShowFlags &EngineShowFlags)
Definition SceneCulling.cpp:2642
virtual ISceneExtensionUpdater * CreateUpdater()
Definition SceneCulling.cpp:2637
FSpatialHash::FFootprint32 FFootprint32
Definition SceneCulling.h:160
UE::Tasks::FTask GetUpdateTaskHandle() const
Definition SceneCulling.cpp:2836
FSpatialHash::FFootprint8 FFootprint8
Definition SceneCulling.h:159
void EndUpdate(FRDGBuilder &GraphBuilder, FSceneUniformBuffer &SceneUniformBuffer, bool bPublishStats)
Definition SceneCulling.cpp:2777
FSpatialHash::FFootprint64 FFootprint64
Definition SceneCulling.h:161
void TestSphere(const FSphere &Sphere, ResultConsumerType &ResultConsumer) const
Definition SceneCulling.inl:36
bool IsEnabled() const
Definition SceneCulling.h:90
Definition SceneCullingRenderer.h:80
Definition ScenePrimitiveUpdates.h:129
Definition ScenePrimitiveUpdates.h:116
Definition SceneRendering.h:2023
Definition SceneUniformBuffer.h:137
Definition ScenePrivate.h:2875
Definition SpanAllocator.h:15
Definition SceneExtensions.h:69
Definition SceneExtensions.h:45
Definition SceneExtensions.h:24
FScene & Scene
Definition SceneExtensions.h:40
Definition Array.h:670
RenderingSpatialHash::TLocation< int8 > FLocation8
Definition HierarchicalSpatialHashGrid.h:181
TFootprint< int8 > FFootprint8
Definition HierarchicalSpatialHashGrid.h:214
RenderingSpatialHash::TLocation< int32 > FLocation32
Definition HierarchicalSpatialHashGrid.h:180
RenderingSpatialHash::TLocation< int64 > FLocation64
Definition HierarchicalSpatialHashGrid.h:179
TFootprint< int64 > FFootprint64
Definition HierarchicalSpatialHashGrid.h:212
TFootprint< int32 > FFootprint32
Definition HierarchicalSpatialHashGrid.h:213
Definition RefCounting.h:454
Definition SharedPointer.h:692
Definition SparseArray.h:524
@ Dynamic
Definition SpatialAccelerationCollection.h:22
@ Unknown
Definition BehaviorTreeTypes.h:183
FString ToString(uint16 Value)
Definition PathFollowingComponent.cpp:82
double GetCellSize(int32 Level)
Definition RenderingSpatialHash.h:96
State
Definition PacketHandler.h:88
UE_STRING_CLASS Result(Forward< LhsType >(Lhs), RhsLen)
Definition String.cpp.inl:732
@ false
Definition radaudio_common.h:23
U16 Index
Definition radfft.cpp:71
Definition ConvexVolume.h:44
Definition SceneCulling.h:28
FVector3d WorldToVolumeTranslation
Definition SceneCulling.h:30
FSphere3d Sphere
Definition SceneCulling.h:33
FConvexVolume ConvexVolume
Definition SceneCulling.h:31
Definition ShowFlags.h:56
Definition ScenePrivate.h:2459
Definition SceneCulling.h:102
FORCEINLINE int32 GetLevel() const
Definition SceneCulling.h:119
FIntVector4 Data
Definition SceneCulling.h:137
FORCEINLINE void operator=(const FBlockLocAligned &BlockLocAligned)
Definition SceneCulling.h:115
FORCEINLINE bool operator==(const FBlockLocAligned &BlockLocAligned) const
Definition SceneCulling.h:110
FORCEINLINE FIntVector3 GetCoord() const
Definition SceneCulling.h:121
FORCEINLINE FBlockLocAligned(const RenderingSpatialHash::TLocation< int64 > &InLoc)
Definition SceneCulling.h:105
FORCEINLINE FBlockLocAligned()
Definition SceneCulling.h:103
FORCEINLINE FVector3d GetWorldPosition() const
Definition SceneCulling.h:123
FORCEINLINE uint32 GetHash() const
Definition SceneCulling.h:129
Definition SceneCulling.h:143
FBlockLoc FBlockLoc
Definition SceneCulling.h:145
static constexpr int64 MaxCellCoord
Definition SceneCulling.h:150
static constexpr int32 CellBlockDimLog2
Definition SceneCulling.h:144
static constexpr int64 MaxCellBlockCoord
Definition SceneCulling.h:148
Definition SceneCulling.h:187
int32 CellIndex
Definition SceneCulling.h:189
int32 NumInstances
Definition SceneCulling.h:188
Definition RenderingSpatialHash.h:17
Definition PimplPtr.h:50
IntType Z
Definition IntVector.h:1231
IntType W
Definition IntVector.h:1234
IntType X
Definition IntVector.h:1225
IntType Y
Definition IntVector.h:1228