Loading...
Searching...
No Matches
ShadowCascadeSetup.hpp
1#pragma once
2#include <halp/controls.hpp>
3#include <halp/meta.hpp>
4
5#include <ossia/dataflow/geometry_port.hpp>
6
7#include <cstdint>
8#include <memory>
9
10namespace Threedim
11{
12
13// Authors a `shadow_cascades_info` for the scene from the active camera
14// frustum and a directional-light direction. Consumed by:
15// - a depth-only shadow_cascades pass (one draw per cascade)
16// - classic_pbr_full's PCF sampling at final shading
17//
18// Practical-split strategy: blend uniform and logarithmic splits with a
19// λ parameter (Engel / Tabellion). λ=0 → pure uniform (equal depth
20// intervals, wastes near-plane resolution), λ=1 → pure log (near-plane
21// heavy, far cascades get almost no area). λ≈0.5 is a good default for
22// interactive scenes.
23//
24// Each cascade's light view_projection fits the camera frustum slice to
25// a square orthographic light-space box centered at the slice's world-
26// space center, oriented along the light direction.
28{
29public:
30 halp_meta(name, "Shadow Cascade Setup")
31 halp_meta(category, "Visuals/3D/Scene")
32 halp_meta(c_name, "shadow_cascade_setup")
33 halp_meta(description, "Calculate directional-light shadow cascades from the active camera frustum.")
34 halp_meta(authors, "ossia team")
35 halp_meta(
36 manual_url,
37 "https://ossia.io/score-docs/processes/shadow-cascade-setup.html")
38 halp_meta(uuid, "7f4d8c2a-9e5b-4f6a-a3d2-1e8c6b9d7f4a")
39
40 struct ins
41 {
42 struct
43 {
44 halp_meta(name, "Scene In");
45 ossia::scene_spec scene;
46 uint8_t dirty{0};
47 } scene_in;
48
49 // Port-driven rebuild: controls trigger rebuild(); upstream
50 // scene_in changes detected in operator()().
51 struct : halp::spinbox_i32<"Cascade count", halp::irange{1, 8, 4}>
52 { void update(ShadowCascadeSetup& n) { n.rebuild(); } } cascade_count;
53 struct : halp::hslider_f32<"Shadow distance", halp::range{1., 10000., 100.}>
54 { void update(ShadowCascadeSetup& n) { n.rebuild(); } } shadow_distance;
55 struct : halp::hslider_f32<"Split lambda", halp::range{0., 1., 0.5}>
56 { void update(ShadowCascadeSetup& n) { n.rebuild(); } } lambda;
57 // Manual near/far override for the camera (the scene_state doesn't
58 // currently expose the active camera's near/far on an accessible
59 // path — these let the user match them). Typical defaults work for
60 // the Camera node's default near=0.1 / far=1000.
61 struct : halp::hslider_f32<"Camera near", halp::range{0.001, 10., 0.1}>
62 { void update(ShadowCascadeSetup& n) { n.rebuild(); } } camera_near;
63 struct : halp::hslider_f32<"Camera far", halp::range{1., 100000., 1000.}>
64 { void update(ShadowCascadeSetup& n) { n.rebuild(); } } camera_far;
65 // Directional-light override. Normally inherited from the first
66 // directional light in the scene with Cast shadow on (or the first
67 // directional light if none casts), but some pipelines (e.g. a single
68 // orbiting light without a Light node) benefit from setting this
69 // directly. The cascades still belong to that light: only their
70 // direction changes.
71 struct : halp::xyz_spinboxes_f32<"Light direction", halp::range{-1., 1., 0.}>
72 { void update(ShadowCascadeSetup& n) { n.rebuild(); } } light_direction;
73 } inputs;
74
75 struct outs
76 {
77 struct
78 {
79 halp_meta(name, "Scene Out");
80 ossia::scene_spec scene;
81 uint8_t dirty{0};
82 } scene_out;
83 } outputs;
84
85 void rebuild();
86 void operator()();
87
88 std::shared_ptr<const ossia::scene_state> m_cached_out;
89 uint8_t m_pending_dirty{0xFF};
90 const ossia::scene_state* m_cached_in_state{};
91 int64_t m_cached_in_version{-1};
92 int m_cached_count{-1};
93 float m_cached_distance{-1.f};
94 float m_cached_lambda{-1.f};
95 float m_cached_near{-1.f};
96 float m_cached_far{-1.f};
97 float m_cached_dir[3]{};
98 int64_t m_version_counter{0};
99 bool m_warned_no_camera{false};
100};
101
102}
Definition ShadowCascadeSetup.hpp:28
Definition ShadowCascadeSetup.hpp:41
Definition ShadowCascadeSetup.hpp:76