Shaders and Effects¶
A shader changes rendered artwork, not the real Shell icon. Compile a reusable
program, wrap it in an Effect, and attach it to an IconAnimationSpec.
Effects work in live animations, seekable timelines and off-screen scenes.
Sources, Programs and Effects¶
ShaderSource holds optional vertex/pixel HLSL, a ShaderPipeline and optional
procedural execution recipe. Python Shader.compile returns a Shader; Rust
shader::compile returns a ShaderProgram. Compilation validates and compiles
source, while animation preparation creates device resources and artwork.
Reuse the compiled program across icons rather than compiling every frame.
Effect adds values, a seed, transparent padding and a strength envelope.
Python accepts a four-float params tuple or named parameters for a declared
recipe. Rust uses the program’s four-value default_params() array and
with_parameters for named recipe values; procedural execution expands these
to 16 slots. Values must match the pipeline/schema; padding is 0..256 physical
pixels. Seeds must be finite; particle/procedural seeds also require absolute
value at most 65535.
The envelope is independent of X/Y motion. Sprite/particle Python defaults fade
in and out; procedural defaults use constant strength. Strength is clamped to
[0, 1]. Endpoints and zero-strength frames use the original artwork. A movement
hold does not pause the effect, and a stationary target can still have an effect
for the entire nonzero fixed duration.
Built-ins¶
|
Use |
|---|---|
Identity |
Baseline artwork rendering |
Glitch |
Displaced horizontal bands and RGB separation |
ParticleVortex |
Artwork fragments orbit and reform |
DustTransfer |
Side-first dissolution and destination assembly |
SilkFlow |
Artwork-colored translucent sheets with label-last reveal |
The built-in catalog is shared across Python and Rust. Dust Transfer and Silk Flow control transport internally; constant-strength envelopes avoid blending their motion back toward the ordinary moving sprite. They are stateless effects, not fluid solvers or persistent particle simulations.
Silk Flow declares four named parameters:
Name |
Default |
Valid range |
|---|---|---|
|
8 |
Integer 2..16 |
|
1 |
0..3 icon-width units |
|
2 |
0.25..6 |
|
0.8 |
0.1..1 |
Particle Vortex and Dust Transfer use the four particle slots described in custom pipelines. Sprite custom parameters are untyped finite floats, so do not apply a built-in’s visual meaning to an unrelated shader.
Enabled labels and badges are part of the input artwork. Procedural recipes can request body and label regions separately. Destination grid reservations do not confine shader pixels: effects can overlap neighbors and clip at edges.
Animation Presets¶
AnimationPreset is a platform-independent value type (rdi_core::AnimationPreset
in Rust). It contains movement: Curve, envelope: Curve and duration: Duration.
AnimationPreset::default() / Python AnimationPreset() returns ease-in-out
movement, smooth strength fades over the first/last 15%, and a fixed two seconds.
Python accepts optional keyword overrides for each field and exposes read-only
properties; Rust exposes owned public fields. Every lookup returns an independent
value, without compiling a shader or creating desktop resources.
On Windows, obtain shader recommendations with Rust
BuiltinShader::DustTransfer.default_preset() or Python
AnimationPreset.builtin(BuiltinShader.DustTransfer). Python also accepts the
catalog name string. Built-in lookup raises UnsupportedPlatform elsewhere;
constructing and using the common preset value itself remains portable.
Shader |
Movement |
Envelope |
Duration |
|---|---|---|---|
Identity |
Ease-in-out |
Smooth 15% fades |
2 seconds |
Glitch |
Smooth travel between 15% and 85%, holds outside |
Smooth 15% fades |
2 seconds |
ParticleVortex |
Ease-in-out |
Smooth 15% fades |
4 seconds |
DustTransfer |
Ease-in-out |
Constant one |
4 seconds |
SilkFlow |
Ease-in-out |
Constant one |
5 seconds |
Pass the values separately through the existing APIs. This Windows example constructs a spec but does not start playback or move real icons:
import rusty_desktop_icons as rdi
preset = rdi.AnimationPreset.builtin(rdi.BuiltinShader.DustTransfer)
shader = rdi.Shader.compile(rdi.ShaderSource.builtin(rdi.BuiltinShader.DustTransfer))
effect = rdi.Effect(shader, envelope=preset.envelope)
spec = rdi.IconAnimationSpec(
id="example", target=(600, 300), duration=preset.duration,
curve=preset.movement, effect=effect,
)
Reuse shader across icons. Substitute any field with your own curve/duration,
or pass the movement curve independently as curve_x and curve_y. Presets are
opt-in: existing constructors and showcases retain their defaults. The interactive
timeline editor applies them when selecting built-in shaders in Default Preset
mode; its duration slider and Custom curves remain independent afterward.
Movement does not retime shader progress or pause an effect during a hold.
Dust Transfer/Silk Flow own visual travel at full strength, but the movement
curve still determines the engine position used for stop-in-place. Constant
envelopes do not disable the engine’s clean endpoint override.
Catalog contributors may add default_preset: <expression> after pixel in
builtin_shaders!. Omitting it returns AnimationPreset::default(). Keep
shader-specific recommendations in this catalog, not in the core renderer.
Trusted Source Only¶
This is a proof-of-concept HLSL API, not a security sandbox. Expensive or malicious code can stall the GPU, freeze the display or trigger a driver reset. Filesystem includes are disabled, but that does not establish compiler/driver safety. Review third-party or AI-generated source before compiling it. Shader interfaces are not promised stable; the implemented backend is D3D11/HLSL, not WGSL.