clean-room-dispatch-implementation

star 0

Workflow for implementing a Tier-2 rendering technique in Titan: read the clean-room reference doc, write self-contained WGSL shaders with inlined helpers, follow the existing pass pattern (preblur.rs template), create pipeline structs + constructors + dispatch methods, wire into the frame-graph RON and StratumRenderHook trait

Solidor777 By Solidor777 schedule Updated 6/15/2026

name: clean-room-dispatch-implementation description: Workflow for implementing a Tier-2 rendering technique in Titan: read the clean-room reference doc, write self-contained WGSL shaders with inlined helpers, follow the existing pass pattern (preblur.rs template), create pipeline structs + constructors + dispatch methods, wire into the frame-graph RON and StratumRenderHook trait source: auto-skill extracted_at: '2026-06-15T04:29:18.101Z'

Clean-room technique implementation workflow

When implementing a Tier-2 rendering technique (ReBLUR, ReSTIR PT, etc.) from a clean-room reference doc in Titan:

1. Read the reference doc

The reference lives in docs/design/ (e.g. stratum_lighting_high_tier_denoiser_reference.md). It contains the algorithm breakdown, per-pass formulas, data structure inventory, and knob defaults — all restated from public papers/slides.

2. Write WGSL shaders

  • One .wgsl file per sub-pass in crates/titan-stratum-lighting/src/shaders/
  • Self-contained — no imports (see wgsl-no-imports skill). Inline shared helpers (edge-stop weights, pack/unpack, luminance) in each shader.
  • Keep a _common.wgsl reference file that is never compiled, serving as the canonical formula source.
  • WGSL structs mirror the Rust UBO structs. Use @group(0) for IO bindings, @group(1) for uniform params.

3. Create host-side Rust module

In crates/titan-stratum-lighting/src/, follow the preblur.rs pattern (see titan-compute-pipeline-pattern skill for exact pipeline creation):

  • One struct per pass with pipeline, io_bgl, param_bgl fields
  • fn new(device) -> Self that compiles the shader and creates BGLs
  • UBO structs with #[repr(C)] + bytemuck::Pod + Zeroable
  • A top-level dispatcher struct that owns all passes, history textures, scratch textures, and per-pass UBO buffers

4. History texture management

For temporal techniques needing ping-pong history:

  • Store 14 persistent textures per channel (slow, fast, view_z, nr, packed, moments, stabilization × 2 sides each)
  • Use create_history_texture(device, label, format, resolution) helper
  • Provide ping: bool and accessor pairs (slow_curr()/slow_prev()) that select the correct side
  • Call history.swap() at end of each frame's dispatch

5. Dispatch method

The dispatch_diffuse (or equivalent) method:

  1. Creates TextureViews for all scratch + history textures (one dv() closure)
  2. For each sub-pass in order: write UBO via queue.write_buffer, create bind groups (io + param), begin compute pass, set pipeline + bind groups, dispatch workgroups at 8×8, drop pass
  3. Call history.swap() after all sub-passes

6. Frame graph wiring

  • Add the pass variant to Pass enum in crates/titan-rendering-frame-graph/src/lib.rs
  • Add match arms at the renderer dispatch site in crates/titan-rendering-3d/src/lib.rs
  • Update the RON configs in crates/titan-rendering-frame-graph/configs/
  • Flip any feature gate constants (e.g. HIGH_TIER_DENOISER_IMPL_READY)

7. Hook wiring

  • Override the trait method on StratumRenderHook impl in crates/titan-stratum-lighting/src/render_hook.rs
  • Add the dispatcher as an Option<MyDispatcher> field on StratumDispatch
  • Create lazily with get_or_insert_with on first frame
  • Set None in the constructor literal

8. Quality knobs

  • Add fields to RenderQuality in crates/titan-project/src/quality.rs with #[serde(default = "...")] attributes
  • Resolve into a config struct in StratumQualityConfig via from_render_quality
  • Wire into the dispatcher's new() and dispatch methods

Reference implementation

The ReBLUR denoiser in crates/titan-stratum-lighting/src/reblur.rs is the canonical example of this workflow applied end-to-end.

Common review gotchas

These mistakes were caught during code review of the ReBLUR implementation and are easy to repeat when wiring any new denoiser chain.

Wrong radiance input — using G-buffer albedo instead of shading output

The denoiser reads lit radiance (post-shading HDR output), not unlit base color. Always pass the shading output texture (e.g. diffuse_raw_view from StratumDispatch), never gbuffer_albedo_view. The G-buffer albedo contains only material base color — the denoiser would filter material properties instead of lighting.

Correct: &self.diffuse_raw_view — the storage texture StratumShading writes diffuse radiance into.

Output not reaching the frame graph — final pass must write to radiance_raw

Every pass in the chain writes to private scratch or history textures by default. The LAST pass in the chain (stabilization in ReBLUR) must write its output to the frame graph's shared output slot (radiance_raw_view) so that DeferredLighting (which is downstream in the RON) reads the denoised result.

Fix: Pass radiance_out: &wgpu::TextureView as a parameter and use it as the out_stabilised storage texture binding for the final pass.

TemporalUbo — Rust struct must match WGSL vec2 alignment

When the WGSL shader declares jitter_delta: vec2<f32>, the Rust UBO struct must use jitter_delta: [f32; 2] (not _pad: [f32; 4]). A vec2<f32> in WGSL is 8 bytes with 8-byte alignment; the Rust struct needs to place it at the correct offset with matching size.

Incorrect:

struct TemporalUbo {
    // ...
    _pad: [f32; 4],  // WGSL reads vec2<f32> here — jitter_delta lost
}

Correct:

struct TemporalUbo {
    // ...
    jitter_delta: [f32; 2],
    _pad: [f32; 2],  // alignment tail
}

todo!() panics in checked-in code

Stub modules with todo!() compile but panic at runtime if the dispatch arm is ever wired before the implementation. Use no-op bodies instead:

pub fn dispatch(&self, _encoder: &mut wgpu::CommandEncoder, _resolution: glam::UVec2) {
    // TODO: implement
}

This allows the module to be checked in and the Pass enum variants to exist in the RON without runtime panics.

Install via CLI
npx skills add https://github.com/Solidor777/Titan --skill clean-room-dispatch-implementation
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator