SleakEngine
0.1.0
C++23 multi-backend game engine
Toggle main menu visibility
Loading...
Searching...
No Matches
CullingSystem.hpp
Go to the documentation of this file.
1
#ifndef _CULLING_SYSTEM_HPP_
2
#define _CULLING_SYSTEM_HPP_
3
4
#include <
Camera/ViewFrustum.hpp
>
5
#include <
Core/OSDef.hpp
>
6
#include <
Math/AABB.hpp
>
7
#include <
Math/Matrix.hpp
>
8
#include <
Math/Vector.hpp
>
9
#include <cstdint>
10
11
namespace
Sleak
{
12
13
/// CPU visibility system: view-frustum culling plus software occlusion
14
/// culling against a low-resolution depth buffer rasterized from
15
/// game-submitted occluder volumes. Backend-agnostic (no GPU work).
16
///
17
/// Frame protocol:
18
/// 1. BeginFrame(...) once per frame after camera update
19
/// (the engine calls this automatically from the main camera)
20
/// 2. SubmitOccluderBox/Triangles any number of world-space occluders
21
/// 3. FinalizeOccluders() sort by distance, rasterize budget
22
/// 4. IsVisible(aabb) frustum + occlusion query
23
/// Steps 2-3 are optional; IsVisible degrades to frustum-only.
24
///
25
/// Everything here is static and lives for the process. The main camera
26
/// calls BeginFrame() for you during its update, so a game that only wants
27
/// frustum culling can call IsVisible() and stop reading here.
28
///
29
/// Occlusion culling is the part you opt into. Submit occluder volumes
30
/// every frame, call FinalizeOccluders() once, then test your objects.
31
/// Occluders must be fully solid volumes: a box submitted over a cave or
32
/// an open doorway will hide geometry that should be visible. The bounds
33
/// you test with should be tight around the real vertex extent, since
34
/// bounds that overshoot into empty space pass the depth test and cull
35
/// nothing while still costing you the test.
36
///
37
/// The occlusion pass adapts. When a rasterized frame culls nothing, it
38
/// stops rasterizing and probes again every `probeInterval` frames, with
39
/// queries falling back to frustum-only in between. GetStats() reports
40
/// what the last pass actually did.
41
///
42
/// @code{.cpp}
43
/// // Optional tuning, once at startup
44
/// Sleak::CullingSystem::SetOcclusionCullingEnabled(true);
45
/// Sleak::CullingSystem::SetOcclusionBufferSize(256, 144);
46
/// Sleak::CullingSystem::SetMaxOccluders(192);
47
/// Sleak::CullingSystem::SetAdaptiveOcclusion(true, 20);
48
///
49
/// // Every frame, after the camera has updated
50
/// for (const auto& chunk : loadedChunks) {
51
/// for (const auto& solid : chunk.solidVolumes) {
52
/// Sleak::CullingSystem::SubmitOccluderBox(solid);
53
/// }
54
/// }
55
/// Sleak::CullingSystem::FinalizeOccluders();
56
///
57
/// for (auto& chunk : loadedChunks) {
58
/// chunk.visible = Sleak::CullingSystem::IsVisible(chunk.bounds);
59
/// }
60
///
61
/// const auto& stats = Sleak::CullingSystem::GetStats();
62
/// SLEAK_LOG("culled {} by frustum, {} by occlusion",
63
/// stats.frustumCulled, stats.occlusionCulled);
64
/// @endcode
65
///
66
/// @see ViewFrustum, Camera, Math::AABB
67
/// @ingroup culling
68
class
ENGINE_API
CullingSystem
{
69
public
:
70
/// Per-frame counters for the last completed culling pass.
71
struct
Stats
{
72
uint32_t
occludersSubmitted
= 0;
73
uint32_t
occludersRasterized
= 0;
74
uint32_t
tested
= 0;
75
uint32_t
frustumCulled
= 0;
76
uint32_t
occlusionCulled
= 0;
77
bool
occlusionSkipped
=
false
;
// adaptive pass idle this frame
78
float
rasterizeMs
= 0.0f;
79
};
80
81
static
void
SetFrustumCullingEnabled
(
bool
enabled);
82
static
void
SetOcclusionCullingEnabled
(
bool
enabled);
83
static
bool
IsFrustumCullingEnabled
();
84
static
bool
IsOcclusionCullingEnabled
();
85
86
/// Occlusion depth buffer resolution (default 256x144).
87
static
void
SetOcclusionBufferSize
(uint32_t
width
, uint32_t
height
);
88
/// Max occluders rasterized per frame after the distance sort
89
/// (default 192).
90
static
void
SetMaxOccluders
(uint32_t count);
91
92
/// Adaptive occlusion (default on, interval 20): when a rasterized
93
/// frame culls nothing, skip rasterization for `probeInterval` frames
94
/// and probe again. Queries degrade to frustum-only while skipping.
95
static
void
SetAdaptiveOcclusion
(
bool
enabled, uint32_t probeInterval);
96
97
/// viewProj uses the engine row-vector convention: clip = point * VP,
98
/// depth range [0, w]. cameraPos is world-space.
99
static
void
BeginFrame
(
const
ViewFrustum
& frustum,
100
const
Math::Matrix4
& viewProj,
101
const
Math::Vector3D
& cameraPos);
102
103
/// World-space occluders. Boxes must be fully solid volumes.
104
static
void
SubmitOccluderBox
(
const
Math::AABB
& box);
105
/// World-space triangle occluder; same fully-solid-volume requirement as SubmitOccluderBox.
106
static
void
SubmitOccluderTriangles
(
const
Math::Vector3D
* vertices,
107
uint32_t vertexCount,
108
const
uint32_t* indices,
109
uint32_t indexCount);
110
/// Sorts submitted occluders by distance and rasterizes them into the depth buffer up to the max-occluder budget.
111
static
void
FinalizeOccluders
();
112
113
/// Frustum test, then conservative depth test against the occlusion
114
/// buffer. Never falsely culls a visible box (given valid occluders).
115
static
bool
IsVisible
(
const
Math::AABB
& box);
116
/// Frustum-only visibility test, skipping the occlusion buffer entirely.
117
static
bool
IsVisibleFrustumOnly
(
const
Math::AABB
& box);
118
119
static
const
Stats
&
GetStats
();
120
121
/// Debug: row-major width*height floats, NDC depth (0 near, 1 far).
122
/// Returns nullptr if occlusion has never rasterized.
123
static
const
float
*
GetDepthBuffer
(uint32_t&
width
, uint32_t&
height
);
124
125
static
void
Shutdown
();
126
};
127
128
}
// namespace Sleak
129
130
#endif
// _CULLING_SYSTEM_HPP_
AABB.hpp
width
int width
Definition
Application.cpp:40
height
int height
Definition
Application.cpp:41
Matrix.hpp
OSDef.hpp
Vector.hpp
ViewFrustum.hpp
Sleak::CullingSystem
Definition
CullingSystem.hpp:68
Sleak::CullingSystem::Shutdown
static void Shutdown()
Definition
CullingSystem.cpp:484
Sleak::CullingSystem::IsVisibleFrustumOnly
static bool IsVisibleFrustumOnly(const Math::AABB &box)
Frustum-only visibility test, skipping the occlusion buffer entirely.
Definition
CullingSystem.cpp:455
Sleak::CullingSystem::GetStats
static const Stats & GetStats()
Definition
CullingSystem.cpp:468
Sleak::CullingSystem::SetAdaptiveOcclusion
static void SetAdaptiveOcclusion(bool enabled, uint32_t probeInterval)
Definition
CullingSystem.cpp:304
Sleak::CullingSystem::SetOcclusionBufferSize
static void SetOcclusionBufferSize(uint32_t width, uint32_t height)
Occlusion depth buffer resolution (default 256x144).
Definition
CullingSystem.cpp:294
Sleak::CullingSystem::SetOcclusionCullingEnabled
static void SetOcclusionCullingEnabled(bool enabled)
Definition
CullingSystem.cpp:282
Sleak::CullingSystem::GetDepthBuffer
static const float * GetDepthBuffer(uint32_t &width, uint32_t &height)
Definition
CullingSystem.cpp:472
Sleak::CullingSystem::SubmitOccluderTriangles
static void SubmitOccluderTriangles(const Math::Vector3D *vertices, uint32_t vertexCount, const uint32_t *indices, uint32_t indexCount)
World-space triangle occluder; same fully-solid-volume requirement as SubmitOccluderBox.
Definition
CullingSystem.cpp:351
Sleak::CullingSystem::SubmitOccluderBox
static void SubmitOccluderBox(const Math::AABB &box)
World-space occluders. Boxes must be fully solid volumes.
Definition
CullingSystem.cpp:337
Sleak::CullingSystem::BeginFrame
static void BeginFrame(const ViewFrustum &frustum, const Math::Matrix4 &viewProj, const Math::Vector3D &cameraPos)
Definition
CullingSystem.cpp:312
Sleak::CullingSystem::IsVisible
static bool IsVisible(const Math::AABB &box)
Definition
CullingSystem.cpp:435
Sleak::CullingSystem::FinalizeOccluders
static void FinalizeOccluders()
Sorts submitted occluders by distance and rasterizes them into the depth buffer up to the max-occlude...
Definition
CullingSystem.cpp:386
Sleak::CullingSystem::IsFrustumCullingEnabled
static bool IsFrustumCullingEnabled()
Definition
CullingSystem.cpp:286
Sleak::CullingSystem::IsOcclusionCullingEnabled
static bool IsOcclusionCullingEnabled()
Definition
CullingSystem.cpp:290
Sleak::CullingSystem::SetMaxOccluders
static void SetMaxOccluders(uint32_t count)
Definition
CullingSystem.cpp:300
Sleak::CullingSystem::SetFrustumCullingEnabled
static void SetFrustumCullingEnabled(bool enabled)
Definition
CullingSystem.cpp:278
Sleak::Math::Vector3D
Definition
Vector.hpp:354
Sleak::ViewFrustum
Definition
ViewFrustum.hpp:35
Sleak::Math::Matrix4
Matrix< float, 4, 4 > Matrix4
Definition
Matrix.hpp:413
Sleak
Root namespace for everything the engine exposes.
Definition
Camera.hpp:10
Sleak::CullingSystem::Stats
Per-frame counters for the last completed culling pass.
Definition
CullingSystem.hpp:71
Sleak::CullingSystem::Stats::rasterizeMs
float rasterizeMs
Definition
CullingSystem.hpp:78
Sleak::CullingSystem::Stats::occlusionCulled
uint32_t occlusionCulled
Definition
CullingSystem.hpp:76
Sleak::CullingSystem::Stats::tested
uint32_t tested
Definition
CullingSystem.hpp:74
Sleak::CullingSystem::Stats::occludersRasterized
uint32_t occludersRasterized
Definition
CullingSystem.hpp:73
Sleak::CullingSystem::Stats::frustumCulled
uint32_t frustumCulled
Definition
CullingSystem.hpp:75
Sleak::CullingSystem::Stats::occlusionSkipped
bool occlusionSkipped
Definition
CullingSystem.hpp:77
Sleak::CullingSystem::Stats::occludersSubmitted
uint32_t occludersSubmitted
Definition
CullingSystem.hpp:72
Sleak::Math::AABB
Definition
AABB.hpp:11
include
public
Culling
CullingSystem.hpp
Generated on
for SleakEngine by
1.18.0