Unravel Engine C++ Reference
Loading...
Searching...
No Matches
shadow.h
Go to the documentation of this file.
1#pragma once
2#include <engine/engine_export.h>
3
4#include <engine/ecs/ecs.h>
7
8#include <base/basetypes.hpp>
9#include <context/context.hpp>
10
11#include <engine/ecs/ecs.h>
13#include <graphics/graphics.h>
14#include <hpp/small_vector.hpp>
15
16namespace unravel
17{
18namespace shadow
19{
31
33{
34 enum Enum
35 {
38
39 Count
40 };
41};
42
44{
45 enum Enum
46 {
49
50 Count
51 };
52};
53
54struct SmImpl
55{
56 enum Enum
57 {
63
64 Count
65 };
66};
67
68struct SmType
69{
70 enum Enum
71 {
75
76 Count
77 };
78};
79
81{
82 enum Enum
83 {
88
89 Count
90 };
91};
92
94{
95 enum Enum
96 {
99
100 Count
101 };
102};
103
116
118{
119 float m_x;
120 float m_y;
121 float m_z;
122 uint32_t m_normal;
123 float m_u;
124 float m_v;
125};
126
127struct Light
128{
130 {
131 struct
132 {
133 float m_x;
134 float m_y;
135 float m_z;
136 float m_w;
137 };
138
139 float m_v[4];
140 };
141
143 {
144 struct
145 {
146 float m_x;
147 float m_y;
148 float m_z;
149 float m_inner;
150 };
151
152 float m_v[4];
153 };
154
157};
158
160{
161 void init()
162 {
163 m_ambientPass = 1.0f;
164 m_lightingPass = 1.0f;
165
166 m_shadowMapBias = 0.003f;
167 m_shadowMapOffset = 0.0f;
168 m_shadowMapParam0 = 0.5;
169 m_shadowMapParam1 = 1.0;
170 m_depthValuePow = 1.0f;
171 m_showSmCoverage = 1.0f;
172 m_shadowMapTexelSize = 1.0f / 512.0f;
173
174 m_csmFarDistances[0] = 30.0f;
175 m_csmFarDistances[1] = 90.0f;
176 m_csmFarDistances[2] = 180.0f;
177 m_csmFarDistances[3] = 1000.0f;
178
179 m_tetraNormalGreen[0] = 0.0f;
180 m_tetraNormalGreen[1] = -0.57735026f;
181 m_tetraNormalGreen[2] = 0.81649661f;
182
183 m_tetraNormalYellow[0] = 0.0f;
184 m_tetraNormalYellow[1] = -0.57735026f;
185 m_tetraNormalYellow[2] = -0.81649661f;
186
187 m_tetraNormalBlue[0] = -0.81649661f;
188 m_tetraNormalBlue[1] = 0.57735026f;
189 m_tetraNormalBlue[2] = 0.0f;
190
191 m_tetraNormalRed[0] = 0.81649661f;
192 m_tetraNormalRed[1] = 0.57735026f;
193 m_tetraNormalRed[2] = 0.0f;
194
195 m_XNum = 2.0f;
196 m_YNum = 2.0f;
197 m_XOffset = 10.0f / 512.0f;
198 m_YOffset = 10.0f / 512.0f;
199
200 u_params0 = bgfx::createUniform("u_params0", bgfx::UniformType::Vec4);
201 u_params1 = bgfx::createUniform("u_params1", bgfx::UniformType::Vec4);
202 u_params2 = bgfx::createUniform("u_params2", bgfx::UniformType::Vec4);
203 u_color = bgfx::createUniform("u_color", bgfx::UniformType::Vec4);
204 u_smSamplingParams = bgfx::createUniform("u_smSamplingParams", bgfx::UniformType::Vec4);
205 u_csmFarDistances = bgfx::createUniform("u_csmFarDistances", bgfx::UniformType::Vec4);
206 u_lightMtx = bgfx::createUniform("u_lightMtx", bgfx::UniformType::Mat4);
207
208 u_tetraNormalGreen = bgfx::createUniform("u_tetraNormalGreen", bgfx::UniformType::Vec4);
209 u_tetraNormalYellow = bgfx::createUniform("u_tetraNormalYellow", bgfx::UniformType::Vec4);
210 u_tetraNormalBlue = bgfx::createUniform("u_tetraNormalBlue", bgfx::UniformType::Vec4);
211 u_tetraNormalRed = bgfx::createUniform("u_tetraNormalRed", bgfx::UniformType::Vec4);
212
213 u_shadowMapMtx0 = bgfx::createUniform("u_shadowMapMtx0", bgfx::UniformType::Mat4);
214 u_shadowMapMtx1 = bgfx::createUniform("u_shadowMapMtx1", bgfx::UniformType::Mat4);
215 u_shadowMapMtx2 = bgfx::createUniform("u_shadowMapMtx2", bgfx::UniformType::Mat4);
216 u_shadowMapMtx3 = bgfx::createUniform("u_shadowMapMtx3", bgfx::UniformType::Mat4);
217 }
218
219 void setPtrs(Light* _lightPtr,
220 float* _colorPtr,
221 float* _lightMtxPtr,
222 float* _shadowMapMtx0,
223 float* _shadowMapMtx1,
224 float* _shadowMapMtx2,
225 float* _shadowMapMtx3)
226 {
227 m_lightMtxPtr = _lightMtxPtr;
228 m_colorPtr = _colorPtr;
229 m_lightPtr = _lightPtr;
230
231 m_shadowMapMtx0 = _shadowMapMtx0;
232 m_shadowMapMtx1 = _shadowMapMtx1;
233 m_shadowMapMtx2 = _shadowMapMtx2;
234 m_shadowMapMtx3 = _shadowMapMtx3;
235 }
236
237 // Call this once at initialization.
239 {
240 bgfx::setUniform(u_tetraNormalGreen, m_tetraNormalGreen);
241 bgfx::setUniform(u_tetraNormalYellow, m_tetraNormalYellow);
242 bgfx::setUniform(u_tetraNormalBlue, m_tetraNormalBlue);
243 bgfx::setUniform(u_tetraNormalRed, m_tetraNormalRed);
244 }
245
246 // Call this once per frame.
248 {
249 bgfx::setUniform(u_params1, m_params1);
250 bgfx::setUniform(u_params2, m_params2);
251 bgfx::setUniform(u_smSamplingParams, m_paramsBlur);
252 bgfx::setUniform(u_csmFarDistances, m_csmFarDistances);
253 }
254
255 // Call this before each draw call.
257 {
258 bgfx::setUniform(u_shadowMapMtx0, m_shadowMapMtx0);
259 bgfx::setUniform(u_shadowMapMtx1, m_shadowMapMtx1);
260 bgfx::setUniform(u_shadowMapMtx2, m_shadowMapMtx2);
261 bgfx::setUniform(u_shadowMapMtx3, m_shadowMapMtx3);
262
263 bgfx::setUniform(u_params0, m_params0);
264 bgfx::setUniform(u_lightMtx, m_lightMtxPtr);
265 bgfx::setUniform(u_color, m_colorPtr);
266 }
267
268 void destroy()
269 {
270 bgfx::destroy(u_params0);
271 bgfx::destroy(u_params1);
272 bgfx::destroy(u_params2);
273 bgfx::destroy(u_color);
274 bgfx::destroy(u_smSamplingParams);
275 bgfx::destroy(u_csmFarDistances);
276
277 bgfx::destroy(u_tetraNormalGreen);
278 bgfx::destroy(u_tetraNormalYellow);
279 bgfx::destroy(u_tetraNormalBlue);
280 bgfx::destroy(u_tetraNormalRed);
281
282 bgfx::destroy(u_shadowMapMtx0);
283 bgfx::destroy(u_shadowMapMtx1);
284 bgfx::destroy(u_shadowMapMtx2);
285 bgfx::destroy(u_shadowMapMtx3);
286
287 bgfx::destroy(u_lightMtx);
288 }
289
290 union
291 {
292 struct
293 {
298 };
299
300 float m_params0[4];
301 };
302
303 union
304 {
305 struct
306 {
311 };
312
313 float m_params1[4];
314 };
315
316 union
317 {
318 struct
319 {
324 };
325
326 float m_params2[4];
327 };
328
329 union
330 {
331 struct
332 {
333 float m_XNum;
334 float m_YNum;
337 };
338
339 float m_paramsBlur[4];
340 };
341
347
355
356private:
357 bgfx::UniformHandle u_params0;
358 bgfx::UniformHandle u_params1;
359 bgfx::UniformHandle u_params2;
360 bgfx::UniformHandle u_color;
361 bgfx::UniformHandle u_smSamplingParams;
362 bgfx::UniformHandle u_csmFarDistances;
363
364 bgfx::UniformHandle u_tetraNormalGreen;
365 bgfx::UniformHandle u_tetraNormalYellow;
366 bgfx::UniformHandle u_tetraNormalBlue;
367 bgfx::UniformHandle u_tetraNormalRed;
368
369 bgfx::UniformHandle u_shadowMapMtx0;
370 bgfx::UniformHandle u_shadowMapMtx1;
371 bgfx::UniformHandle u_shadowMapMtx2;
372 bgfx::UniformHandle u_shadowMapMtx3;
373
374 bgfx::UniformHandle u_lightMtx;
375};
376
398
399struct PosColorTexCoord0Vertex : gfx::vertex<PosColorTexCoord0Vertex>
400{
401 float m_x;
402 float m_y;
403 float m_z;
404 uint32_t m_rgba;
405 float m_u;
406 float m_v;
407
408 static void init(gfx::vertex_layout& decl)
409 {
410 decl.begin()
411 .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
412 .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
413 .add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
414 .end();
415 }
416};
417
418struct PosVertex : gfx::vertex<PosVertex>
419{
420 float m_x;
421 float m_y;
422 float m_z;
423 static void init(gfx::vertex_layout& decl)
424 {
425 decl.begin().add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float).end();
426 }
427};
428
430{
431 void init(rtti::context& ctx);
432
433 void destroy()
434 {
435 // Pack depth.
436 for(uint8_t ii = 0; ii < DepthImpl::Count; ++ii)
437 {
438 for(uint8_t jj = 0; jj < PackDepth::Count; ++jj)
439 {
440 m_packDepth[ii][jj].reset();
441 }
442 }
443
444 // Draw depth.
445 for(uint8_t ii = 0; ii < PackDepth::Count; ++ii)
446 {
447 m_drawDepth[ii].reset();
448 }
449
450 // Hblur.
451 for(uint8_t ii = 0; ii < PackDepth::Count; ++ii)
452 {
453 m_hBlur[ii].reset();
454 }
455
456 // Vblur.
457 for(uint8_t ii = 0; ii < PackDepth::Count; ++ii)
458 {
459 m_vBlur[ii].reset();
460 }
461
462 // Misc.
463 m_black.reset();
464 }
465
472};
473
475{
476#define SHADOW_FLOAT_PARAM(_name) \
477 float _name{}, _name##Min{}, _name##Max{}, _name##Step \
478 { \
479 }
480 SHADOW_FLOAT_PARAM(m_sizePwrTwo);
481 SHADOW_FLOAT_PARAM(m_depthValuePow);
485 SHADOW_FLOAT_PARAM(m_normalOffset);
486 SHADOW_FLOAT_PARAM(m_customParam0);
487 SHADOW_FLOAT_PARAM(m_customParam1);
492 bool m_doBlur{};
495#undef SHADOW_FLOAT_PARAM
496};
497
517
519{
520 ClearValues(uint32_t _clearRgba = 0x30303000, float _clearDepth = 1.0f, uint8_t _clearStencil = 0)
521 : clear_rgba(_clearRgba)
522 , clear_depth(_clearDepth)
523 , clear_stencil(_clearStencil)
524 {
525 }
526
527 uint32_t clear_rgba;
530};
531
533{
534 enum Enum
535 {
536 legacy, // Original fixed frustum calculation
537 adaptive, // Altitude-aware adaptive frustum
538 hybrid, // Combination of both approaches
539
540 count
541 };
542};
543
545{
546 enum Enum
547 {
548 none = 0,
549 altitude_compensation = 1 << 0, // Adjust frustum based on camera altitude
550 scene_bounds_fitting = 1 << 1, // Fit to actual scene bounds
551 dynamic_split_weights = 1 << 2, // Adjust split distribution dynamically
552 stabilized_light_matrix = 1 << 3, // Improve light matrix positioning
553
555 };
556};
557
559{
560 float altitude_scale_factor = 0.5f; // How much altitude affects frustum extension
561 float min_altitude_boost = 0.05f; // Minimum altitude compensation
562 float max_altitude_boost = 100.0f; // Maximum altitude compensation
563 float scene_bounds_margin = 1.2f; // Margin factor for scene bounds fitting
564 float split_weight_bias = 0.1f; // Bias for dynamic split weight adjustment
565};
566
567using shadow_map_models_t = hpp::small_vector<entt::handle>;
568
597{
598public:
601
602 void init(rtti::context& ctx);
603 void deinit();
604 void deinit_textures();
605 void deinit_uniforms();
606
607 void update(const camera& cam, const light& l, const math::transform& ltrans, bool is_active);
608 auto already_updated() const -> bool;
609
611
612 auto get_depth_type() const -> PackDepth::Enum;
613 auto get_rt_texture(uint8_t split) const -> bgfx::TextureHandle;
615 void submit_uniforms(uint8_t stage) const;
616
617 // Configuration methods for improved shadow mapping
618 void set_frustum_calculation_method(frustum_calculation_method::Enum method) { frustum_method_ = method; }
619 auto get_frustum_calculation_method() const -> frustum_calculation_method::Enum { return frustum_method_; }
620
621 void set_csm_optimization_flags(uint32_t flags) { csm_optimization_flags_ = flags; }
622 auto get_csm_optimization_flags() const -> uint32_t { return csm_optimization_flags_; }
623
624 void enable_adaptive_shadows(bool enable) {
625 if(enable) {
626 frustum_method_ = frustum_calculation_method::adaptive;
627 csm_optimization_flags_ = csm_optimization_flags::all;
628 } else {
629 frustum_method_ = frustum_calculation_method::legacy;
630 csm_optimization_flags_ = csm_optimization_flags::none;
631 }
632 }
633
634 // Adaptive parameter configuration methods
635 void set_adaptive_params(const adaptive_shadow_params& params) { adaptive_params_ = params; }
636 auto get_adaptive_params() const -> const adaptive_shadow_params& { return adaptive_params_; }
637
638 void set_altitude_scale_factor(float factor) { adaptive_params_.altitude_scale_factor = factor; }
639 auto get_altitude_scale_factor() const -> float { return adaptive_params_.altitude_scale_factor; }
640
641 void set_altitude_boost_range(float min_boost, float max_boost) {
642 adaptive_params_.min_altitude_boost = min_boost;
643 adaptive_params_.max_altitude_boost = max_boost;
644 }
645
646 auto get_min_altitude_boost() const -> float { return adaptive_params_.min_altitude_boost; }
647 auto get_max_altitude_boost() const -> float { return adaptive_params_.max_altitude_boost; }
648
649private:
650 auto render_scene_into_shadowmap(uint8_t shadowmap_1_id,
651 const shadow_map_models_t& models,
653 ShadowMapSettings* currentSmSettings) -> bool;
654
655 ClearValues clear_values_;
656
657 float color_[4];
658 Light point_light_;
659 Light directional_light_;
660
661 float light_mtx_[16];
662 float shadow_map_mtx_[ShadowMapRenderTargets::Count][16];
663
665 SceneSettings settings_;
666
667 uint16_t current_shadow_map_size_{};
668 uint8_t current_num_splits_{};
669
670 Uniforms uniforms_;
671 Programs programs_;
672
673 float light_view_[ShadowMapRenderTargets::Count][16];
674 float light_proj_[ShadowMapRenderTargets::Count][16];
675
677
678 bgfx::UniformHandle tex_color_{bgfx::kInvalidHandle};
679 bgfx::UniformHandle shadow_map_[ShadowMapRenderTargets::Count];
680 bgfx::FrameBufferHandle rt_shadow_map_[ShadowMapRenderTargets::Count];
681 bgfx::FrameBufferHandle rt_blur_{bgfx::kInvalidHandle};
682
683 bool valid_{};
684
685 uint64_t last_update_ = -1;
686 std::shared_ptr<int> sentinel_ = std::make_shared<int>(0);
687
688 // New configuration members
690 uint32_t csm_optimization_flags_ = csm_optimization_flags::none;
691
692 // Additional parameters for adaptive calculations
693 adaptive_shadow_params adaptive_params_;
694};
695
696} // namespace shadow
697} // namespace unravel
Storage for frustum planes / values and wraps up common functionality.
Definition frustum.h:18
General purpose transformation class designed to maintain each component of the transformation separa...
Definition transform.hpp:27
Class representing a camera. Contains functionality for manipulating and updating a camera....
Definition camera.h:35
Class representing a GPU program.
Definition gpu_program.h:17
std::shared_ptr< gpu_program > ptr
Definition gpu_program.h:19
Structure describing a LOD group (set of meshes), LOD transitions, and their materials.
Definition model.h:42
Shadow mapping generator with improved algorithms for high-altitude cameras.
Definition shadow.h:597
void set_adaptive_params(const adaptive_shadow_params &params)
Definition shadow.h:635
auto get_csm_optimization_flags() const -> uint32_t
Definition shadow.h:622
void generate_shadowmaps(const shadow_map_models_t &model)
Definition shadow.cpp:1907
auto get_frustum_calculation_method() const -> frustum_calculation_method::Enum
Definition shadow.h:619
auto get_adaptive_params() const -> const adaptive_shadow_params &
Definition shadow.h:636
auto get_min_altitude_boost() const -> float
Definition shadow.h:646
auto get_depth_type() const -> PackDepth::Enum
Definition shadow.cpp:1190
void submit_uniforms(uint8_t stage) const
Definition shadow.cpp:1211
auto get_rt_texture(uint8_t split) const -> bgfx::TextureHandle
Definition shadow.cpp:1196
auto get_max_altitude_boost() const -> float
Definition shadow.h:647
void set_altitude_boost_range(float min_boost, float max_boost)
Definition shadow.h:641
void update(const camera &cam, const light &l, const math::transform &ltrans, bool is_active)
Definition shadow.cpp:1236
void init(rtti::context &ctx)
Definition shadow.cpp:570
void set_csm_optimization_flags(uint32_t flags)
Definition shadow.h:621
auto already_updated() const -> bool
Definition shadow.cpp:1231
void set_altitude_scale_factor(float factor)
Definition shadow.h:638
auto get_depth_render_program(PackDepth::Enum depth) const -> gpu_program::ptr
Definition shadow.cpp:1206
void set_frustum_calculation_method(frustum_calculation_method::Enum method)
Definition shadow.h:618
auto get_altitude_scale_factor() const -> float
Definition shadow.h:639
void enable_adaptive_shadows(bool enable)
Definition shadow.h:624
bgfx::VertexLayout vertex_layout
Definition vertex_decl.h:8
hpp::small_vector< entt::handle > shadow_map_models_t
Definition shadow.h:567
Struct representing a light.
Definition light.h:87
ClearValues(uint32_t _clearRgba=0x30303000, float _clearDepth=1.0f, uint8_t _clearStencil=0)
Definition shadow.h:520
SpotDirectionInner m_spotDirectionInner
Definition shadow.h:156
static void init(gfx::vertex_layout &decl)
Definition shadow.h:408
static void init(gfx::vertex_layout &decl)
Definition shadow.h:423
gpu_program::ptr m_packDepthSkinned[DepthImpl::Count][PackDepth::Count]
Definition shadow.h:471
gpu_program::ptr m_hBlur[PackDepth::Count]
Definition shadow.h:468
gpu_program::ptr m_black
Definition shadow.h:466
gpu_program::ptr m_packDepth[DepthImpl::Count][PackDepth::Count]
Definition shadow.h:470
void init(rtti::context &ctx)
Definition shadow.cpp:2353
gpu_program::ptr m_drawDepth[PackDepth::Count]
Definition shadow.h:469
gpu_program::ptr m_vBlur[PackDepth::Count]
Definition shadow.h:467
DepthImpl::Enum m_depthImpl
Definition shadow.h:501
LightType::Enum m_lightType
Definition shadow.h:500
void submitPerFrameUniforms() const
Definition shadow.h:247
void setPtrs(Light *_lightPtr, float *_colorPtr, float *_lightMtxPtr, float *_shadowMapMtx0, float *_shadowMapMtx1, float *_shadowMapMtx2, float *_shadowMapMtx3)
Definition shadow.h:219
void submitPerDrawUniforms() const
Definition shadow.h:256
void submitConstUniforms() const
Definition shadow.h:238
float m_tetraNormalYellow[3]
Definition shadow.h:343
float m_tetraNormalGreen[3]
Definition shadow.h:342