SleakEngine 1.0.0
C++23 multi-backend game engine
Loading...
Searching...
No Matches
LightManager.hpp
Go to the documentation of this file.
1#ifndef _LIGHT_MANAGER_HPP_
2#define _LIGHT_MANAGER_HPP_
3
4#include <Core/OSDef.hpp>
6#include <Math/Vector.hpp>
7#include <Memory/RefPtr.hpp>
8
9namespace Sleak {
10
11 class Light;
12
13 namespace RenderEngine {
14 class BufferBase;
15 struct LightCBData;
16 }
17
18 /// Owns the registered light list and the GPU-side light/fog constant buffers; one instance per scene.
19 ///
20 /// Each Scene owns one, reachable through
21 /// SceneBase::GetLightManager(). Lights register themselves when their
22 /// GameObject is added to the scene, so you almost never call
23 /// RegisterLight() directly. What you do use it for is the scene-wide
24 /// atmosphere that is not attached to any single light: ambient color
25 /// and intensity, distance fog, and height fog.
26 ///
27 /// Ambient light is the floor value that keeps shadow-side surfaces
28 /// from going flat black. Tinting it toward the sky color, then keeping
29 /// the intensity low, reads as sky bounce without washing out the
30 /// directional lights doing the real work.
31 ///
32 /// Fog has two layers that stack. Distance fog blends between a horizon
33 /// color and a zenith color as the view tilts upward, fading in between
34 /// the start and end distances. Height fog adds exponential density
35 /// below a world height, which is what grounds figures on a floor plane
36 /// and pools haze in valleys.
37 ///
38 /// @code{.cpp}
39 /// if (auto* lm = GetLightManager()) {
40 /// lm->SetAmbientColor(0.30f, 0.34f, 0.40f);
41 /// lm->SetAmbientIntensity(0.75f);
42 ///
43 /// lm->SetFogColor(0.62f, 0.70f, 0.82f); // horizon
44 /// lm->SetFogZenithColor(0.42f, 0.55f, 0.80f); // straight up
45 /// lm->SetFogDistances(60.0f, 220.0f);
46 /// lm->SetFogEnabled(true);
47 ///
48 /// lm->SetHeightFogEnabled(true);
49 /// lm->SetHeightFogTop(4.0f);
50 /// lm->SetHeightFogDensity(0.15f);
51 /// lm->SetHeightFogFalloff(0.25f);
52 /// }
53 /// @endcode
54 ///
55 /// @see Light, DirectionalLight, PointLight, SpotLight, SceneBase
56 /// @ingroup lighting
57 class ENGINE_API LightManager {
58 public:
61
62 /// Allocates the GPU light buffer; call once before the first UpdateAndBind.
63 void Initialize();
64
65 void RegisterLight(Light* light);
66 void UnregisterLight(Light* light);
67
68 /// Packs every registered light and the fog/ambient parameters into the light buffer and binds it.
69 void UpdateAndBind();
70 /// Picks the active shadow-casting light and refreshes its shadow-space matrices.
71 void UpdateShadowData();
72 /// Refreshes the deferred-pass constant buffer (fog, ambient) independent of the per-light data.
73 void UpdateDeferredCB();
74
75 void SetAmbientColor(float r, float g, float b);
76 void SetAmbientIntensity(float intensity) {
77 m_ambientIntensity = intensity;
78 }
79
80 float GetAmbientIntensity() const {
81 return m_ambientIntensity;
82 }
83
84 size_t GetLightCount() const {
85 return m_lights.GetSize();
86 }
87
88 void SetFogColor(float r, float g, float b) {
89 m_fogR = r; m_fogG = g; m_fogB = b;
90 }
91 void SetFogDistances(float start, float end) {
92 m_fogStart = start; m_fogEnd = end;
93 }
94 void SetFogEnabled(bool enabled) { m_fogEnabled = enabled; }
95 bool IsFogEnabled() const { return m_fogEnabled; }
96 float GetFogStart() const { return m_fogStart; }
97 float GetFogEnd() const { return m_fogEnd; }
98
99 /// Two-color sky-matched fog gradient. SetFogColor(r,g,b) above sets
100 /// the horizon color; the zenith color blends in as the view direction
101 /// tilts upward.
102 void SetFogZenithColor(float r, float g, float b) {
103 m_fogZenithR = r; m_fogZenithG = g; m_fogZenithB = b;
104 }
105
106 /// Height fog: exponential density that thickens below HeightFogTop.
107 /// density(y) = HeightFogDensity * exp(-max(0, y - HeightFogTop) * HeightFogFalloff)
108 void SetHeightFogEnabled(bool enabled) { m_heightFogEnabled = enabled; }
109 void SetHeightFogTop(float worldY) { m_heightFogTop = worldY; }
110 void SetHeightFogDensity(float d) { m_heightFogDensity = d; }
111 void SetHeightFogFalloff(float f) { m_heightFogFalloff = f; }
112 bool IsHeightFogEnabled() const { return m_heightFogEnabled; }
113 float GetHeightFogTop() const { return m_heightFogTop; }
114 float GetHeightFogDensity() const { return m_heightFogDensity; }
115 float GetHeightFogFalloff() const { return m_heightFogFalloff; }
116
117 private:
118 List<Light*> m_lights;
119
121
122 float m_ambientR = 0.1f;
123 float m_ambientG = 0.1f;
124 float m_ambientB = 0.1f;
125 float m_ambientIntensity = 1.0f;
126
127 // Fog
128 bool m_fogEnabled = true;
129 float m_fogR = 0.62f, m_fogG = 0.74f, m_fogB = 0.88f; // horizon (warm-cool sky tint)
130 float m_fogZenithR = 0.42f, m_fogZenithG = 0.58f, m_fogZenithB = 0.86f; // zenith
131 float m_fogStart = 80.0f;
132 float m_fogEnd = 256.0f;
133
134 // Height fog (denser in valleys / over water)
135 bool m_heightFogEnabled = true;
136 float m_heightFogTop = 80.0f;
137 float m_heightFogDensity = 0.55f;
138 float m_heightFogFalloff = 0.04f;
139
140 // Previous frame's lightVP — sent to lighting UBO so it matches what
141 // is actually in the shadow map (which was rendered this frame using
142 // the renderer's m_lightVP, set at the END of the previous frame).
143 // Without this lag, the lighting pass samples shadow texels using a
144 // different transform than what produced them → static-geometry shake
145 // when the camera moves.
146 float m_prevLightVP[16] = {
147 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1
148 };
149 bool m_hasPrevLightVP = false;
150 };
151
152} // namespace Sleak
153
154#endif // _LIGHT_MANAGER_HPP_
float GetFogStart() const
void SetFogColor(float r, float g, float b)
size_t GetLightCount() const
float GetFogEnd() const
void SetFogZenithColor(float r, float g, float b)
void SetAmbientIntensity(float intensity)
void SetAmbientColor(float r, float g, float b)
void SetHeightFogEnabled(bool enabled)
void SetHeightFogDensity(float d)
void SetHeightFogTop(float worldY)
float GetHeightFogTop() const
float GetHeightFogDensity() const
bool IsFogEnabled() const
void RegisterLight(Light *light)
void UpdateDeferredCB()
Refreshes the deferred-pass constant buffer (fog, ambient) independent of the per-light data.
void SetFogEnabled(bool enabled)
void SetFogDistances(float start, float end)
float GetHeightFogFalloff() const
void Initialize()
Allocates the GPU light buffer; call once before the first UpdateAndBind.
void UpdateShadowData()
Picks the active shadow-casting light and refreshes its shadow-space matrices.
float GetAmbientIntensity() const
void SetHeightFogFalloff(float f)
void UpdateAndBind()
Packs every registered light and the fog/ambient parameters into the light buffer and binds it.
void UnregisterLight(Light *light)
bool IsHeightFogEnabled() const
Implements a dynamic array-like list for storing and managing a collection of elements.
Definition List.hpp:20
Backend-agnostic GPU buffer: vertex, index, constant, or resource view target.
Backend-facing rendering layer shared by the four graphics backends.
Root namespace for everything the engine exposes.
Definition Camera.hpp:10
Full per-frame lighting UBO: camera, ambient, fog, and the packed light array.