Skip to main content

bevy_react/filters/
mod.rs

1//! Filter wire types, built-in filters, and the filter registry: the
2//! layer-based `filter` style chain.
3//!
4//! This module owns the filter wire format and registry the way
5//! [`crate::canvas`]/[`crate::animations`] own theirs: `protocol`/
6//! `reconcile`/`ui_map` reference these types by module path, never the
7//! reverse. On the wire a filter is one `{"name", "params"}` object or an
8//! ordered array of them; `params` stays an untyped JSON map at this layer —
9//! typed validation happens later against the registry, not during decode.
10//!
11//! Decoding follows the protocol's warn-don't-abort convention (see
12//! [`Length`](crate::protocol::units::Length)'s custom `Deserialize`): a malformed
13//! value emits a `decode_warn` and the whole chain degrades to empty, never
14//! failing the containing `Style`'s deserialization.
15//!
16//! The typed layer below the wire — [`ReactFilter`], the built-in param
17//! structs, and [`FilterRegistry`] — turns a [`FilterUse`] into
18//! [`ResolvedFilterPass`]es: deserialize the raw params (strict:
19//! deny-unknown-fields), pack them into a `Vec4` uniform array with a
20//! [`ParamSlot`] layout (no-straddle rule: a slot never crosses a `Vec4`
21//! boundary), and pick the pass shader. The thirteen built-ins register via
22//! [`register_builtin_filters`]; custom filters are `#[react_filter]` structs
23//! registered with `add_react_filter`.
24//!
25//! The module also owns the runtime write path of a chain.
26//! [`resolve_chains`] turns a promoted root's [`FilterInput`] into a
27//! [`ResolvedFilterChain`] component — resolving each entry against the
28//! registry (invalid entries skip with a `filterParams` warning), rewriting
29//! `Length` slots to physical px, stamping [`ResolvedFilterPass::wire_index`],
30//! and summing the chain outset. The interpolation primitives
31//! ([`lerp_packed_params`], [`lerp_angle`]) blend packed param arrays
32//! layout-aware for the easing paths. Exactly three systems write
33//! [`ResolvedFilterChain`] and bump its `version` counter: the resolver's
34//! snap, the transition filter channel's whole-value ease (`transition.rs`,
35//! planned by [`plan_filter_ease`] with identity-padding for chain
36//! extensions), and the animation per-param `filter[<i>].<param>` bindings
37//! (`animations`) — see [`ResolvedFilterChain::version`] for the writer
38//! registry and precedence.
39//!
40//! File map: `wire` (the wire format + warn-don't-abort decode), `params`
41//! (packing layout, caps, param value types, interpolation), `registry` (the
42//! [`ReactFilter`] trait, resolved passes, the registry), `builtin` (the
43//! thirteen built-ins), `morph` (the `morphFilter` style's wire type + resolver
44//! instance + runtime state), `transition` (whole-value `filter` transition
45//! planning),
46//! `resolve` (the chain resolve system). Submodules are private; everything
47//! is re-exported here, so `crate::filters::X` is the one path.
48
49mod backdrop;
50mod builtin;
51mod morph;
52mod params;
53mod registry;
54mod resolve;
55mod transition;
56mod wire;
57
58#[cfg(test)]
59mod macro_tests;
60#[cfg(test)]
61pub(crate) mod test_util;
62
63pub use backdrop::{BackdropInput, ResolvedBackdropChain};
64pub use builtin::{
65    BloomParams, BlurParams, BrightnessParams, ChromaticAberrationParams, ContrastParams,
66    CrossfadeParams, GradientMapParams, GradientMapStop, GrayscaleParams, HueRotateParams,
67    InvertParams, LinearWipeParams, MAX_GRADIENT_STOPS, OutlineParams, PixelizeParams,
68    SaturateParams, SepiaParams, ShadowParams, register_builtin_filters,
69};
70pub(crate) use morph::de_morph_filter;
71pub use morph::{
72    MORPH_MAX_USER_PARAM_VECS, MorphFilter, MorphInput, MorphState, ResolvedMorphChain,
73};
74pub use params::{
75    FilterColor, MAX_FILTER_OUTSET_PX, MAX_FILTER_PARAM_VECS, ParamSlot, length_logical_px,
76    lerp_angle, lerp_packed_params,
77};
78pub use registry::{
79    FilterRegistration, FilterRegistry, ReactFilter, ReactMorphFilter, ResolvedFilterPass,
80    resolve_single_pass,
81};
82pub use resolve::{
83    ChainInput, FilterInput, ResolvedChain, ResolvedFilterChain, quantize_outset, resolve_chains,
84};
85pub(crate) use transition::{FilterEase, plan_filter_ease};
86pub use wire::{FilterChain, FilterUse, MAX_CHAIN_LEN};