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(authors, "ossia team")
34 halp_meta(
35 manual_url,
36 "https://ossia.io/score-docs/processes/shadow-cascade-setup.html")
37 halp_meta(uuid, "7f4d8c2a-9e5b-4f6a-a3d2-1e8c6b9d7f4a")
38
39 struct ins
40 {
41 struct
42 {
43 halp_meta(name, "Scene In");
44 ossia::scene_spec scene;
45 uint8_t dirty{0};
46 } scene_in;
47
48 // Port-driven rebuild: controls trigger rebuild(); upstream
49 // scene_in changes detected in operator()().
50 struct : halp::spinbox_i32<"Cascade count", halp::irange{1, 8, 4}>
51 { void update(ShadowCascadeSetup& n) { n.rebuild(); } } cascade_count;
52 struct : halp::hslider_f32<"Shadow distance", halp::range{1., 10000., 100.}>
53 { void update(ShadowCascadeSetup& n) { n.rebuild(); } } shadow_distance;
54 struct : halp::hslider_f32<"Split lambda", halp::range{0., 1., 0.5}>
55 { void update(ShadowCascadeSetup& n) { n.rebuild(); } } lambda;
56 // Manual near/far override for the camera (the scene_state doesn't
57 // currently expose the active camera's near/far on an accessible
58 // path — these let the user match them). Typical defaults work for
59 // the Camera node's default near=0.1 / far=1000.
60 struct : halp::hslider_f32<"Camera near", halp::range{0.001, 10., 0.1}>
61 { void update(ShadowCascadeSetup& n) { n.rebuild(); } } camera_near;
62 struct : halp::hslider_f32<"Camera far", halp::range{1., 100000., 1000.}>
63 { void update(ShadowCascadeSetup& n) { n.rebuild(); } } camera_far;
64 // Directional-light override. Normally inherited from the first
65 // directional light in the scene, but some pipelines (e.g. a single
66 // orbiting light without a Light node) benefit from setting this
67 // directly.
68 struct : halp::xyz_spinboxes_f32<"Light direction", halp::range{-1., 1., 0.}>
69 { void update(ShadowCascadeSetup& n) { n.rebuild(); } } light_direction;
70 } inputs;
71
72 struct outs
73 {
74 struct
75 {
76 halp_meta(name, "Scene Out");
77 ossia::scene_spec scene;
78 uint8_t dirty{0};
79 } scene_out;
80 } outputs;
81
82 void rebuild();
83 void operator()();
84
85 std::shared_ptr<const ossia::scene_state> m_cached_out;
86 uint8_t m_pending_dirty{0xFF};
87 const ossia::scene_state* m_cached_in_state{};
88 int64_t m_cached_in_version{-1};
89 int m_cached_count{-1};
90 float m_cached_distance{-1.f};
91 float m_cached_lambda{-1.f};
92 float m_cached_near{-1.f};
93 float m_cached_far{-1.f};
94 float m_cached_dir[3]{};
95 int64_t m_version_counter{0};
96};
97
98}
Definition ShadowCascadeSetup.hpp:28
Definition ShadowCascadeSetup.hpp:40
Definition ShadowCascadeSetup.hpp:73