Kagari
Type to search documentation.

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.

kis
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

FunctionArgumentsValue
linear(angle)LinearMaska ramp across the box
radial(center)RadialMaskdistance from a point
diamond(center)DiamondMaskthe L1 distance from a point
clock(center, start)ClockMaskthe angle around a point
stripes(angle, count)StripesMaskrepeated linear ramps
checker(columns, rows)CheckerMaska checkerboard of ramps
noise(scale, seed)NoiseMasksmooth random values
gaussian(center, sigma)GaussianMaska Gaussian spot
rounded_rect(radius, feather)RoundedRectMaska 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

kis
#[shader_arg]
pub struct LinearMask {
pub angle: Angle,
}
pub const LINEAR: MaskShader<LinearMask> = asset("shaders/mask/linear.wgsl");
pub const fn linear(angle: Angle) -> Mask

A 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

kis
#[shader_arg]
pub struct RadialMask {
pub center: Anchor,
}
pub const RADIAL: MaskShader<RadialMask> = asset("shaders/mask/radial.wgsl");
pub const fn radial(center: Anchor) -> Mask

A 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

kis
#[shader_arg]
pub struct DiamondMask {
pub center: Anchor,
}
pub const DIAMOND: MaskShader<DiamondMask> = asset("shaders/mask/diamond.wgsl");
pub const fn diamond(center: Anchor) -> Mask

Like radial, with the distance measured as |dx| + |dy|: the reveal grows as a diamond.

Clock

kis
#[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) -> Mask

A 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

kis
#[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) -> Mask

count stripes, each a linear ramp along angle: blinds in any direction. A count of 0 counts as 1.

Checker

kis
#[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) -> Mask

A 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

kis
#[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) -> Mask

Smooth 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

kis
#[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) -> Mask

1.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

kis
#[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) -> Mask

1.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