---
title: Pass
description: "The [Pass](/api/core/pass) object is a collection of [Shader](/api/core/shader) objects that are rendered to a [Target](/api/core/target) by the [Renderer](/api/core/renderer)."
category: core
categoryLabel: Core
---

import { Code, Tabs, TabItem, Aside } from "@astrojs/starlight/components";

## Description

The [Pass](/api/core/pass) object is a collection of [Shader](/api/core/shader) objects that are rendered to a [Target](/api/core/target) by the [Renderer](/api/core/renderer).

While the [Shader](/api/core/shader) represents a single **Render Pipeline** or a **Compute Pipeline**,
the [Pass](/api/core/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](/api/core/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](/api/core/pass)::compute().

After creation, it will only accept a compatible [Shader](/api/core/shader) object. If you try to add a Compute [Shader](/api/core/shader) to a Render [Pass](/api/core/pass) or vice-versa,
it won't add the shader to its internal list and log a warning message in the console.



## Example

<Tabs>

<TabItem label="Rust">
<Code
code={`
async fn run() -> Result<(), Box<dyn std::error::Error>> {

use fragmentcolor::{ Shader, Pass, Renderer, Frame };

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);

// standalone
renderer.render(&pass, &target)?;

// using a Frame
let mut frame = Frame::new();
frame.add_pass(&pass);
frame.add_pass(&pass2);
renderer.render(&frame, &target)?;

// vector of passes (consume them)
renderer.render(&vec![pass, pass2], &target)?;

Ok(())
}
fn main() -> Result<(), Box<dyn std::error::Error>> { pollster::block_on(run()) }
`}
lang="rust" meta="collapse={1-1, 28-30}"
/>

</TabItem>

<TabItem label="JavaScript">
<Code
code={`

import { Shader, Pass, Renderer, Frame } 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);

// standalone
renderer.render(pass, target);

// using a Frame
const frame = new Frame();
frame.addPass(pass);
frame.addPass(pass2);
renderer.render(frame, target);

// vector of passes (consume them)
renderer.render([pass, pass2], target);

`}
lang="js"
/>

</TabItem>

<TabItem label="Python">
<Code
code={`
from rendercanvas.auto import RenderCanvas, loop

from fragmentcolor import Shader, Pass, Renderer, Frame

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)

# standalone
renderer.render(rpass, target)

# using a Frame
frame = Frame()
frame.add_pass(rpass)
frame.add_pass(pass2)
renderer.render(frame, target)

# vector of passes (consume them)
renderer.render([rpass, pass2], target)

`}
lang="python"
/>

</TabItem>

<TabItem label="Swift">
<Aside type="caution" title="Work in progress">Swift bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Swift placeholder â bindings WIP

`}
lang="text"
/>

</TabItem>

<TabItem label="Kotlin">
<Aside type="caution" title="Work in progress">Kotlin/Android bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Kotlin placeholder â bindings WIP

`}
lang="text"
/>

</TabItem>

</Tabs>


## Methods


---

### Pass::new(name: &str) -&gt; Self

#### Creates a new Pass

The name property is optional and is used for debugging purposes.

#### Example

<Tabs>

<TabItem label="Rust">
<Code
code={`
use fragmentcolor::Pass;

let pass = Pass::new("first pass");

_ = pass;
`}
lang="rust" meta="collapse={5-5}"
/>

</TabItem>

<TabItem label="JavaScript">
<Code
code={`
import { Pass } from "fragmentcolor";

const pass = new Pass("first pass");

`}
lang="js"
/>

</TabItem>

<TabItem label="Python">
<Code
code={`
from fragmentcolor import Pass

rpass = Pass("first rpass")

`}
lang="python"
/>

</TabItem>

<TabItem label="Swift">
<Aside type="caution" title="Work in progress">Swift bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Swift placeholder â bindings WIP

`}
lang="text"
/>

</TabItem>

<TabItem label="Kotlin">
<Aside type="caution" title="Work in progress">Kotlin/Android bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Kotlin placeholder â bindings WIP

`}
lang="text"
/>

