Pass
Description
Section titled “Description”The Pass object is a collection of Shader objects that are rendered to a Target by the Renderer.
While the Shader represents a single Render Pipeline or a Compute Pipeline, the Pass can be used to draw multiple Shaders in sequence, for example when you have multiple objects in a scene with different materials.
The Pass represents a single RenderPass or a ComputePass in the WebGPU API.
The constructor creates a RenderPass by default. To create a ComputePass, call Pass::compute().
After creation, it will only accept a compatible Shader object. If you try to add a Compute Shader to a Render Pass or vice-versa, it won’t add the shader to its internal list and log a warning message in the console.
Example
Section titled “Example”1 collapsed line
async fn run() -> Result<(), Box<dyn std::error::Error>> {
use fragmentcolor::{ Shader, Pass, Renderer };
let renderer = Renderer::new();let window = fragmentcolor::headless_window([100, 100]);let target = renderer.create_target(window).await?;let shader = Shader::default();
let mut pass = Pass::new("First Pass");pass.add_shader(&shader);
let mut pass2 = Pass::new("Second Pass");pass2.add_shader(&shader);
// standalonerenderer.render(&pass, &target)?;
// vector of passes rendered in order (any iterable of Pass is renderable)renderer.render(&vec![pass, pass2], &target)?;
3 collapsed lines
Ok(())}fn main() -> Result<(), Box<dyn std::error::Error>> { pollster::block_on(run()) }import { Shader, Pass, Renderer } from "fragmentcolor";
const renderer = new Renderer();const canvas = document.createElement('canvas');const target = await renderer.createTarget(canvas);const shader = Shader.default();
const pass = new Pass("First Pass");pass.addShader(shader);
const pass2 = new Pass("Second Pass");pass2.addShader(shader);
// standalonerenderer.render(pass, target);
// vector of passes rendered in order (any iterable of Pass is renderable)renderer.render([pass, pass2], target);import os, sys# Skip this example in headless/CI environments that have no display surface.if os.environ.get('DISPLAY') is None and sys.platform != 'win32' and os.environ.get('FC_ALLOW_WINDOW') != '1': raise SystemExit(0)
from rendercanvas.auto import RenderCanvas, loop
from fragmentcolor import Shader, Pass, Renderer
renderer = Renderer()canvas = RenderCanvas(size=(100, 100))target = renderer.create_target(canvas)shader = Shader.default()
rpass = Pass("First Pass")rpass.add_shader(shader)
pass2 = Pass("Second Pass")pass2.add_shader(shader)
# standalonerenderer.render(rpass, target)
# vector of passes rendered in order (any iterable of Pass is renderable)renderer.render([rpass, pass2], target)import FragmentColor
let renderer = Renderer()// iOS: window/canvas provided by CAMetalLayer at runtimelet target = try await renderer.createTextureTarget([800, 600])let shader = Shader.default()
let pass = Pass("First Pass")pass.addShader(shader)
let pass2 = Pass("Second Pass")pass2.addShader(shader)
// standalonetry renderer.render(pass, target)
// vector of passes rendered in order (any iterable of Pass is renderable)try renderer.render([pass, pass2], target)import org.fragmentcolor.*
val renderer = Renderer()// HEADLESS: canvas creation not needed on Androidval target = renderer.createTextureTarget(800u, 600u)val shader = Shader.default()
val pass = Pass("First Pass")pass.addShader(shader)
val pass2 = Pass("Second Pass")pass2.addShader(shader)
// standalonerenderer.render(pass, target)
// vector of passes rendered in order (any iterable of Pass is renderable)renderer.render(listOf(pass, pass2), target)Methods
Section titled “Methods”Pass::new(name: &str) -> Self
Section titled “Pass::new(name: &str) -> Self”Creates a new Pass
Section titled “Creates a new Pass”The name property is optional and is used for debugging purposes.
Example
Section titled “Example”use fragmentcolor::Pass;
let pass = Pass::new("first pass");
1 collapsed line
_ = pass;import { Pass } from "fragmentcolor";
const pass = new Pass("first pass");from fragmentcolor import Pass
rpass = Pass("first rpass")import FragmentColor
let pass = Pass("first pass")import org.fragmentcolor.*
val pass = Pass("first pass")Pass::compute(name: &str) -> Pass
Section titled “Pass::compute(name: &str) -> Pass”Creates a new Pass configured for compute workloads.
Only Shader objects that compile to compute pipelines can be added.
Example
Section titled “Example”use fragmentcolor::{Pass, Shader};
let cs = Shader::new("@compute @workgroup_size(8,8,1) fn cs_main() {}").unwrap();let pass = Pass::from_shader("compute", &cs);import { Pass, Shader } from "fragmentcolor";
const cs = new Shader("@compute @workgroup_size(8,8,1) fn cs_main() {}").unwrap();const pass = new Pass("compute"); pass.addShader(cs);from fragmentcolor import Pass, Shader
cs = Shader("@compute @workgroup_size(8,8,1) fn cs_main() {}")rpass = Pass("compute"); rpass.add_shader(cs)import FragmentColor
let cs = try! Shader("@compute @workgroup_size(8,8,1) fn cs_main() {}")let pass = Pass("compute"); pass.addShader(cs)import org.fragmentcolor.*
val cs = Shader("@compute @workgroup_size(8,8,1) fn cs_main() {}")val pass = Pass("compute"); pass.addShader(cs)Pass::from_shader(name: &str, shader: Shader) -> Pass
Section titled “Pass::from_shader(name: &str, shader: Shader) -> Pass”Creates a new Pass from a single Shader.
The created Pass inherits the render/compute type from the provided Shader.
Example
Section titled “Example”use fragmentcolor::{Pass, Shader};
let shader = Shader::default();let pass = Pass::from_shader("single", &shader);import { Pass, Shader } from "fragmentcolor";
const shader = Shader.default();const pass = new Pass("single"); pass.addShader(shader);from fragmentcolor import Pass, Shader
shader = Shader.default()rpass = Pass("single"); rpass.add_shader(shader)import FragmentColor
let shader = Shader.default()let pass = Pass("single"); pass.addShader(shader)import org.fragmentcolor.*
val shader = Shader.default()val pass = Pass("single"); pass.addShader(shader)Pass::load_previous()
Section titled “Pass::load_previous()”Configures this Pass to load the previous contents of the Target instead of clearing it.
This is useful when layering multiple passes where the next pass should blend with the prior results.
Example
Section titled “Example”1 collapsed line
async fn run() -> Result<(), Box<dyn std::error::Error>> {
use fragmentcolor::{Renderer, Pass, Shader};
let renderer = Renderer::new();let target = renderer.create_texture_target([64, 64]).await?;
let shader = Shader::default();let mut pass = Pass::new("blend with previous");pass.add_shader(&shader);pass.load_previous();
renderer.render(&pass, &target)?;
3 collapsed lines
Ok(())}fn main() -> Result<(), Box<dyn std::error::Error>> { pollster::block_on(run()) }import { Renderer, Pass, Shader } from "fragmentcolor";
const renderer = new Renderer();const target = await renderer.createTextureTarget([64, 64]);
const shader = Shader.default();const pass = new Pass("blend with previous");pass.addShader(shader);pass.loadPrevious();
renderer.render(pass, target);from fragmentcolor import Renderer, Pass, Shader
renderer = Renderer()target = renderer.create_texture_target([64, 64])
shader = Shader.default()rpass = Pass("blend with previous")rpass.add_shader(shader)rpass.load_previous()
renderer.render(rpass, target)import FragmentColor
let renderer = Renderer()let target = try await renderer.createTextureTarget([64, 64])
let shader = Shader.default()let pass = Pass("blend with previous")pass.addShader(shader)pass.loadPrevious()
try renderer.render(pass, target)import org.fragmentcolor.*
val renderer = Renderer()val target = renderer.createTextureTarget(64u, 64u)
val shader = Shader.default()val pass = Pass("blend with previous")pass.addShader(shader)pass.loadPrevious()
renderer.render(pass, target)Pass::get_input() -> PassInput
Section titled “Pass::get_input() -> PassInput”Returns a copy of the current input configuration for this Pass.
It includes the clear/load behavior and clear color.
Example
Section titled “Example”use fragmentcolor::Pass;
let pass = Pass::new("example");let input = pass.get_input();
1 collapsed line
_ = input; // Silence unused variable warningimport { Pass } from "fragmentcolor";
const pass = new Pass("example");const input = pass.getInput();from fragmentcolor import Pass
rpass = Pass("example")input = rpass.get_input()import FragmentColor
let pass = Pass("example")let input = pass.getInput()import org.fragmentcolor.*
val pass = Pass("example")val input = pass.getInput()Pass::add_shader(shader: Shader)
Section titled “Pass::add_shader(shader: Shader)”Add a Shader to the Pass. Shaders run in the order they were added, sharing the pass’s targets, viewport, clear color, and load policy.
Example
Section titled “Example”use fragmentcolor::{Pass, Shader};
let shader = Shader::default();let pass = Pass::new("p");pass.add_shader(&shader);import { Pass, Shader } from "fragmentcolor";
const shader = Shader.default();const pass = new Pass("p");pass.addShader(shader);from fragmentcolor import Pass, Shader
shader = Shader.default()rpass = Pass("p")rpass.add_shader(shader)import FragmentColor
let shader = Shader.default()let pass = Pass("p")pass.addShader(shader)import org.fragmentcolor.*
val shader = Shader.default()val pass = Pass("p")pass.addShader(shader)Pass::add_mesh
Section titled “Pass::add_mesh”Attach a Mesh to this Pass.
- The mesh is attached to the last shader previously added to this Pass.
- Validates compatibility with that shaderâs vertex inputs.
- Returns Result
Result<(), ShaderError>; on error, the mesh is not attached.
If a Shader wasn’t provided earlier, FragmentColor will create a default one.
Example
Section titled “Example”1 collapsed line
fn main() -> Result<(), Box<dyn std::error::Error>> {use fragmentcolor::{Pass, Shader, Mesh};
let mesh = Mesh::new();mesh.add_vertex([0.0, 0.0]);
let shader = Shader::new(r#"struct VOut { @builtin(position) pos: vec4<f32> };@vertexfn vs_main(@location(0) pos: vec2<f32>) -> VOut { var out: VOut; out.pos = vec4<f32>(pos, 0.0, 1.0); return out;}@fragmentfn fs_main(_v: VOut) -> @location(0) vec4<f32> { return vec4<f32>(1.,0.,0.,1.); }"#)?;
let pass = Pass::from_shader("pass", &shader);
pass.add_mesh(&mesh)?;
2 collapsed lines
Ok(())}import { Pass, Shader, Mesh } from "fragmentcolor";
const mesh = new Mesh();mesh.addVertex([0.0, 0.0]);
const shader = new Shader(`
struct VOut { @builtin(position) pos: vec4<f32> };@vertexfn vs_main(@location(0) pos: vec2<f32>) -> VOut { var out: VOut; out.pos = vec4<f32>(pos, 0.0, 1.0); return out;}@fragmentfn fs_main(_v: VOut) -> @location(0) vec4<f32> { return vec4<f32>(1.,0.,0.,1.); }
`);
const pass = new Pass("pass"); pass.addShader(shader);
pass.addMesh(mesh);from fragmentcolor import Pass, Shader, Mesh
mesh = Mesh()mesh.add_vertex([0.0, 0.0])
shader = Shader("""struct VOut { @builtin(position) pos: vec4<f32> };@vertexfn vs_main(@location(0) pos: vec2<f32>) -> VOut { var out: VOut; out.pos = vec4<f32>(pos, 0.0, 1.0); return out;}@fragmentfn fs_main(_v: VOut) -> @location(0) vec4<f32> { return vec4<f32>(1.,0.,0.,1.); }
""")
rpass = Pass("rpass"); rpass.add_shader(shader)
rpass.add_mesh(mesh)import FragmentColor
let mesh = Mesh()try mesh.addVertex([0.0, 0.0])
let shader = try Shader("""struct VOut { @builtin(position) pos: vec4<f32> }@vertexfn vs_main(@location(0) pos: vec2<f32>) -> VOut { var out: VOut out.pos = vec4<f32>(pos, 0.0, 1.0) return out}@fragmentfn fs_main(_v: VOut) -> @location(0) vec4<f32> { return vec4<f32>(1.,0.,0.,1.); }
""")
let pass = Pass("pass"); pass.addShader(shader)
try pass.addMesh(mesh)import org.fragmentcolor.*
val mesh = Mesh()mesh.addVertex(Vertex(listOf(0.0f, 0.0f)))
val shader = Shader("""struct VOut { @builtin(position) pos: vec4<f32> }@vertexfn vs_main(@location(0) pos: vec2<f32>) -> VOut { var out: VOut out.pos = vec4<f32>(pos, 0.0, 1.0) return out}@fragmentfn fs_main(_v: VOut) -> @location(0) vec4<f32> { return vec4<f32>(1.,0.,0.,1.); }
""")
val pass = Pass("pass"); pass.addShader(shader)
pass.addMesh(mesh)Pass::set_viewport(viewport)
Section titled “Pass::set_viewport(viewport)”Sets the viewport region for this Pass.
The viewport restricts drawing to a rectangular area of the Target.
The viewport argument accepts anything convertible into a ScreenRegion â an [x, y, w, h] array, a (w, h) tuple, or a ScreenRegion constructed explicitly.
Example
Section titled “Example”1 collapsed line
async fn run() -> Result<(), Box<dyn std::error::Error>> {
use fragmentcolor::{Renderer, Pass, Shader, ScreenRegion};
let renderer = Renderer::new();let target = renderer.create_texture_target([64, 64]).await?;
let shader = Shader::default();let mut pass = Pass::new("clipped");pass.add_shader(&shader);
pass.set_viewport(ScreenRegion::new((0, 0), (32, 32)));
renderer.render(&pass, &target)?;
3 collapsed lines
Ok(())}fn main() -> Result<(), Box<dyn std::error::Error>> { pollster::block_on(run()) }import { Renderer, Pass, Shader, ScreenRegion } from "fragmentcolor";
const renderer = new Renderer();const target = await renderer.createTextureTarget([64, 64]);
const shader = Shader.default();const pass = new Pass("clipped");pass.addShader(shader);
pass.setViewport([(0, 0), (32, 32)]);
renderer.render(pass, target);from fragmentcolor import Renderer, Pass, Shader, ScreenRegion
renderer = Renderer()target = renderer.create_texture_target([64, 64])
shader = Shader.default()rpass = Pass("clipped")rpass.add_shader(shader)
rpass.set_viewport(ScreenRegion((0, 0), (32, 32)))
renderer.render(rpass, target)import FragmentColor
let renderer = Renderer()let target = try await renderer.createTextureTarget([64, 64])
let shader = Shader.default()let pass = Pass("clipped")pass.addShader(shader)
pass.setViewport([(0, 0), (32, 32)])
try renderer.render(pass, target)import org.fragmentcolor.*
val renderer = Renderer()val target = renderer.createTextureTarget(64u, 64u)
val shader = Shader.default()val pass = Pass("clipped")pass.addShader(shader)
pass.setViewport(ScreenRegion(minX=0u, minY=0u, maxX=32u, maxY=32u))
renderer.render(pass, target)Pass::set_clear_color(color: [f32; 4])
Section titled “Pass::set_clear_color(color: [f32; 4])”Sets the clear color for this Pass.
When the pass is configured to clear, the render target is cleared to the given RGBA color before drawing.
Example
Section titled “Example”1 collapsed line
async fn run() -> Result<(), Box<dyn std::error::Error>> {
use fragmentcolor::{Renderer, Pass, Shader};
let renderer = Renderer::new();let target = renderer.create_texture_target([64, 64]).await?;
let shader = Shader::default();let mut pass = Pass::new("solid background");pass.add_shader(&shader);
pass.set_clear_color([0.1, 0.2, 0.3, 1.0]);
renderer.render(&pass, &target)?;
3 collapsed lines
Ok(())}fn main() -> Result<(), Box<dyn std::error::Error>> { pollster::block_on(run()) }import { Renderer, Pass, Shader } from "fragmentcolor";
const renderer = new Renderer();const target = await renderer.createTextureTarget([64, 64]);
const shader = Shader.default();const pass = new Pass("solid background");pass.addShader(shader);
pass.setClearColor([0.1, 0.2, 0.3, 1.0]);
renderer.render(pass, target);from fragmentcolor import Renderer, Pass, Shader
renderer = Renderer()target = renderer.create_texture_target([64, 64])
shader = Shader.default()rpass = Pass("solid background")rpass.add_shader(shader)
rpass.set_clear_color([0.1, 0.2, 0.3, 1.0])
renderer.render(rpass, target)import FragmentColor
let renderer = Renderer()let target = try await renderer.createTextureTarget([64, 64])
let shader = Shader.default()let pass = Pass("solid background")pass.addShader(shader)
try pass.setClearColor([0.1, 0.2, 0.3, 1.0])
try renderer.render(pass, target)import org.fragmentcolor.*
val renderer = Renderer()val target = renderer.createTextureTarget(64u, 64u)
val shader = Shader.default()val pass = Pass("solid background")pass.addShader(shader)
pass.setClearColor(listOf(0.1f, 0.2f, 0.3f, 1.0f))
renderer.render(pass, target)Pass::set_compute_dispatch
Section titled “Pass::set_compute_dispatch”Set the workgroup-grid size for a compute pass. The three numbers are the
number of workgroups to dispatch in each dimension; total invocations are
x * y * z * workgroup_size_x * workgroup_size_y * workgroup_size_z,
where the per-workgroup size comes from the WGSL @workgroup_size
attribute. Has no effect on render passes.
Example
Section titled “Example”use fragmentcolor::{Pass, Shader};let cs = Shader::new("@compute @workgroup_size(8,8,1) fn cs_main() {}").unwrap();let pass = Pass::from_shader("compute", &cs);pass.set_compute_dispatch(64, 64, 1);import { Pass, Shader } from "fragmentcolor";const cs = new Shader("@compute @workgroup_size(8,8,1) fn cs_main() {}").unwrap();const pass = new Pass("compute"); pass.addShader(cs);pass.setComputeDispatch(64, 64, 1);from fragmentcolor import Pass, Shadercs = Shader("@compute @workgroup_size(8,8,1) fn cs_main() {}")rpass = Pass("compute"); rpass.add_shader(cs)rpass.set_compute_dispatch(64, 64, 1)import FragmentColorlet cs = try! Shader("@compute @workgroup_size(8,8,1) fn cs_main() {}")let pass = Pass("compute"); pass.addShader(cs)pass.setComputeDispatch(64, 64, 1)import org.fragmentcolor.*val cs = Shader("@compute @workgroup_size(8,8,1) fn cs_main() {}")val pass = Pass("compute"); pass.addShader(cs)pass.setComputeDispatch(64u,64u,1u)Pass::add_target(target)
Section titled “Pass::add_target(target)”Attach a per-pass color render target. When set, this pass renders into the provided texture instead of the final Target.
Use this to render intermediate results (e.g., a shadow map) that later passes can sample.
Example
Section titled “Example”1 collapsed line
async fn run() -> Result<(), Box<dyn std::error::Error>> {use fragmentcolor::{Renderer, Pass, TextureFormat};
let r = Renderer::new();let tex_target = r.create_texture_target([512, 512]).await?;
let p = Pass::new("shadow");p.add_target(&tex_target);
3 collapsed lines
Ok(())}fn main() -> Result<(), Box<dyn std::error::Error>> { pollster::block_on(run()) }import { Renderer, Pass, TextureFormat } from "fragmentcolor";
const r = new Renderer();const tex_target = await r.createTextureTarget([512, 512]);
const p = new Pass("shadow");p.addTarget(tex_target);from fragmentcolor import Renderer, Pass, TextureFormat
r = Renderer()tex_target = r.create_texture_target([512, 512])
p = Pass("shadow")p.add_target(tex_target)import FragmentColor
let r = Renderer()let tex_target = try await r.createTextureTarget([512, 512])
let p = Pass("shadow")try p.addTarget(tex_target)import org.fragmentcolor.*
val r = Renderer()val tex_target = r.createTextureTarget(512u, 512u)
val p = Pass("shadow")p.addTarget(tex_target)Pass::add_depth_target
Section titled “Pass::add_depth_target”Select a depth attachment for this pass.
The target must be a stable texture created by the same Renderer with create_depth_texture().
When a depth target is attached, the renderer will create a render pipeline with a depth-stencil
matching the texture format (e.g., Depth32Float) of the created texture.
Example
Section titled “Example”1 collapsed line
async fn run() -> Result<(), Box<dyn std::error::Error>> {use fragmentcolor::{Renderer, Pass, Shader, Mesh};
let renderer = Renderer::new();let target = renderer.create_texture_target([64, 64]).await?;
// Create a depth texture usable as a per-pass attachmentlet depth = renderer.create_depth_texture([64, 64]).await?;
let mut mesh = Mesh::new();mesh.add_vertex([0.0, 0.0, 0.0]);mesh.add_vertex([1.0, 0.0, 0.0]);mesh.add_vertex([0.0, 1.0, 0.0]);mesh.add_vertex([1.0, 1.0, 0.0]);let shader = Shader::from_mesh(&mesh);let pass = Pass::from_shader("scene", &shader);
// Attach depth texture to enable depth testing.// Pipeline will include a matching depth-stencil statepass.add_depth_target(&depth)?;
// Render as usualrenderer.render(&pass, &target)?;3 collapsed lines
Ok(())}fn main() -> Result<(), Box<dyn std::error::Error>> { pollster::block_on(run()) }import { Renderer, Pass, Shader, Mesh } from "fragmentcolor";
const renderer = new Renderer();const target = await renderer.createTextureTarget([64, 64]);
// Create a depth texture usable as a per-pass attachmentconst depth = await renderer.createDepthTexture([64, 64]);
const mesh = new Mesh();mesh.addVertex([0.0, 0.0, 0.0]);mesh.addVertex([1.0, 0.0, 0.0]);mesh.addVertex([0.0, 1.0, 0.0]);mesh.addVertex([1.0, 1.0, 0.0]);const shader = Shader.fromMesh(mesh);const pass = new Pass("scene"); pass.addShader(shader);
// Attach depth texture to enable depth testing.// Pipeline will include a matching depth-stencil statepass.addDepthTarget(depth);
// Render as usualrenderer.render(pass, target);from fragmentcolor import Renderer, Pass, Shader, Mesh
renderer = Renderer()target = renderer.create_texture_target([64, 64])
# Create a depth texture usable as a per-pass attachmentdepth = renderer.create_depth_texture([64, 64])
mesh = Mesh()mesh.add_vertex([0.0, 0.0, 0.0])mesh.add_vertex([1.0, 0.0, 0.0])mesh.add_vertex([0.0, 1.0, 0.0])mesh.add_vertex([1.0, 1.0, 0.0])shader = Shader.from_mesh(mesh)rpass = Pass("scene"); rpass.add_shader(shader)
# Attach depth texture to enable depth testing.# Pipeline will include a matching depth-stencil staterpass.add_depth_target(depth)
# Render as usualrenderer.render(rpass, target)import FragmentColor
let renderer = Renderer()let target = try await renderer.createTextureTarget([64, 64])
// Create a depth texture usable as a per-pass attachmentlet depth = try await renderer.createDepthTexture([64, 64])
let mesh = Mesh()try mesh.addVertex([0.0, 0.0, 0.0])try mesh.addVertex([1.0, 0.0, 0.0])try mesh.addVertex([0.0, 1.0, 0.0])try mesh.addVertex([1.0, 1.0, 0.0])let shader = Shader.fromMesh(mesh)let pass = Pass("scene"); pass.addShader(shader)
// Attach depth texture to enable depth testing.// Pipeline will include a matching depth-stencil statetry pass.addDepthTarget(depth)
// Render as usualtry renderer.render(pass, target)import org.fragmentcolor.*
val renderer = Renderer()val target = renderer.createTextureTarget(64u, 64u)
// Create a depth texture usable as a per-pass attachmentval depth = renderer.createDepthTexture(64u, 64u)
val mesh = Mesh()mesh.addVertex(Vertex(listOf(0.0f, 0.0f, 0.0f)))mesh.addVertex(Vertex(listOf(1.0f, 0.0f, 0.0f)))mesh.addVertex(Vertex(listOf(0.0f, 1.0f, 0.0f)))mesh.addVertex(Vertex(listOf(1.0f, 1.0f, 0.0f)))val shader = Shader.fromMesh(mesh)val pass = Pass("scene"); pass.addShader(shader)
// Attach depth texture to enable depth testing.// Pipeline will include a matching depth-stencil statepass.addDepthTarget(depth)
// Render as usualrenderer.render(pass, target)Pass::is_compute
Section titled “Pass::is_compute”Returns true if this Pass is a compute pass (has only compute shaders).
Example
Section titled “Example”1 collapsed line
fn main() -> Result<(), Box<dyn std::error::Error>> {use fragmentcolor::{Shader, Pass};
let shader = Shader::new(r#"@compute @workgroup_size(1)fn cs_main() { }"#)?;let pass = Pass::from_shader("p", &shader);
// Call the methodlet is_compute = pass.is_compute();
4 collapsed lines
_ = is_compute;assert!(pass.is_compute());Ok(())}import { Shader, Pass } from "fragmentcolor";
const shader = new Shader(`
@compute @workgroup_size(1)fn cs_main() { }
`);const pass = new Pass("p"); pass.addShader(shader);
// Call the methodconst is_compute = pass.isCompute();from fragmentcolor import Shader, Pass
shader = Shader("""@compute @workgroup_size(1)fn cs_main() { }
""")rpass = Pass("p"); rpass.add_shader(shader)
# Call the methodis_compute = rpass.is_compute()import FragmentColor
let shader = try Shader("""@compute @workgroup_size(1)fn cs_main() { }
""")let pass = Pass("p"); pass.addShader(shader)
// Call the methodlet is_compute = pass.isCompute()import org.fragmentcolor.*
val shader = Shader("""@compute @workgroup_size(1)fn cs_main() { }
""")val pass = Pass("p"); pass.addShader(shader)
// Call the methodval is_compute = pass.isCompute()Pass::require(deps)
Section titled “Pass::require(deps)”Declare that this pass depends on one or more other renderables (Pass, Shader, Mesh). All dependencies will render before this Pass.
Return value
Section titled “Return value”- Ok(()) on success
- Err(PassError::SelfDependency) if a pass requires itself
- Err(PassError::DuplicateDependency(name)) if the dependency is already present
- Err(PassError::DependencyCycle { via }) if adding the dependency would create a cycle
Description
Section titled “Description”require establishes a dependency: the given dependencies must render before self.
This allows you to build DAG render graphs directly from passes. The graph is validated at build time and does not perform cycle checks at render time.
- Dependencies are stored in insertion order.
- Traversal is dependencies-first, then the current pass, with deduplication.
- Creation order of passes does not matter.
Example
Section titled “Example”1 collapsed line
async fn run() -> Result<(), Box<dyn std::error::Error>> {use fragmentcolor::{Pass, Renderer};let renderer = Renderer::new();let target = renderer.create_texture_target([100,100]).await?;let color = Pass::new("color");let blurx = Pass::new("blur_x");blurx.require(&color)?; // color before blur_xlet blury = Pass::new("blur_y");blury.require(&blurx)?; // blur_x before blur_ylet compose = Pass::new("compose");compose.require(&color)?;compose.require(&blury)?; // fan-in; color and blur_y before composerenderer.render(&compose, &target)?; // compose renders last3 collapsed lines
Ok(())}fn main() -> Result<(), Box<dyn std::error::Error>> { pollster::block_on(run()) }import { Pass, Renderer } from "fragmentcolor";const renderer = new Renderer();const target = await renderer.createTextureTarget([100,100]);const color = new Pass("color");const blurx = new Pass("blur_x");blurx.require(color); // color before blur_x;const blury = new Pass("blur_y");blury.require(blurx); // blur_x before blur_y;const compose = new Pass("compose");compose.require(color);compose.require(blury); // fan-in; color and blur_y before compose;renderer.render(compose, target); // compose renders last;from fragmentcolor import Pass, Rendererrenderer = Renderer()target = renderer.create_texture_target([100,100])color = Pass("color")blurx = Pass("blur_x")blurx.require(color); # color before blur_xblury = Pass("blur_y")blury.require(blurx); # blur_x before blur_ycompose = Pass("compose")compose.require(color)compose.require(blury); # fan-in; color and blur_y before composerenderer.render(compose, target); # compose renders lastimport FragmentColorlet renderer = Renderer()let target = try await renderer.createTextureTarget([100,100])let color = Pass("color")let blurx = Pass("blur_x")try blurx.require(color); // color before blur_xlet blury = Pass("blur_y")try blury.require(blurx); // blur_x before blur_ylet compose = Pass("compose")try compose.require(color)try compose.require(blury); // fan-in; color and blur_y before composetry renderer.render(compose, target); // compose renders lastimport org.fragmentcolor.*val renderer = Renderer()val target = renderer.createTextureTarget(100u, 100u)val color = Pass("color")val blurx = Pass("blur_x")blurx.require(color); // color before blur_xval blury = Pass("blur_y")blury.require(blurx); // blur_x before blur_yval compose = Pass("compose")compose.require(color)compose.require(blury); // fan-in; color and blur_y before composerenderer.render(compose, target); // compose renders last