UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
SceneCulling.inl
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "SceneCulling.h"
6
7
8template <typename ScalarType>
16
34
35template <typename ResultConsumerType>
37{
39
40 // TODO[Opt]: Maybe specialized bit set since we have a fixed size & alignment guaranteed (64-bit words all in use)
41 // TODO[Opt]: Add a per-view grid / cache that works like the VSM page table and allows skipping within the footprint?
42 for (TConstSetBitIterator<> BitIt(BlockLevelOccupancyMask); BitIt; ++BitIt)
43 {
44 int32 BlockLevel = BitIt.GetIndex();
46 // Note float size, this is intentional, the idea should be to never have cell sizes of unusual size
47 const float LevelCellSize = SpatialHash.GetCellSize(Level);
48
49 // TODO[Opt]: may be computed as a relative from the previous level, needs to be adjusted for skipping levels:
50 // Expand by 1 (half a cell on the next level) before dividing to maintain looseness
51 // LightFootprint.Min -= FInt64Vector3(1);
52 // LightFootprint.Max += FInt64Vector3(1);
53 // LightFootprint = ToLevelRelative(LightFootprint, 1);
54 FFootprint64 LightFootprint = SpatialHash.CalcFootprintSphere(Level, Sphere.Center, Sphere.W + (LevelCellSize * 0.5f));
55
58 const float BlockSize = SpatialHash.GetCellSize(BlockFootprint.Level);
59
60 // Loop over footprint
61 BlockFootprint.ForEach([&](const FLocation64& BlockLoc)
62 {
63 // TODO[Opt]: Add cache for block ID lookups? The hash lookup is somewhat costly and we hit it quite a bit due to the loose footprint.
64 // Could be a 3d grid/level (or not?) with modulo and use the BlockLoc as key. Getting very similar to just using a cheaper hash...
66 if (BlockId.IsValid())
67 {
68 const FSpatialHash::FCellBlock& Block = GlobalSpatialHash.GetByElementId(BlockId).Value;
69 FVector3d BlockWorldPos = FVector3d(BlockLoc.Coord) * double(BlockSize);
70
71 // relative query offset, float precision.
72 // This is probably not important on PC, but on GPU the block world pos can be precomputed on host and this gets us out of large precision work
73 // Expand by 1/2 cell size for loose
74 FSphere3f BlockLocalSphere(FVector3f(Sphere.Center - BlockWorldPos), float(Sphere.W) + (LevelCellSize * 0.5f));
75
76 FFootprint8 LightFootprintInBlock = ToBlockLocal(LightFootprint, BlockLoc);
77
78 // Calc block mask
79 // TODO[Opt]: We can make a table of this and potentially save a bit of work here
80 uint64 LightCellMask = FSpatialHash::FCellBlock::BuildFootPrintMask(LightFootprintInBlock);
81
82 if ((Block.CoarseCellMask & LightCellMask) != 0ULL)
83 {
84 LightFootprintInBlock.ForEach([&](const FLocation8& CellSubLoc)
85 {
86 if ((Block.CoarseCellMask & FSpatialHash::FCellBlock::CalcCellMask(CellSubLoc.Coord)) != 0ULL)
87 {
88 // optionally test the cell bounds against the query
89 // 1. Make local bounding box (we could do a global one but this is more GPU friendly)
90 // Note: not expanded because the query is:
91 FBox3f Box;
92 Box.Min = FVector3f(CellSubLoc.Coord) * LevelCellSize;
93 Box.Max = Box.Min + LevelCellSize;
94
95 bool bIntersects = true;
96
97 if (bTestCellVsQueryBounds)
98 {
99 if (!FMath::SphereAABBIntersection(BlockLocalSphere, Box))
100 {
101 bIntersects = false;
102 }
103 }
104 if (bIntersects)
105 {
106 uint32 CellId = Block.GetCellGridOffset(CellSubLoc.Coord);
107 ResultConsumer.OnCellOverlap(CellId);
108 }
109 }
110 });
111 }
112 }
113 });
114 }
115}
116
118{
119 return CellHeader.bIsValid;
120}
121
123{
124 // For a valid cell the value is always nonzero
125 return CellHeader.Packed0 != 0u;
126}
127
129{
130 const uint64& Bits = reinterpret_cast<const uint64&>(Packed);
134 CellHeader.NumDynamicChunks = uint32(Bits) & ((1u << INSTANCE_HIERARCHY_CELL_HEADER_COUNT_BITS) - 1u);
135 CellHeader.bIsValid = CellHeader.NumDynamicChunks != 0u;
136 if (CellHeader.bIsValid)
137 {
138 CellHeader.NumDynamicChunks -= 1u;
139 }
140 CellHeader.NumItemChunks = CellHeader.NumDynamicChunks + CellHeader.NumStaticChunks;
141 return CellHeader;
142}
#define check(expr)
Definition AssertionMacros.h:314
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
UE::Math::TIntVector3< int64 > FInt64Vector3
Definition MathFwd.h:99
UE::Math::TIntVector3< int8 > FInt8Vector3
Definition SceneCulling.cpp:282
FSceneCulling::FFootprint8 ToBlockLocal(const FSceneCulling::FFootprint64 &ObjFootprint, const FSceneCulling::FLocation64 &BlockLoc)
Definition SceneCulling.inl:17
FCellHeader UnpackCellHeader(const FPackedCellHeader &Packed)
Definition SceneCulling.inl:128
UE::Math::TIntVector3< ScalarType > ClampDim(const UE::Math::TIntVector3< ScalarType > &Vec, ScalarType MinValueInc, ScalarType MaxValueInc)
Definition SceneCulling.inl:9
bool IsValidCell(const FCellHeader &CellHeader)
Definition SceneCulling.inl:117
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition RobinHoodHashTable.h:72
bool IsValid() const
Definition RobinHoodHashTable.h:82
FSpatialHash::FFootprint8 FFootprint8
Definition SceneCulling.h:159
FSpatialHash::FFootprint64 FFootprint64
Definition SceneCulling.h:161
FBlockLocAligned FBlockLoc
Definition SceneCulling.h:140
void TestSphere(const FSphere &Sphere, ResultConsumerType &ResultConsumer) const
Definition SceneCulling.inl:36
Definition BitArray.h:1944
FFootprint64 CalcFootprintSphere(int32 Level, const FVector &Origin, double Radius) const
Definition HierarchicalSpatialHashGrid.h:321
static double GetCellSize(int32 Level)
Definition HierarchicalSpatialHashGrid.h:302
static constexpr int32 CellBlockDimLog2
Definition HierarchicalSpatialHashGrid.h:172
const FSpatialHashMap & GetHashMap() const
Definition HierarchicalSpatialHashGrid.h:468
static FFootprint64 CalcCellBlockFootprint(const FFootprint64 &Footprint)
Definition HierarchicalSpatialHashGrid.h:331
static constexpr int32 CellBlockDim
Definition HierarchicalSpatialHashGrid.h:175
static constexpr UE_FORCEINLINE_HINT T Clamp(const T X, const T MinValue, const T MaxValue)
Definition UnrealMathUtility.h:592
Definition RenderingSpatialHash.h:17
Definition IntVector.h:22