</TabItem>

</Tabs>


---

### Pass::compute(name: &str) -&gt; Pass

Creates a new [Pass](/api/core/pass) configured for compute workloads.

Only [Shader](/api/core/shader) objects that compile to compute pipelines can be added.

#### Example

<Tabs>

<TabItem label="Rust">
<Code
code={`
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);
`}
lang="rust"
/>

</TabItem>

<TabItem label="JavaScript">
<Code
code={`
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);
`}
lang="js"
/>

</TabItem>

<TabItem label="Python">
<Code
code={`
from fragmentcolor import Pass, Shader

cs = Shader("@compute @workgroup_size(8,8,1) fn cs_main() {}")
rpass = Pass("compute"); rpass.add_shader(cs)
`}
lang="python"
/>

</TabItem>

<TabItem label="Swift">
<Aside type="caution" title="Work in progress">Swift bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Swift placeholder â bindings WIP

`}
lang="text"
/>

</TabItem>

<TabItem label="Kotlin">
<Aside type="caution" title="Work in progress">Kotlin/Android bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Kotlin placeholder â bindings WIP

`}
lang="text"
/>

</TabItem>

</Tabs>


---

### Pass::from_shader(name: &str, shader: Shader) -&gt; Pass

Creates a new [Pass](/api/core/pass) from a single [Shader](/api/core/shader).

The created [Pass](/api/core/pass) inherits the render/compute type from the provided [Shader](/api/core/shader).

#### Example

<Tabs>

<TabItem label="Rust">
<Code
code={`
use fragmentcolor::{Pass, Shader};

let shader = Shader::default();
let pass = Pass::from_shader("single", &shader);
`}
lang="rust"
/>

</TabItem>

<TabItem label="JavaScript">
<Code
code={`
import { Pass, Shader } from "fragmentcolor";

const shader = Shader.default();
const pass = new Pass("single"); pass.addShader(shader);
`}
lang="js"
/>

</TabItem>

<TabItem label="Python">
<Code
code={`
from fragmentcolor import Pass, Shader

shader = Shader.default()
rpass = Pass("single"); rpass.add_shader(shader)
`}
lang="python"
/>

</TabItem>

<TabItem label="Swift">
<Aside type="caution" title="Work in progress">Swift bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Swift placeholder â bindings WIP

`}
lang="text"
/>

</TabItem>

<TabItem label="Kotlin">
<Aside type="caution" title="Work in progress">Kotlin/Android bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Kotlin placeholder â bindings WIP

`}
lang="text"
/>

</TabItem>

</Tabs>


---

### Pass::load_previous()

Configures this [Pass](/api/core/pass) to load the previous contents of the [Target](/api/core/target) instead of clearing it.

This is useful when layering multiple passes where the next pass should blend with the prior results.

#### Example

<Tabs>

<TabItem label="Rust">
<Code
code={`
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)?;

Ok(())
}
fn main() -> Result<(), Box<dyn std::error::Error>> { pollster::block_on(run()) }
`}
lang="rust" meta="collapse={1-1, 15-17}"
/>

</TabItem>

<TabItem label="JavaScript">
<Code
code={`

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);

`}
lang="js"
/>

</TabItem>

<TabItem label="Python">
<Code
code={`

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)

`}
lang="python"
/>

</TabItem>

<TabItem label="Swift">
<Aside type="caution" title="Work in progress">Swift bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Swift placeholder â bindings WIP

`}
lang="text"
/>

</TabItem>

<TabItem label="Kotlin">
<Aside type="caution" title="Work in progress">Kotlin/Android bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Kotlin placeholder â bindings WIP

`}
lang="text"
/>

</TabItem>

</Tabs>


---

### Pass::get_input() -&gt; PassInput

Returns a copy of the current input configuration for this [Pass](/api/core/pass).

It includes the clear/load behavior and clear color.

#### Example

<Tabs>

<TabItem label="Rust">
<Code
code={`
use fragmentcolor::Pass;

let pass = Pass::new("example");
let input = pass.get_input();

_ = input; // Silence unused variable warning
`}
lang="rust" meta="collapse={6-6}"
/>

