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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//! Shader cache key for the **masked** (alpha-tested) variant of the
//! geometry / visibility-buffer raster pass.
//!
//! A material with glTF `alphaMode = MASK` is alpha-tested *opaque* — it
//! belongs in the visibility/opaque path (so transmission samples it, it
//! casts shadows, and it's deferred-shaded), but its fragments below the
//! cutoff must be `discard`ed so cutouts are see-through. The plain
//! geometry raster writes depth unconditionally; this masked variant adds
//! the per-fragment cutoff `discard` before writing the visibility buffer,
//! so holes never write depth (and later depth-tested geometry / shadows /
//! transmission show through them).
//!
//! The variant is **specialized per `shader_id`** (mirroring the opaque
//! compute's `ShaderCacheKeyMaterialOpaque`) because the geometry template
//! cannot include the full `materials_wgsl` blob — it pulls dynamic-material
//! fragments that reference opaque-only contract types. Built-in materials
//! (PBR / Unlit / Toon) emit a minimal base-color-alpha load; a dynamic
//! (custom) material emits the author's *alpha-only* WGSL fragment.
//!
//! To stay within the `maxBindGroups = 4` ceiling the masked variant does
//! NOT add a 5th group: it reuses the plain geometry pass's groups 1
//! (transforms), 2 (uniform meta) and 3 (animation) verbatim, and *appends*
//! its fragment-only bindings (materials, material_mesh_metas, the merged
//! geometry pool, texture_transforms, texture pool) onto group 0 — which
//! already carries the camera/frame_globals uniforms the shared vertex
//! reads. The vertex path is therefore untouched.
//!
//! Masked meshes always take the non-instanced, uniform-meta, CPU-recorded
//! draw path (so this key carries no instancing / meta-storage toggles);
//! instanced masked meshes fall back to the plain (solid) pipeline.
use MaterialShaderId;
use crate::;
/// Cache key for the masked geometry raster shader.
/// Per-dynamic-material info embedded in the masked cache key so the
/// template can emit the author's alpha-only fragment + its `MaterialData`
/// accessor. Mirrors `material_opaque`'s `DynamicShaderInfo`, but carries
/// the *second* (alpha-only) WGSL window rather than the color fragment.
///
/// Hashed by the generated WGSL strings; two registrations that produce
/// byte-identical WGSL collapse to the same compiled shader.