CineCode
How-to Guides

Apply GPU shaders

Add WGSL shader effects and a bloom post-process using the GPU backend.

Goal

Add custom visual effects โ€” backgrounds, region effects, overlays โ€” and a bloom glow, rendered on the GPU.

Shaders and bloom require the GPU backend. Always render these with --gpu.

Step 1 โ€” Write a WGSL shader

A CineCode shader implements one function:

shaders/aurora.wgsl
fn shade(uv: vec2<f32>, local: vec2<f32>, frag: vec2<f32>) -> vec4<f32> {
    let t = u.time;
    let wave = sin(uv.x * 8.0 + t) * 0.5 + 0.5;
    let g = mix(0.05, 0.6, wave * uv.y);
    return vec4<f32>(0.04, g, 0.5 * g + 0.1, 1.0);
}

The full uniform/binding contract (resolution, time, progress, rect, params, the src texture, and samp sampler) is in Shaders reference.

Step 2 โ€” Declare it in the manifest

codescene.toml
[shaders]
aurora = "shaders/aurora.wgsl"
glitch = "shaders/glitch.wgsl"
scanlines = "shaders/scanlines.wgsl"

Step 3 โ€” Apply it in a scene

There are several application points, composited in this order: background โ†’ CPU content โ†’ region/overlay shaders โ†’ bloom.

// Full-frame animated background, behind everything
s.background_shader("aurora");

// A shader applied to a rectangular region (samples the content under it)
s.shader("glitch", 700, 160, 420, 300).params(0.8, 0.2, 0.0, 0.0);

// A full-frame overlay on top of all content
s.overlay_shader("scanlines");

Use shader_fill to fill a region with a shader that ignores the content beneath it, and .params(a, b, c, d) to pass up to four floats into your WGSL.

Step 4 โ€” Render with bloom

cinecode render my-video -o effects.mp4 --gpu --bloom 0.8

--bloom <n> adds a bright-pass glow as the final compositing step.

GPU render: background, region, and overlay shaders plus bloom.
Files that made this video

The GPU effects scene: a scene script, one Rust source file, and three WGSL shaders registered in the manifest.

codescene.toml
Project manifest: output size, theme, scene order, transitions, and shader names.
Open full file
scenes = ["scenes/intro.ccs", "scenes/terrain.ccs", "scenes/pathfind.ccs", "scenes/particles.ccs", "scenes/graph.ccs", "scenes/life.ccs", "scenes/boids.ccs", "scenes/tweens.ccs", "scenes/inserts.ccs", "scenes/edit.ccs", "scenes/edit_source.ccs", "scenes/editor_theme.ccs", "scenes/font_set.ccs", "scenes/remove_styles.ccs", "scenes/morph.ccs", "scenes/shapes.ccs", "scenes/effects.ccs"]
theme = "dark_documentary"

[episode]
title = "How Rivers Form"

[output]
fps = 30
width = 1280
height = 720

[shaders]
aurora = "shaders/aurora.wgsl"
glitch = "shaders/glitch.wgsl"
scanlines = "shaders/scanlines.wgsl"

[transition]
kind = "crossfade"
frames = 18

Expand Files that made this video under the clip to see all the moving parts together: codescene.toml registers the shader names, scenes/effects.ccs places them in the frame, and the .wgsl files define the pixels.

CPU vs GPU effects

Some effects also exist on the CPU backend (no flag needed). Compare:

CPU effects showcase.
Files that made this video

The GPU effects scene: a scene script, one Rust source file, and three WGSL shaders registered in the manifest.

codescene.toml
Project manifest: output size, theme, scene order, transitions, and shader names.
Open full file
scenes = ["scenes/intro.ccs", "scenes/terrain.ccs", "scenes/pathfind.ccs", "scenes/particles.ccs", "scenes/graph.ccs", "scenes/life.ccs", "scenes/boids.ccs", "scenes/tweens.ccs", "scenes/inserts.ccs", "scenes/edit.ccs", "scenes/edit_source.ccs", "scenes/editor_theme.ccs", "scenes/font_set.ccs", "scenes/remove_styles.ccs", "scenes/morph.ccs", "scenes/shapes.ccs", "scenes/effects.ccs"]
theme = "dark_documentary"

[episode]
title = "How Rivers Form"

[output]
fps = 30
width = 1280
height = 720

[shaders]
aurora = "shaders/aurora.wgsl"
glitch = "shaders/glitch.wgsl"
scanlines = "shaders/scanlines.wgsl"

[transition]
kind = "crossfade"
frames = 18
GPU shaders + bloom.
Files that made this video

The GPU effects scene: a scene script, one Rust source file, and three WGSL shaders registered in the manifest.

codescene.toml
Project manifest: output size, theme, scene order, transitions, and shader names.
Open full file
scenes = ["scenes/intro.ccs", "scenes/terrain.ccs", "scenes/pathfind.ccs", "scenes/particles.ccs", "scenes/graph.ccs", "scenes/life.ccs", "scenes/boids.ccs", "scenes/tweens.ccs", "scenes/inserts.ccs", "scenes/edit.ccs", "scenes/edit_source.ccs", "scenes/editor_theme.ccs", "scenes/font_set.ccs", "scenes/remove_styles.ccs", "scenes/morph.ccs", "scenes/shapes.ccs", "scenes/effects.ccs"]
theme = "dark_documentary"

[episode]
title = "How Rivers Form"

[output]
fps = 30
width = 1280
height = 720

[shaders]
aurora = "shaders/aurora.wgsl"
glitch = "shaders/glitch.wgsl"
scanlines = "shaders/scanlines.wgsl"

[transition]
kind = "crossfade"
frames = 18

Reference

The WGSL contract, every uniform, and every binding are in Shaders reference.

On this page