</TabItem>

<TabItem label="JavaScript">
<Code
code={`
import { Pass } from "fragmentcolor";

const pass = new Pass("example");
const input = pass.getInput();

`}
lang="js"
/>

</TabItem>

<TabItem label="Python">
<Code
code={`
from fragmentcolor import Pass

rpass = Pass("example")
input = rpass.get_input()

`}
lang="python"
/>

</TabItem>

<TabItem label="Swift">
<Aside type="caution" title="Work in progress">Swift bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Swift placeholder â bindings WIP

`}
lang="text"
/>

</TabItem>

<TabItem label="Kotlin">
<Aside type="caution" title="Work in progress">Kotlin/Android bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Kotlin placeholder â bindings WIP

`}
lang="text"
/>

</TabItem>

</Tabs>


---

### Pass::add_shader(shader: Shader)

Adds a [Shader](/api/core/shader) object to the [Pass](/api/core/pass).

#### Example

<Tabs>

<TabItem label="Rust">
<Code
code={`
use fragmentcolor::{Pass, Shader};

let shader = Shader::default();
let pass = Pass::new("p");
pass.add_shader(&shader);
`}
lang="rust"
/>

</TabItem>

<TabItem label="JavaScript">
<Code
code={`
import { Pass, Shader } from "fragmentcolor";

const shader = Shader.default();
const pass = new Pass("p");
pass.addShader(shader);
`}
lang="js"
/>

</TabItem>

<TabItem label="Python">
<Code
code={`
from fragmentcolor import Pass, Shader

shader = Shader.default()
rpass = Pass("p")
rpass.add_shader(shader)
`}
lang="python"
/>

</TabItem>

<TabItem label="Swift">
<Aside type="caution" title="Work in progress">Swift bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Swift placeholder â bindings WIP

`}
lang="text"
/>

</TabItem>

<TabItem label="Kotlin">
<Aside type="caution" title="Work in progress">Kotlin/Android bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Kotlin placeholder â bindings WIP

`}
lang="text"
/>

</TabItem>

</Tabs>


---

### 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

<Tabs>

<TabItem label="Rust">
<Code
code={`
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> };
  @vertex
  fn vs_main(@location(0) pos: vec2<f32>) -> VOut {
    var out: VOut;
    out.pos = vec4<f32>(pos, 0.0, 1.0);
    return out;
  }
  @fragment
  fn 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)?;

Ok(())
}
`}
lang="rust" meta="collapse={1-1, 23-24}"
/>

</TabItem>

<TabItem label="JavaScript">
<Code
code={`
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> };
  @vertex
  fn vs_main(@location(0) pos: vec2<f32>) -> VOut {
    var out: VOut;
    out.pos = vec4<f32>(pos, 0.0, 1.0);
    return out;
  }
  @fragment
  fn 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);

`}
lang="js"
/>

</TabItem>

<TabItem label="Python">
<Code
code={`
from fragmentcolor import Pass, Shader, Mesh

mesh = Mesh()
mesh.add_vertex([0.0, 0.0])

shader = Shader("""
  struct VOut { @builtin(position) pos: vec4<f32> };
  @vertex
  fn vs_main(@location(0) pos: vec2<f32>) -> VOut {
    var out: VOut;
    out.pos = vec4<f32>(pos, 0.0, 1.0);
    return out;
  }
  @fragment
  fn 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)

`}
lang="python"
/>

</TabItem>

<TabItem label="Swift">
<Aside type="caution" title="Work in progress">Swift bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Swift placeholder: bindings WIP

`}
lang="text"
/>

</TabItem>

<TabItem label="Kotlin">
<Aside type="caution" title="Work in progress">Kotlin/Android bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Kotlin placeholder: bindings WIP

`}
lang="text"
/>

</TabItem>

</Tabs>


---

### Pass::add_mesh_to_shader

Attach a Mesh to a specific Shader in this Pass. This forwards to `shader.add_mesh(mesh)` and returns the same Result.

