TextureTarget
Description
Section titled “Description”The TextureTarget is an offscreen Target backed by a GPU texture.
Use it for headless rendering, tests, server-side image generation, or CI.
Example
Section titled “Example”1 collapsed line
async fn run() -> Result<(), Box<dyn std::error::Error>> {
use fragmentcolor::{Renderer, Shader, Target};
let renderer = Renderer::new();let mut target = renderer.create_texture_target([64, 64]).await?;
let shader = Shader::default();renderer.render(&shader, &target)?;
let image = target.get_image().await;
7 collapsed lines
assert_eq!(image.len(), 64 * 64 * 4); // RGBA8target.resize([128, 128]);assert_eq!(target.size().width, 128);assert_eq!(target.size().height, 128);Ok(())}fn main() -> Result<(), Box<dyn std::error::Error>> { pollster::block_on(run()) }import { Renderer, Shader } from "fragmentcolor";
const renderer = new Renderer();const target = await renderer.createTextureTarget([64, 64]);
const shader = Shader.default();renderer.render(shader, target);
const image = await target.getImage();from fragmentcolor import Renderer, Shader
renderer = Renderer()target = renderer.create_texture_target([64, 64])
shader = Shader.default()renderer.render(shader, target)
image = target.get_image()import FragmentColor
let renderer = Renderer()let target = try await renderer.createTextureTarget([64, 64])
let shader = Shader.default()try renderer.render(shader, target)
let image = try await target.getImage()import org.fragmentcolor.*
val renderer = Renderer()val target = renderer.createTextureTarget(64u, 64u)
val shader = Shader.default()renderer.render(shader, target)
val image = target.getImage()Methods
Section titled “Methods”TextureTarget::texture
Section titled “TextureTarget::texture”Return a sampleable Texture
handle that aliases the offscreen render target’s storage. Useful for
multi-pass pipelines: render into the TextureTarget, then bind the
returned Texture as a shader uniform on the next pass to read it back.
The first call registers the underlying texture object with the renderer
and caches the resulting TextureId; subsequent calls return a fresh
Texture handle pointing at the same registered id (no duplicate
registration). The returned handle is Clone; pass it around freely.
Example
Section titled “Example”1 collapsed line
async fn run() -> Result<(), Box<dyn std::error::Error>> {use fragmentcolor::{Renderer, Shader};
let renderer = Renderer::new();let target = renderer.create_texture_target([256, 256]).await?;
// Bind the offscreen target's contents as a uniform on a downstream// post-processing shader.let post = Shader::new(r#" @group(0) @binding(0) var input_image : texture_2d<f32>; @group(0) @binding(1) var input_sampler : sampler;
@vertex fn vs_main(@builtin(vertex_index) i: u32) -> @builtin(position) vec4<f32> { let p = array<vec2<f32>, 3>(vec2f(-1.0,-1.0), vec2f(3.0,-1.0), vec2f(-1.0,3.0)); return vec4<f32>(p[i], 0.0, 1.0); } @fragment fn fs_main(@builtin(position) pos: vec4<f32>) -> @location(0) vec4<f32> { return textureSample(input_image, input_sampler, vec2<f32>(0.5, 0.5)); }"#)?;post.set("input_image", &target.texture())?;3 collapsed lines
Ok(())}fn main() -> Result<(), Box<dyn std::error::Error>> { pollster::block_on(run()) }import { Renderer, Shader } from "fragmentcolor";
const renderer = new Renderer();
// Render some scene into an offscreen target, then read it back as a// texture in a second fullscreen pass.const offscreen = await renderer.createTextureTarget([512, 512]);const output = await renderer.createTextureTarget([512, 512]);
const postShader = new Shader(`struct VOut { @builtin(position) pos: vec4<f32>, @location(0) uv: vec2<f32>,};
@vertexfn vs_main(@builtin(vertex_index) i: u32) -> VOut { var p = array<vec2<f32>, 3>(vec2<f32>(-1., -1.), vec2<f32>(3., -1.), vec2<f32>(-1., 3.)); var uv = array<vec2<f32>, 3>(vec2<f32>(0., 1.), vec2<f32>(2., 1.), vec2<f32>(0., -1.)); var out: VOut; out.pos = vec4<f32>(p[i], 0., 1.); out.uv = uv[i]; return out;}
@group(0) @binding(0) var t: texture_2d<f32>;@group(0) @binding(1) var samp: sampler;
@fragmentfn fs_main(in: VOut) -> @location(0) vec4<f32> { return textureSample(t, samp, in.uv);}`);
// `texture()` hands back the offscreen target's color texture so it can be// bound as a shader uniform on web.const tex = offscreen.texture();await postShader.set("t", tex);renderer.render(postShader, output);from fragmentcolor import Renderer, Shader
renderer = Renderer()target = renderer.create_texture_target([256, 256])
# Bind the offscreen target's contents as a uniform on a downstream# post-processing shader.post = Shader(""" @group(0) @binding(0) var input_image : texture_2d<f32>; @group(0) @binding(1) var input_sampler : sampler;
@vertex fn vs_main(@builtin(vertex_index) i: u32) -> @builtin(position) vec4<f32> { let p = array<vec2<f32>, 3>(vec2f(-1.0,-1.0), vec2f(3.0,-1.0), vec2f(-1.0,3.0)); return vec4<f32>(p[i], 0.0, 1.0); } @fragment fn fs_main(@builtin(position) pos: vec4<f32>) -> @location(0) vec4<f32> { return textureSample(input_image, input_sampler, vec2<f32>(0.5, 0.5)); }
""")post.set("input_image", target.texture())import FragmentColor
let renderer = Renderer()let target = try await renderer.createTextureTarget([256, 256])
// Bind the offscreen target's contents as a uniform on a downstream// post-processing shader.let post = try Shader(""" @group(0) @binding(0) var input_image : texture_2d<f32> @group(0) @binding(1) var input_sampler : sampler
@vertex fn vs_main(@builtin(vertex_index) i: u32) -> @builtin(position) vec4<f32> { let p = array<vec2<f32>, 3>(vec2f(-1.0,-1.0), vec2f(3.0,-1.0), vec2f(-1.0,3.0)) return vec4<f32>(p[i], 0.0, 1.0) } @fragment fn fs_main(@builtin(position) pos: vec4<f32>) -> @location(0) vec4<f32> { return textureSample(input_image, input_sampler, vec2<f32>(0.5, 0.5)) }
""")try post.set("input_image", target.texture())import org.fragmentcolor.*
val renderer = Renderer()val target = renderer.createTextureTarget(256u, 256u)
// Bind the offscreen target's contents as a uniform on a downstream// post-processing shader.val post = Shader(""" @group(0) @binding(0) var input_image : texture_2d<f32> @group(0) @binding(1) var input_sampler : sampler
@vertex fn vs_main(@builtin(vertex_index) i: u32) -> @builtin(position) vec4<f32> { let p = array<vec2<f32>, 3>(vec2f(-1.0,-1.0), vec2f(3.0,-1.0), vec2f(-1.0,3.0)) return vec4<f32>(p[i], 0.0, 1.0) } @fragment fn fs_main(@builtin(position) pos: vec4<f32>) -> @location(0) vec4<f32> { return textureSample(input_image, input_sampler, vec2<f32>(0.5, 0.5)) }
""")post.set("input_image", target.texture())