Clip + spotlight on vector masks
|
|
|
Output is pixel-identical to the M-MASK.1 / M-MASK.6 equivalents —
the vector path lets you drive both off the same Vector value, and
adds freehand-polygon variants of each.
Closes the M-VEC.4..6 refactor zone. apply_clip (the rounded-crop
foundation from M-MASK.1) and apply_spotlight (M-MASK.6) now route
through the shared mask + compose path. Path-driven variants of both
land here.
#![allow(unused)] fn main() { use glam::Vec2; use wisp::{Color, Vector, VectorShape}; // Path-driven crop (impossible before M-VEC.6): let diamond = Vector::new(VectorShape::path(vec![ Vec2::new( 0.0, 0.6), Vec2::new( 0.6, 0.0), Vec2::new( 0.0, -0.6), Vec2::new(-0.6, 0.0), ])); renderer.apply_clip_vector(&app, &diamond, &foreground, &output); // Path-driven spotlight (impossible before M-VEC.6): renderer.apply_spotlight_vector( &app, &diamond, Color::rgba(0.0, 0.0, 0.0, 0.7), &base, &output, ); }
Architecture
apply_clip(and the newapply_clip_vector) — usescached_vector_mask_texture+apply_mask_to_texture. Output is byte-equivalent to the previousClipPipelinepath.apply_spotlight_vector— same pattern but with the inverted mask. Analytic shapes usecached_mask_texture_inverted; the path variant routes throughpath_clip.applyininvert: truemode (the cached path-mask doesn't have an inverted form yet — straightforward future extension).
Auto-dispatch path NOT refactored
render_stage auto-dispatches Container::clip = Some(MaskShape)
through the inline ClipPipeline directly. That path is hot —
called per dispatched node every frame — and the existing single-
shader implementation already optimizes it. The vector-mask refactor
adds an extra render pass per call which is fine for explicit
primitives (offset by mask cache hits) but would be a regression on
the hot path. The auto-dispatch keeps using the inline clip
pipeline; explicit apply_clip calls go through the new path.