#### Example

<Tabs>

<TabItem label="Rust">
<Code
code={`
fn main() -> Result<(), Box<dyn std::error::Error>> {
use fragmentcolor::{Shader, Mesh, Vertex, Pass};

let mesh = Mesh::new();
mesh.add_vertex(Vertex::new([0.0, 0.0]));
let shader = Shader::new(r#"
  struct VOut { @builtin(position) pos: vec4<f32> };
  @vertex
  fn vs_main(@location(0) pos: vec2<f32>) -> VOut {
    var out: VOut;
    out.pos = vec4<f32>(pos, 0.0, 1.0);
    return out;
  }
  @fragment
  fn 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_to_shader(&mesh, &shader)?;

Ok(())
}
`}
lang="rust" meta="collapse={1-1, 21-22}"
/>

</TabItem>

<TabItem label="JavaScript">
<Code
code={`
import { Shader, Mesh, Vertex, Pass } from "fragmentcolor";

const mesh = new Mesh();
mesh.addVertex(Vertex.new([0.0, 0.0]));
const shader = new Shader(\`
  struct VOut { @builtin(position) pos: vec4<f32> };
  @vertex
  fn vs_main(@location(0) pos: vec2<f32>) -> VOut {
    var out: VOut;
    out.pos = vec4<f32>(pos, 0.0, 1.0);
    return out;
  }
  @fragment
  fn fs_main(_v: VOut) -> @location(0) vec4<f32> { return vec4<f32>(1.,0.,0.,1.); }

\`);

const pass = new Pass("pass"); pass.addShader(shader);
pass.addMeshToShader(mesh, shader);

`}
lang="js"
/>

</TabItem>

<TabItem label="Python">
<Code
code={`
from fragmentcolor import Shader, Mesh, Vertex, Pass

mesh = Mesh()
mesh.add_vertex(Vertex([0.0, 0.0]))
shader = Shader("""
  struct VOut { @builtin(position) pos: vec4<f32> };
  @vertex
  fn vs_main(@location(0) pos: vec2<f32>) -> VOut {
    var out: VOut;
    out.pos = vec4<f32>(pos, 0.0, 1.0);
    return out;
  }
  @fragment
  fn 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_to_shader(mesh, shader)

`}
lang="python"
/>

</TabItem>

<TabItem label="Swift">
<Aside type="caution" title="Work in progress">Swift bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Swift placeholder: bindings WIP

`}
lang="text"
/>

</TabItem>

<TabItem label="Kotlin">
<Aside type="caution" title="Work in progress">Kotlin/Android bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Kotlin placeholder: bindings WIP

`}
lang="text"
/>

</TabItem>

</Tabs>


---

### Pass::set_viewport(viewport: Region)

Sets the viewport region for this [Pass](/api/core/pass).

The viewport restricts drawing to a rectangular area of the [Target](/api/core/target).

#### Example

<Tabs>

<TabItem label="Rust">
<Code
code={`
async fn run() -> Result<(), Box<dyn std::error::Error>> {

use fragmentcolor::{Renderer, Pass, Shader, Region};

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(Region::new((0, 0), (32, 32)));

renderer.render(&pass, &target)?;

Ok(())
}
fn main() -> Result<(), Box<dyn std::error::Error>> { pollster::block_on(run()) }
`}
lang="rust" meta="collapse={1-1, 16-18}"
/>

</TabItem>

<TabItem label="JavaScript">
<Code
code={`

import { Renderer, Pass, Shader, Region } 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);

`}
lang="js"
/>

</TabItem>

<TabItem label="Python">
<Code
code={`

from fragmentcolor import Renderer, Pass, Shader, Region

renderer = Renderer()
target = renderer.create_texture_target([64, 64])

shader = Shader.default()
rpass = Pass("clipped")
rpass.add_shader(shader)

rpass.set_viewport(Region((0, 0), (32, 32)))

renderer.render(rpass, target)

`}
lang="python"
/>

</TabItem>

