Build and Reuse Effects¶
These recipes construct effects without moving icons. Attach the returned effect
to an IconAnimationSpec, then use the off-screen example
before live playback. See shader concepts and
the custom HLSL contract for pipeline details.
Compile a Built-in Once¶
import rusty_desktop_icons as rdi
shader = rdi.Shader.compile(rdi.ShaderSource.builtin(rdi.BuiltinShader.SilkFlow))
effect = rdi.Effect(
shader, parameters={"strands": 8, "spread": 1.0, "folds": 2.0, "density": 0.8},
seed=7.0,
)
Reuse shader across effects with different seeds/parameters. The catalog also
provides Identity, Glitch, ParticleVortex and DustTransfer.
Tint the Artwork¶
import rusty_desktop_icons as rdi
source = rdi.ShaderSource(pixel="""
float4 pixel(VertexOutput input) : SV_Target {
float4 color = default_pixel(input);
color.rgb *= float3(0.4, 1.0, 0.7);
return color;
}
""")
effect = rdi.Effect(rdi.Shader.compile(source), padding_px=16)
The Sprite wrapper fades the pixel effect using its envelope. To displace the
geometry too, supply a vertex string with the signature in the custom contract.
Add a Named Procedural Parameter¶
import rusty_desktop_icons as rdi
recipe = rdi.ProceduralSource(
parameters=[rdi.EffectParameter("green", 0.8, min=0.0, max=1.0)],
passes=[rdi.RenderPass(pixel="""
float4 pixel(VertexOutput input) : SV_Target {
float4 color = default_pixel(input);
color.rgb *= float3(0.5, parameter(0), 0.8);
return color;
}
""")],
)
shader = rdi.Shader.compile(rdi.ShaderSource(
pipeline=rdi.ShaderPipeline.Procedural, execution=recipe,
))
effect = rdi.Effect(shader, parameters={"green": 1.0})
Render Through an Intermediate Target¶
import rusty_desktop_icons as rdi
fullscreen = """
VertexOutput vertex(Instance instance, uint vertex_id : SV_VertexID) {
VertexOutput output = default_vertex(instance, vertex_id);
output.position = float4(output.uv.x * 2 - 1, 1 - output.uv.y * 2, 0, 1);
return output;
}
"""
composite = """
float4 pixel(VertexOutput input) : SV_Target {
return pass_inputs[0].Sample(artwork_sampler, input.uv);
}
"""
recipe = rdi.ProceduralSource(
targets=[rdi.RenderTarget(128, 128)],
passes=[
rdi.RenderPass(vertex=fullscreen, output=0, blend="replace"),
rdi.RenderPass(pixel=composite, inputs=[0]),
],
)
shader = rdi.Shader.compile(rdi.ShaderSource(
pipeline=rdi.ShaderPipeline.Procedural, execution=recipe,
))
effect = rdi.Effect(shader)
The first pass maps the complete artwork onto the target; the second maps that target onto the icon’s scene rectangle. This is a resampling example, not a blur or feedback simulation. Add processing in the first/second pixel stage within the pass-graph limits.