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>
9
10#include <base/basetypes.hpp>
11#include <context/context.hpp>
12
13#include <engine/ecs/ecs.h>
15#include <graphics/graphics.h>
16#include <hpp/small_vector.hpp>
17
18namespace unravel
19{
20namespace shadow
21{
33
35{
36 enum Enum
37 {
40
41 Count
42 };
43};
44
46{
47 enum Enum
48 {
51
52 Count
53 };
54};
55
56struct SmImpl
57{
58 enum Enum
59 {
65
66 Count
67 };
68};
69
70struct SmType
71{
72 enum Enum
73 {
77
78 Count
79 };
80};
81
83{
84 enum Enum
85 {
90
91 Count
92 };
93};
94
96{
97 enum Enum
98 {
101
102 Count
103 };
104};
105
118
120{
121 float m_x;
122 float m_y;
123 float m_z;
124 uint32_t m_normal;
125 float m_u;
126 float m_v;
127};
128
129struct Light
130{
132 {
133 struct
134 {
135 float m_x;
136 float m_y;
137 float m_z;
138 float m_w;
139 };
140
141 float m_v[4];
142 };
143
145 {
146 struct
147 {
148 float m_x;
149 float m_y;
150 float m_z;
151 float m_inner;
152 };
153
154 float m_v[4];
155 };
156
159};
160
162{
163 void init()
164 {
165 m_ambientPass = 1.0f;
166 m_lightingPass = 1.0f;
167
168 m_shadowMapBias = 0.003f;
169 m_shadowMapOffset = 0.0f;
170 m_shadowMapParam0 = 0.5;
171 m_shadowMapParam1 = 1.0;
172 m_depthValuePow = 1.0f;
173 m_showSmCoverage = 1.0f;
174 m_shadowMapTexelSize = 1.0f / 512.0f;
175
176 m_csmFarDistances[0] = 30.0f;
177 m_csmFarDistances[1] = 90.0f;
178 m_csmFarDistances[2] = 180.0f;
179 m_csmFarDistances[3] = 1000.0f;
180
181 m_tetraNormalGreen[0] = 0.0f;
182 m_tetraNormalGreen[1] = -0.57735026f;
183 m_tetraNormalGreen[2] = 0.81649661f;
184
185 m_tetraNormalYellow[0] = 0.0f;
186 m_tetraNormalYellow[1] = -0.57735026f;
187 m_tetraNormalYellow[2] = -0.81649661f;
188
189 m_tetraNormalBlue[0] = -0.81649661f;
190 m_tetraNormalBlue[1] = 0.57735026f;
191 m_tetraNormalBlue[2] = 0.0f;
192
193 m_tetraNormalRed[0] = 0.81649661f;
194 m_tetraNormalRed[1] = 0.57735026f;
195 m_tetraNormalRed[2] = 0.0f;
196
197 m_XNum = 2.0f;
198 m_YNum = 2.0f;
199 m_XOffset = 10.0f / 512.0f;
200 m_YOffset = 10.0f / 512.0f;
201
202 u_params0 = bgfx::createUniform("u_params0", bgfx::UniformType::Vec4);
203 u_params1 = bgfx::createUniform("u_params1", bgfx::UniformType::Vec4);
204 u_params2 = bgfx::createUniform("u_params2", bgfx::UniformType::Vec4);
205 u_color = bgfx::createUniform("u_color", bgfx::UniformType::Vec4);
206 u_smSamplingParams = bgfx::createUniform("u_smSamplingParams", bgfx::UniformType::Vec4);
207 u_csmFarDistances = bgfx::createUniform("u_csmFarDistances", bgfx::UniformType::Vec4);
208 u_lightMtx = bgfx::createUniform("u_lightMtx", bgfx::UniformType::Mat4);
209
210 u_tetraNormalGreen = bgfx::createUniform("u_tetraNormalGreen", bgfx::UniformType::Vec4);
211 u_tetraNormalYellow = bgfx::createUniform("u_tetraNormalYellow", bgfx::UniformType::Vec4);
212 u_tetraNormalBlue = bgfx::createUniform("u_tetraNormalBlue", bgfx::UniformType::Vec4);
213 u_tetraNormalRed = bgfx::createUniform("u_tetraNormalRed", bgfx::UniformType::Vec4);
214
215 u_shadowMapMtx0 = bgfx::createUniform("u_shadowMapMtx0", bgfx::UniformType::Mat4);
216 u_shadowMapMtx1 = bgfx::createUniform("u_shadowMapMtx1", bgfx::UniformType::Mat4);
217 u_shadowMapMtx2 = bgfx::createUniform("u_shadowMapMtx2", bgfx::UniformType::Mat4);
218 u_shadowMapMtx3 = bgfx::createUniform("u_shadowMapMtx3", bgfx::UniformType::Mat4);
219 }
220
221 void setPtrs(Light* _lightPtr,
222 float* _colorPtr,
223 float* _lightMtxPtr,
224 float* _shadowMapMtx0,
225 float* _shadowMapMtx1,
226 float* _shadowMapMtx2,
227 float* _shadowMapMtx3)
228 {
229 m_lightMtxPtr = _lightMtxPtr;
230 m_colorPtr = _colorPtr;
231 m_lightPtr = _lightPtr;
232
233 m_shadowMapMtx0 = _shadowMapMtx0;
234 m_shadowMapMtx1 = _shadowMapMtx1;
235 m_shadowMapMtx2 = _shadowMapMtx2;
236 m_shadowMapMtx3 = _shadowMapMtx3;
237 }
238
239 // Call this once at initialization.
241 {
242 bgfx::setUniform(u_tetraNormalGreen, m_tetraNormalGreen);
243 bgfx::setUniform(u_tetraNormalYellow, m_tetraNormalYellow);
244 bgfx::setUniform(u_tetraNormalBlue, m_tetraNormalBlue);
245 bgfx::setUniform(u_tetraNormalRed, m_tetraNormalRed);
246 }
247
248 // Call this once per frame.
250 {
251 bgfx::setUniform(u_params1, m_params1);
252 bgfx::setUniform(u_params2, m_params2);
253 bgfx::setUniform(u_smSamplingParams, m_paramsBlur);
254 bgfx::setUniform(u_csmFarDistances, m_csmFarDistances);
255 }
256
257 // Call this before each draw call.
259 {
260 bgfx::setUniform(u_shadowMapMtx0, m_shadowMapMtx0);
261 bgfx::setUniform(u_shadowMapMtx1, m_shadowMapMtx1);
262 bgfx::setUniform(u_shadowMapMtx2, m_shadowMapMtx2);
263 bgfx::setUniform(u_shadowMapMtx3, m_shadowMapMtx3);
264
265 bgfx::setUniform(u_params0, m_params0);
266 bgfx::setUniform(u_lightMtx, m_lightMtxPtr);
267 bgfx::setUniform(u_color, m_colorPtr);
268 }
269
270 void destroy()
271 {
272 bgfx::destroy(u_params0);
273 bgfx::destroy(u_params1);
274 bgfx::destroy(u_params2);
275 bgfx::destroy(u_color);
276 bgfx::destroy(u_smSamplingParams);
277 bgfx::destroy(u_csmFarDistances);
278
279 bgfx::destroy(u_tetraNormalGreen);
280 bgfx::destroy(u_tetraNormalYellow);
281 bgfx::destroy(u_tetraNormalBlue);
282 bgfx::destroy(u_tetraNormalRed);
283
284 bgfx::destroy(u_shadowMapMtx0);
285 bgfx::destroy(u_shadowMapMtx1);
286 bgfx::destroy(u_shadowMapMtx2);
287 bgfx::destroy(u_shadowMapMtx3);
288
289 bgfx::destroy(u_lightMtx);
290 }
291
292 union
293 {
294 struct
295 {
300 };
301
302 float m_params0[4];
303 };
304
305 union
306 {
307 struct
308 {
313 };
314
315 float m_params1[4];
316 };
317
318 union
319 {
320 struct
321 {
326 };
327
328 float m_params2[4];
329 };
330
331 union
332 {
333 struct
334 {
335 float m_XNum;
336 float m_YNum;
339 };
340
341 float m_paramsBlur[4];
342 };
343
349
357
358private:
359 bgfx::UniformHandle u_params0;
360 bgfx::UniformHandle u_params1;
361 bgfx::UniformHandle u_params2;
362 bgfx::UniformHandle u_color;
363 bgfx::UniformHandle u_smSamplingParams;
364 bgfx::UniformHandle u_csmFarDistances;
365
366 bgfx::UniformHandle u_tetraNormalGreen;
367 bgfx::UniformHandle u_tetraNormalYellow;
368 bgfx::UniformHandle u_tetraNormalBlue;
369 bgfx::UniformHandle u_tetraNormalRed;
370
371 bgfx::UniformHandle u_shadowMapMtx0;
372 bgfx::UniformHandle u_shadowMapMtx1;
373 bgfx::UniformHandle u_shadowMapMtx2;
374 bgfx::UniformHandle u_shadowMapMtx3;
375
376 bgfx::UniformHandle u_lightMtx;
377};
378
400
401struct PosColorTexCoord0Vertex : gfx::vertex<PosColorTexCoord0Vertex>
402{
403 float m_x;
404 float m_y;
405 float m_z;
406 uint32_t m_rgba;
407 float m_u;
408 float m_v;
409
410 static void init(gfx::vertex_layout& decl)
411 {
412 decl.begin()
413 .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
414 .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
415 .add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
416 .end();
417 }
418};
419
420struct PosVertex : gfx::vertex<PosVertex>
421{
422 float m_x;
423 float m_y;
424 float m_z;
425 static void init(gfx::vertex_layout& decl)
426 {
427 decl.begin().add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float).end();
428 }
429};
430
432{
433 void init(rtti::context& ctx);
434
435 void destroy()
436 {
437 // Pack depth.
438 for(uint8_t ii = 0; ii < DepthImpl::Count; ++ii)
439 {
440 for(uint8_t jj = 0; jj < PackDepth::Count; ++jj)
441 {
442 m_packDepth[ii][jj].reset();
443 m_packDepthInstanced[ii][jj].reset();
444 m_packDepthSkinned[ii][jj].reset();
445 }
446 }
447
448 // Draw depth.
449 for(uint8_t ii = 0; ii < PackDepth::Count; ++ii)
450 {
451 m_drawDepth[ii].reset();
452 }
453
454 // Hblur.
455 for(uint8_t ii = 0; ii < PackDepth::Count; ++ii)
456 {
457 m_hBlur[ii].reset();
458 }
459
460 // Vblur.
461 for(uint8_t ii = 0; ii < PackDepth::Count; ++ii)
462 {
463 m_vBlur[ii].reset();
464 }
465
466 // Misc.
467 m_black.reset();
468 }
469
477};
478
480{
481#define SHADOW_FLOAT_PARAM(_name) \
482 float _name{}, _name##Min{}, _name##Max{}, _name##Step \
483 { \
484 }
485 SHADOW_FLOAT_PARAM(m_sizePwrTwo);
486 SHADOW_FLOAT_PARAM(m_depthValuePow);
490 SHADOW_FLOAT_PARAM(m_normalOffset);
491 SHADOW_FLOAT_PARAM(m_customParam0);
492 SHADOW_FLOAT_PARAM(m_customParam1);
497 bool m_doBlur{};
501#undef SHADOW_FLOAT_PARAM
502};
503
523
525{
526 ClearValues(uint32_t _clearRgba = 0x30303000, float _clearDepth = 1.0f, uint8_t _clearStencil = 0)
527 : clear_rgba(_clearRgba)
528 , clear_depth(_clearDepth)
529 , clear_stencil(_clearStencil)
530 {
531 }
532
533 uint32_t clear_rgba;
536};
537
539{
540 enum Enum
541 {
542 legacy, // Original fixed frustum calculation
543 adaptive, // Altitude-aware adaptive frustum
544 hybrid, // Combination of both approaches
545
546 count
547 };
548};
549
551{
552 enum Enum
553 {
554 none = 0,
555 altitude_compensation = 1 << 0, // Adjust frustum based on camera altitude
556 scene_bounds_fitting = 1 << 1, // Fit to actual scene bounds
557 dynamic_split_weights = 1 << 2, // Adjust split distribution dynamically
558 stabilized_light_matrix = 1 << 3, // Improve light matrix positioning
559
561 };
562};
563
565{
566 float altitude_scale_factor = 0.5f; // How much altitude affects frustum extension
567 float min_altitude_boost = 0.05f; // Minimum altitude compensation
568 float max_altitude_boost = 100.0f; // Maximum altitude compensation
569 float scene_bounds_margin = 1.2f; // Margin factor for scene bounds fitting
570 float split_weight_bias = 0.1f; // Bias for dynamic split weight adjustment
571};
572
573using shadow_map_models_t = hpp::small_vector<entt::handle>;
574
603{
604public:
607
608 void init(rtti::context& ctx);
609 void deinit();
610 void deinit_textures();
611 void deinit_uniforms();
612
613 void update(const camera& cam, const light& l, const math::transform& ltrans, bool is_active);
614 auto already_updated() const -> bool;
615
617
618 auto get_depth_type() const -> PackDepth::Enum;
619 auto get_rt_texture(uint8_t split) const -> bgfx::TextureHandle;
621 void submit_uniforms(uint8_t stage) const;
622
623 // Configuration methods for improved shadow mapping
624 void set_frustum_calculation_method(frustum_calculation_method::Enum method) { frustum_method_ = method; }
625 auto get_frustum_calculation_method() const -> frustum_calculation_method::Enum { return frustum_method_; }
626
627 void set_csm_optimization_flags(uint32_t flags) { csm_optimization_flags_ = flags; }
628 auto get_csm_optimization_flags() const -> uint32_t { return csm_optimization_flags_; }
629
630 void enable_adaptive_shadows(bool enable) {
631 if(enable) {
632 frustum_method_ = frustum_calculation_method::adaptive;
633 csm_optimization_flags_ = csm_optimization_flags::all;
634 } else {
635 frustum_method_ = frustum_calculation_method::legacy;
636 csm_optimization_flags_ = csm_optimization_flags::none;
637 }
638 }
639
640 // Adaptive parameter configuration methods
641 void set_adaptive_params(const adaptive_shadow_params& params) { adaptive_params_ = params; }
642 auto get_adaptive_params() const -> const adaptive_shadow_params& { return adaptive_params_; }
643
644 void set_altitude_scale_factor(float factor) { adaptive_params_.altitude_scale_factor = factor; }
645 auto get_altitude_scale_factor() const -> float { return adaptive_params_.altitude_scale_factor; }
646
647 void set_altitude_boost_range(float min_boost, float max_boost) {
648 adaptive_params_.min_altitude_boost = min_boost;
649 adaptive_params_.max_altitude_boost = max_boost;
650 }
651
652 auto get_min_altitude_boost() const -> float { return adaptive_params_.min_altitude_boost; }
653 auto get_max_altitude_boost() const -> float { return adaptive_params_.max_altitude_boost; }
654
655private:
656 auto render_scene_into_shadowmap(uint8_t shadowmap_1_id,
657 const shadow_map_models_t& models,
659 ShadowMapSettings* currentSmSettings) -> bool;
660
661 void collect_model_for_shadow_batching_cascade(batch_collector& collector,
662 const model& model_asset,
663 const math::mat4& world_transform,
664 const pose_mat4& submesh_transforms,
665 uint32_t lod_index);
666
667 void submit_batched_shadow_geometry_cascade(batch_collector& collector,
668 uint8_t viewId,
669 ShadowMapSettings* currentSmSettings,
670 const RenderState& renderState);
671
672 ClearValues clear_values_;
673
674 float color_[4];
675 Light point_light_;
676 Light directional_light_;
677
678 float light_mtx_[16];
679 float shadow_map_mtx_[ShadowMapRenderTargets::Count][16];
680
682 SceneSettings settings_;
683
684 uint16_t current_shadow_map_size_{};
685 uint8_t current_num_splits_{};
686
687 Uniforms uniforms_;
688 Programs programs_;
689
690 float light_view_[ShadowMapRenderTargets::Count][16];
691 float light_proj_[ShadowMapRenderTargets::Count][16];
692
694
695 bgfx::UniformHandle tex_color_{bgfx::kInvalidHandle};
696 bgfx::UniformHandle shadow_map_[ShadowMapRenderTargets::Count];
697 bgfx::FrameBufferHandle rt_shadow_map_[ShadowMapRenderTargets::Count];
698 bgfx::FrameBufferHandle rt_blur_{bgfx::kInvalidHandle};
699
700 bool valid_{};
701
702 uint64_t last_update_ = -1;
703
704 // Static mesh batching system for shadow maps - one collector per cascade/view
705 std::vector<batch_collector> cascade_batch_collectors_;
706
707 std::shared_ptr<int> sentinel_ = std::make_shared<int>(0);
708
709 // New configuration members
711 uint32_t csm_optimization_flags_ = csm_optimization_flags::none;
712
713 // Additional parameters for adaptive calculations
714 adaptive_shadow_params adaptive_params_;
715};
716
717} // namespace shadow
718} // 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
Core batch collection system for grouping compatible draw calls.
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:603
void set_adaptive_params(const adaptive_shadow_params &params)
Definition shadow.h:641
auto get_csm_optimization_flags() const -> uint32_t
Definition shadow.h:628
void generate_shadowmaps(const shadow_map_models_t &model)
Definition shadow.cpp:1938
auto get_frustum_calculation_method() const -> frustum_calculation_method::Enum
Definition shadow.h:625
auto get_adaptive_params() const -> const adaptive_shadow_params &
Definition shadow.h:642
auto get_min_altitude_boost() const -> float
Definition shadow.h:652
auto get_depth_type() const -> PackDepth::Enum
Definition shadow.cpp:1221
void submit_uniforms(uint8_t stage) const
Definition shadow.cpp:1242
auto get_rt_texture(uint8_t split) const -> bgfx::TextureHandle
Definition shadow.cpp:1227
auto get_max_altitude_boost() const -> float
Definition shadow.h:653
void set_altitude_boost_range(float min_boost, float max_boost)
Definition shadow.h:647
void update(const camera &cam, const light &l, const math::transform &ltrans, bool is_active)
Definition shadow.cpp:1267
void init(rtti::context &ctx)
Definition shadow.cpp:571
void set_csm_optimization_flags(uint32_t flags)
Definition shadow.h:627
auto already_updated() const -> bool
Definition shadow.cpp:1262
void set_altitude_scale_factor(float factor)
Definition shadow.h:644
auto get_depth_render_program(PackDepth::Enum depth) const -> gpu_program::ptr
Definition shadow.cpp:1237
void set_frustum_calculation_method(frustum_calculation_method::Enum method)
Definition shadow.h:624
auto get_altitude_scale_factor() const -> float
Definition shadow.h:645
void enable_adaptive_shadows(bool enable)
Definition shadow.h:630
bgfx::VertexLayout vertex_layout
Definition vertex_decl.h:8
hpp::small_vector< entt::handle > shadow_map_models_t
Definition shadow.h:573
Struct representing a light.
Definition light.h:87
ClearValues(uint32_t _clearRgba=0x30303000, float _clearDepth=1.0f, uint8_t _clearStencil=0)
Definition shadow.h:526
SpotDirectionInner m_spotDirectionInner
Definition shadow.h:158
static void init(gfx::vertex_layout &decl)
Definition shadow.h:410
static void init(gfx::vertex_layout &decl)
Definition shadow.h:425
gpu_program::ptr m_packDepthSkinned[DepthImpl::Count][PackDepth::Count]
Definition shadow.h:475
gpu_program::ptr m_hBlur[PackDepth::Count]
Definition shadow.h:472
gpu_program::ptr m_black
Definition shadow.h:470
gpu_program::ptr m_packDepth[DepthImpl::Count][PackDepth::Count]
Definition shadow.h:474
gpu_program::ptr m_packDepthInstanced[DepthImpl::Count][PackDepth::Count]
Definition shadow.h:476
void init(rtti::context &ctx)
Definition shadow.cpp:2559
gpu_program::ptr m_drawDepth[PackDepth::Count]
Definition shadow.h:473
gpu_program::ptr m_vBlur[PackDepth::Count]
Definition shadow.h:471
DepthImpl::Enum m_depthImpl
Definition shadow.h:507
LightType::Enum m_lightType
Definition shadow.h:506
void submitPerFrameUniforms() const
Definition shadow.h:249
void setPtrs(Light *_lightPtr, float *_colorPtr, float *_lightMtxPtr, float *_shadowMapMtx0, float *_shadowMapMtx1, float *_shadowMapMtx2, float *_shadowMapMtx3)
Definition shadow.h:221
void submitPerDrawUniforms() const
Definition shadow.h:258
void submitConstUniforms() const
Definition shadow.h:240
float m_tetraNormalYellow[3]
Definition shadow.h:345
float m_tetraNormalGreen[3]
Definition shadow.h:344