<TabItem label="Swift">
<Aside type="caution" title="Work in progress">Swift bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Swift placeholder â bindings WIP

`}
lang="text"
/>

</TabItem>

<TabItem label="Kotlin">
<Aside type="caution" title="Work in progress">Kotlin/Android bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Kotlin placeholder â bindings WIP

`}
lang="text"
/>

</TabItem>

</Tabs>


---

### Pass::set_clear_color(color: [f32; 4])

Sets the clear color for this [Pass](/api/core/pass).

When the pass is configured to clear, the render target is cleared to the given RGBA color before drawing.

#### Example

<Tabs>

<TabItem label="Rust">
<Code
code={`
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)?;

Ok(())
}
fn main() -> Result<(), Box<dyn std::error::Error>> { pollster::block_on(run()) }
`}
lang="rust" meta="collapse={1-1, 16-18}"
/>

</TabItem>

<TabItem label="JavaScript">
<Code
code={`

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);

`}
lang="js"
/>

</TabItem>

<TabItem label="Python">
<Code
code={`

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)

`}
lang="python"
/>

</TabItem>

<TabItem label="Swift">
<Aside type="caution" title="Work in progress">Swift bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Swift placeholder â bindings WIP

`}
lang="text"
/>

</TabItem>

<TabItem label="Kotlin">
<Aside type="caution" title="Work in progress">Kotlin/Android bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Kotlin placeholder â bindings WIP

`}
lang="text"
/>

</TabItem>

</Tabs>


---

### Pass::set_compute_dispatch

Set the compute dispatch size for a compute pass.

#### Example

<Tabs>

<TabItem label="Rust">
<Code
code={`
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);
`}
lang="rust"
/>

</TabItem>

<TabItem label="JavaScript">
<Code
code={`
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);
`}
lang="js"
/>

</TabItem>

<TabItem label="Python">
<Code
code={`
from fragmentcolor import Pass, Shader
cs = Shader("@compute @workgroup_size(8,8,1) fn cs_main() {}")
rpass = Pass("compute"); rpass.add_shader(cs)
rpass.set_compute_dispatch(64, 64, 1)
`}
lang="python"
/>

</TabItem>

<TabItem label="Swift">
<Aside type="caution" title="Work in progress">Swift bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Swift placeholder: bindings WIP

`}
lang="text"
/>

</TabItem>

<TabItem label="Kotlin">
<Aside type="caution" title="Work in progress">Kotlin/Android bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Kotlin placeholder: bindings WIP

`}
lang="text"
/>

</TabItem>

</Tabs>


---

### 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

<Tabs>

<TabItem label="Rust">
<Code
code={`
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);

Ok(())
}
fn main() -> Result<(), Box<dyn std::error::Error>> { pollster::block_on(run()) }
`}
lang="rust" meta="collapse={1-1, 10-12}"
/>

</TabItem>

<TabItem label="JavaScript">
<Code
code={`
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);

`}
lang="js"
/>

</TabItem>

<TabItem label="Python">
<Code
code={`
from fragmentcolor import Renderer, Pass, TextureFormat

r = Renderer()
tex_target = r.create_texture_target([512, 512])

p = Pass("shadow")
p.add_target(tex_target)

`}
lang="python"
/>

</TabItem>

<TabItem label="Swift">
<Aside type="caution" title="Work in progress">Swift bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Swift placeholder: bindings WIP

`}
lang="text"
/>

</TabItem>

<TabItem label="Kotlin">
<Aside type="caution" title="Work in progress">Kotlin/Android bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Kotlin placeholder: bindings WIP

`}
lang="text"
/>

</TabItem>

</Tabs>


---

### 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

<Tabs>

<TabItem label="Rust">
<Code
code={`
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 attachment
let 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 state
pass.add_depth_target(&depth)?;

// Render as usual
renderer.render(&pass, &target)?;
Ok(())
}
fn main() -> Result<(), Box<dyn std::error::Error>> { pollster::block_on(run()) }
`}
lang="rust" meta="collapse={1-1, 24-26}"
/>

</TabItem>

