Modules
std::shaders::mask
Stability: Tentative — procedural masks: ramps and shapes computed per pixel, so masks and transitions need no mask image.
Mask shaders for Entity::mask, Paint::masked
and anim::masked. Every function returns a
Mask whose value lies in 0.0..=1.0 over the masked box: the entity’s
box, the paint, or the layer of a transition.
- As an alpha mask, 1.0 keeps a pixel and 0.0 hides it.
- In a transition, a pixel switches once its value × 255 is at most the sweeping threshold, so low
values go first.
masked_with(…, reverse = true, …)sweeps the other way.
Positions are measured in pixels of the masked box, so a radial mask stays round on a wide box.
use std::screen::{CENTER, degrees};use std::screen::anim::{masked, masked_with};use std::shaders::mask::{clock, linear, noise, rounded_rect};
screen.background().change(BG::NIGHT).apply_animation(masked_with(linear(degrees(0.0)), 32, false, ms(800)));screen.background().change(BG::ROOF).apply_animation(masked(noise(24.0, 7), ms(1200)));screen.entity(CLOCK_FACE).image().change(CLOCK::FACE).apply_animation(masked(clock(CENTER, degrees(-90.0)), ms(1000)));screen.entity(PORTRAIT).mask().change(Some(rounded_rect(24.0, 2.0))).apply_animation(instant());Overview
| Function | Arguments | Value |
|---|---|---|
linear(angle) | LinearMask | a ramp across the box |
radial(center) | RadialMask | distance from a point |
diamond(center) | DiamondMask | the L1 distance from a point |
clock(center, start) | ClockMask | the angle around a point |
stripes(angle, count) | StripesMask | repeated linear ramps |
checker(columns, rows) | CheckerMask | a checkerboard of ramps |
noise(scale, seed) | NoiseMask | smooth random values |
gaussian(center, sigma) | GaussianMask | a Gaussian spot |
rounded_rect(radius, feather) | RoundedRectMask | a rounded rectangle |
Each section below lists the argument struct, the shader constant and the function, which is
const fn, not builtin. In the formulas, p is the pixel’s position in the box, size the box
size and c = center × size.
Linear
#[shader_arg]pub struct LinearMask { pub angle: Angle,}pub const LINEAR: MaskShader<LinearMask> = asset("shaders/mask/linear.wgsl");pub const fn linear(angle: Angle) -> MaskA linear ramp: 0.0 at the edge the direction angle starts from, 1.0 at the opposite edge. 0° runs
left to right, 90° top to bottom. With d = (cos angle, sin angle) and
e = (|d.x|·w + |d.y|·h) / 2, the value is dot(p − size/2, d) / (2e) + 0.5.
Radial
#[shader_arg]pub struct RadialMask { pub center: Anchor,}pub const RADIAL: MaskShader<RadialMask> = asset("shaders/mask/radial.wgsl");pub const fn radial(center: Anchor) -> MaskA circular ramp: 0.0 at center (fractions of the box), 1.0 at the farthest corner. As a
transition it opens a circle from center.
Diamond
#[shader_arg]pub struct DiamondMask { pub center: Anchor,}pub const DIAMOND: MaskShader<DiamondMask> = asset("shaders/mask/diamond.wgsl");pub const fn diamond(center: Anchor) -> MaskLike radial, with the distance measured as |dx| + |dy|: the reveal grows as a diamond.
Clock
#[shader_arg]pub struct ClockMask { pub center: Anchor, pub start: Angle,}pub const CLOCK: MaskShader<ClockMask> = asset("shaders/mask/clock.wgsl");pub const fn clock(center: Anchor, start: Angle) -> MaskA clock sweep: rises from 0.0 to 1.0 turning clockwise around center, starting at start
(0° points right, 90° down, so −90° starts at twelve o’clock).
Stripes
#[shader_arg]pub struct StripesMask { pub angle: Angle, pub count: u32,}pub const STRIPES: MaskShader<StripesMask> = asset("shaders/mask/stripes.wgsl");pub const fn stripes(angle: Angle, count: u32) -> Maskcount stripes, each a linear ramp along angle: blinds in any direction. A count of 0 counts
as 1.
Checker
#[shader_arg]pub struct CheckerMask { pub columns: u32, pub rows: u32,}pub const CHECKER: MaskShader<CheckerMask> = asset("shaders/mask/checker.wgsl");pub const fn checker(columns: u32, rows: u32) -> MaskA checkerboard of columns × rows cells, each a left-to-right ramp. The cells of one colour cover
0.0..0.5 and the others 0.5..1.0, so a transition wipes one colour of cells, then the other. A
count of 0 counts as 1.
Noise
#[shader_arg]pub struct NoiseMask { pub scale: Decimal, pub seed: u32,}pub const NOISE: MaskShader<NoiseMask> = asset("shaders/mask/noise.wgsl");pub const fn noise(scale: Decimal, seed: u32) -> MaskSmooth random values on a grid of scale-pixel cells (at least 1 pixel), varied by seed. As a
transition it is a dissolve; a small scale gives a fine grain, a large one soft blotches.
Gaussian
#[shader_arg]pub struct GaussianMask { pub center: Anchor, pub sigma: Decimal,}pub const GAUSSIAN: MaskShader<GaussianMask> = asset("shaders/mask/gaussian.wgsl");pub const fn gaussian(center: Anchor, sigma: Decimal) -> Mask1.0 at center, falling off as exp(−|p − c|² / (2·sigma²)) with sigma in pixels: a vignette
or a spotlight. A sigma of 0.0 or less gives 0.0 everywhere.
Rounded rectangle
#[shader_arg]pub struct RoundedRectMask { pub radius: Decimal, pub feather: Decimal,}pub const ROUNDED_RECT: MaskShader<RoundedRectMask> = asset("shaders/mask/rounded_rect.wgsl");pub const fn rounded_rect(radius: Decimal, feather: Decimal) -> Mask1.0 inside the box with its corners rounded by radius pixels, 0.0 outside, softened over
feather pixels across the edge. Use it to round the corners of a portrait or a panel.
Last updated Oct 29, 2026