Build and Reuse Effects¶
Compile source with the Windows backend, then attach the resulting Effect to
an animation specification. These construction recipes do not move icons.
Read shader concepts for ownership and safety,
and custom HLSL for stage/pass contracts.
Built-in With Named Parameters¶
use std::collections::BTreeMap;
use rdi_core::{Curve, Effect, Keyframe, KeyframeInterp};
use rdi_platform_windows::shader::{self, BuiltinShader};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let program = shader::compile(BuiltinShader::SilkFlow)?
.with_parameters(&BTreeMap::from([("strands".to_owned(), 8.0)]))?;
let effect = Effect {
params: program.default_params(), shader: program,
padding_px: 24, seed: 7.0,
envelope: Curve::keyframes(vec![
Keyframe::new(0.0, 1.0), Keyframe::new(1.0, 1.0),
], KeyframeInterp::Linear)?,
};
effect.validate()?;
Ok(())
}
Custom Pixel Stage¶
use rdi_core::{Curve, Effect, Keyframe, KeyframeInterp};
use rdi_platform_windows::shader;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let program = shader::compile(r#"
float4 pixel(VertexOutput input) : SV_Target {
float4 color = default_pixel(input);
color.rgb *= float3(0.4, 1.0, 0.7);
return color;
}
"#)?;
let effect = Effect {
params: program.default_params(), shader: program,
padding_px: 16, seed: 0.0,
envelope: Curve::keyframes(vec![
Keyframe::new(0.0, 0.0), Keyframe::new(0.5, 1.0),
Keyframe::new(1.0, 0.0),
], KeyframeInterp::SmoothStep)?,
};
effect.validate()?;
Ok(())
}
Describe a Procedural Pass¶
use std::sync::Arc;
use rdi_core::{EffectParameter, ParameterKind, ShaderPipeline};
use rdi_platform_windows::shader::{self, ExecutionSource, PassSource, ShaderSource};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let recipe = ExecutionSource {
parameters: vec![EffectParameter {
name: "green".into(), kind: ParameterKind::Float,
default: 0.8, min: 0.0, max: 1.0,
}],
passes: vec![PassSource {
pixel: Some(r#"
float4 pixel(VertexOutput input) : SV_Target {
float4 color = default_pixel(input);
color.rgb *= float3(0.5, parameter(0), 0.8);
return color;
}
"#.into()),
..Default::default()
}],
..Default::default()
};
let program = shader::compile(ShaderSource {
pipeline: ShaderPipeline::Procedural,
execution: Some(Arc::new(recipe)), vertex: None, pixel: None,
})?;
println!("Pipeline: {:?}", program.pipeline);
Ok(())
}
For extra passes, fill ExecutionSource.targets with EffectTarget values and
set each PassSource.inputs, output, draw and blend. Input indices refer
to preceding targets. The Python two-pass recipe
shows the same graph and HLSL; the shared contract maps each descriptor to Rust.