<TabItem label="JavaScript">
<Code
code={`
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 attachment
const 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 state
pass.addDepthTarget(depth);

// Render as usual
renderer.render(pass, target);
`}
lang="js"
/>

</TabItem>

<TabItem label="Python">
<Code
code={`
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 attachment
depth = 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 state
rpass.add_depth_target(depth)

# Render as usual
renderer.render(rpass, target)
`}
lang="python"
/>

</TabItem>

<TabItem label="Swift">
<Aside type="caution" title="Work in progress">Swift bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Swift placeholder: bindings WIP

`}
lang="text"
/>

</TabItem>

<TabItem label="Kotlin">
<Aside type="caution" title="Work in progress">Kotlin/Android bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Kotlin placeholder: bindings WIP

`}
lang="text"
/>

</TabItem>

</Tabs>


---

### Pass::is_compute

Returns true if this Pass is a compute pass (has only compute shaders).

#### Example

<Tabs>

<TabItem label="Rust">
<Code
code={`
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 method
let is_compute = pass.is_compute();

_ = is_compute;
assert!(pass.is_compute());
Ok(())
}
`}
lang="rust" meta="collapse={1-1, 13-16}"
/>

</TabItem>

<TabItem label="JavaScript">
<Code
code={`
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 method
const is_compute = pass.isCompute();

`}
lang="js"
/>

</TabItem>

<TabItem label="Python">
<Code
code={`
from fragmentcolor import Shader, Pass

shader = Shader("""
@compute @workgroup_size(1)
fn cs_main() { }

""")
rpass = Pass("p"); rpass.add_shader(shader)

# Call the method
is_compute = rpass.is_compute()

`}
lang="python"
/>

</TabItem>

<TabItem label="Swift">
<Aside type="caution" title="Work in progress">Swift bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Swift placeholder: bindings WIP

`}
lang="text"
/>

</TabItem>

<TabItem label="Kotlin">
<Aside type="caution" title="Work in progress">Kotlin/Android bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Kotlin placeholder: bindings WIP

`}
lang="text"
/>

</TabItem>

</Tabs>


---

### Pass::require(deps)

Declare that this pass depends on one or more other renderables (Pass, Shader, Frame, Mesh).
All dependencies will render before this Pass.

#### 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 &#123; via &#125;) if adding the dependency would create a cycle

#### 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

<Tabs>

<TabItem label="Rust">
<Code
code={`
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_x
let blury = Pass::new("blur_y");
blury.require(&blurx)?; // blur_x before blur_y
let compose = Pass::new("compose");
compose.require(&color)?;
compose.require(&blury)?; // fan-in; color and blur_y before compose
renderer.render(&compose, &target)?; // compose renders last
Ok(())
}
fn main() -> Result<(), Box<dyn std::error::Error>> { pollster::block_on(run()) }
`}
lang="rust" meta="collapse={1-1, 14-16}"
/>

</TabItem>

<TabItem label="JavaScript">
<Code
code={`
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;
`}
lang="js"
/>

</TabItem>

<TabItem label="Python">
<Code
code={`
from fragmentcolor import Pass, Renderer
renderer = Renderer()
target = renderer.create_texture_target([100,100])
color = Pass("color")
blurx = Pass("blur_x")
blurx.require(color); # color before blur_x
blury = Pass("blur_y")
blury.require(blurx); # blur_x before blur_y
compose = Pass("compose")
compose.require(color)
compose.require(blury); # fan-in; color and blur_y before compose
renderer.render(compose, target); # compose renders last
`}
lang="python"
/>

</TabItem>

<TabItem label="Swift">
<Aside type="caution" title="Work in progress">Swift bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Swift placeholder: bindings WIP

`}
lang="text"
/>

</TabItem>

<TabItem label="Kotlin">
<Aside type="caution" title="Work in progress">Kotlin/Android bindings are not yet available; implementation is in the works.</Aside>
<Code
code={`
// Kotlin placeholder: bindings WIP

`}
lang="text"
/>

</TabItem>

</Tabs>
