1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//! Shadow-subsystem constants + the cube-resolution clamp.
//!
//! Anything in here is shape / capacity metadata read by both the
//! Rust-side packing code and (in the case of layout sizes) the
//! WGSL receiver shader via the `ShadowDescriptor` / `ShadowGlobals`
//! UBOs. Keep these in lockstep with `shared_wgsl/shadow/bind_groups.wgsl`.
/// Maximum number of shadow descriptors stored in the per-frame
/// uniform array. 32 entries × 96 B = 3 KB — well under the
/// `maxUniformBufferBindingSize` ceiling (default 64 KB).
pub const MAX_SHADOW_DESCRIPTORS: u32 = 32;
/// Maximum number of shadow VIEWS per frame (one render pass each).
/// Point lights have 6 views per descriptor (cube faces); directional
/// lights have one per cascade. 96 covers a worst case of 8 point +
/// 4 directional × 4 cascades + 32 spots.
pub const MAX_SHADOW_VIEWS: u32 = 96;
/// Size in bytes of a single packed `ShadowDescriptor` (see
/// `shared_wgsl/shadow/bind_groups.wgsl`):
/// - `view_projection: mat4x4<f32>` (64 B)
/// - `atlas_rect: vec4<f32>` (16 B)
/// - `bias_params: vec4<f32>` (16 B)
/// - `cascade_info: vec4<f32>` (16 B)
pub const SHADOW_DESCRIPTOR_BYTES: usize = 112;
/// Size in bytes of the `ShadowGlobals` uniform block. Layout:
/// - `atlas_sizes: vec4<f32>` (16 B) — `(pcf.w, pcf.h, evsm.w, evsm.h)`
/// - `evsm_sscs: vec4<f32>` (16 B)
/// - `flags: vec4<u32>` (16 B)
/// - `cascade_array: vec4<f32>` (16 B) — `(layer.w, layer.h, max_layers, _)`
pub const SHADOW_GLOBALS_BYTES: usize = 64;
/// Logical size of a single per-view shadow uniform entry: a
/// `mat4x4` view-projection (64 B) and a `vec4` of bias parameters
/// (16 B). The actual buffer is laid out with stride
/// `SHADOW_VIEW_STRIDE` so dynamic uniform offsets stay aligned.
pub const SHADOW_VIEW_BYTES: usize = 80;
/// Stride between shadow-view buffer slots — aligned to
/// `minUniformBufferOffsetAlignment` (256 B on every adapter we
/// target) so each slot is a valid dynamic-offset target.
pub const SHADOW_VIEW_STRIDE: usize = 256;
/// Default per-face cube shadow map resolution. The runtime value is
/// `ShadowsConfig::point_shadow_resolution` (held on `Shadows` as
/// `cube_resolution`); this constant is the default the config falls
/// back to. 1024² × 6 × Depth32f × N_lights of VRAM (24 MB for 8
/// lights) — industry standard for medium-quality point shadows.
/// Drop to 512 / 256 for mobile-class browsers; bump to 2048 for
/// ultra-quality.
pub const POINT_SHADOW_RESOLUTION: u32 = 1024;
/// Minimum legal per-face cube resolution. Anything smaller than this
/// produces extreme stair-step aliasing well before saving meaningful
/// memory (a 32² face is 24 KB, vs 256 KB at 256²) — so we clamp.
pub const MIN_POINT_SHADOW_RESOLUTION: u32 = 64;
/// Clamps a user-supplied cube-face resolution to the legal range. The
/// upper bound matches `SHADOW_ATLAS_MAX_SIZE` so a single cube face
/// can't out-size the 2D atlas (`Shadows::new` already saturates VRAM
/// for the 8-light × 6-face pool when we approach that limit).
/// Near plane used when generating each point-light cube face. The
/// receiver-side WGSL constant `POINT_SHADOW_NEAR` MUST match this —
/// the shadow VS writes perspective NDC.z with this near, and the
/// receiver remaps its linear distance to the same NDC.z curve for
/// the comparison. Diverging values cause silent failure (no shadow
/// or all shadow).
pub const POINT_SHADOW_NEAR: f32 = 0.05;
/// Sentinel meaning "this light has no shadow descriptor allocated"
/// in the packed `LightPacked` row 4. The shading shader uses this to
/// short-circuit shadow sampling.
pub const SHADOW_INDEX_NONE: u32 = u32MAX;
/// Upper bound for `atlas_size` when dynamic resizing kicks in. Caps
/// the atlas at 8K to match the plan's "Shadow atlas size dropdown:
/// 1024 / 2048 / 4096 / 8192" ceiling.
pub const SHADOW_ATLAS_MAX_SIZE: u32 = 8192;