use crate::components::MaterialType;
#[derive(Debug, Clone, Copy, PartialEq)]
#[non_exhaustive]
pub struct Routing {
pub instance_flag: f32,
pub unlit_material: bool,
pub baked_lit: bool,
pub is_skybox: bool,
pub is_grid: bool,
pub is_backdrop: bool,
pub skips_deferred: bool,
}
#[must_use]
pub fn route(material_type: MaterialType) -> Routing {
let (instance_flag, unlit_material, baked_lit, is_skybox, is_grid, is_backdrop) =
match material_type {
MaterialType::Pbr => (0.0, false, false, false, false, false),
MaterialType::Water => (0.0, false, false, false, false, false),
MaterialType::Unlit => (1.0, true, false, false, false, false),
MaterialType::BakedLit => (1.0, false, true, false, false, false),
MaterialType::Skybox => (2.0, false, false, true, false, false),
MaterialType::Backdrop | MaterialType::BackdropPlaced => {
(1.0, false, false, false, false, true)
}
MaterialType::Grid => (0.0, false, false, false, true, false),
};
Routing {
instance_flag,
unlit_material,
baked_lit,
is_skybox,
is_grid,
is_backdrop,
skips_deferred: is_skybox || baked_lit || is_backdrop || unlit_material,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn baked_lit_is_not_deferred_pbr() {
let r = route(MaterialType::BakedLit);
assert_eq!(r.instance_flag, 1.0, "BakedLit fell through a wildcard to 0.0 in one path");
assert!(r.baked_lit);
assert!(r.skips_deferred);
assert!(!r.unlit_material, "baked-lit casts shadows; unlit does not — not the same flag");
}
#[test]
fn grid_is_named_rather_than_defaulted() {
let r = route(MaterialType::Grid);
assert!(r.is_grid);
assert!(!r.skips_deferred, "the engine path's wildcard put Grid on the deferred side");
}
#[test]
fn every_variant_has_an_answer() {
let all = [
MaterialType::Pbr,
MaterialType::Unlit,
MaterialType::BakedLit,
MaterialType::Skybox,
MaterialType::Backdrop,
MaterialType::BackdropPlaced,
MaterialType::Water,
MaterialType::Grid,
];
for t in all {
let r = route(t);
assert!(
(0.0..=2.0).contains(&r.instance_flag),
"{t:?} produced an instance flag outside the shader's three cases"
);
assert_eq!(
r.is_backdrop,
crate::backdrop::is_backdrop(t),
"{t:?}: routing and backdrop::is_backdrop disagree"
);
}
}
#[test]
fn skipping_deferred_does_not_mean_skipping_shadows() {
assert!(route(MaterialType::BakedLit).skips_deferred);
assert!(route(MaterialType::Unlit).skips_deferred);
assert_ne!(
route(MaterialType::BakedLit).baked_lit,
route(MaterialType::Unlit).baked_lit,
"these two share skips_deferred and part company in the shadow pass"
);
}
}