Research-Stack/5-Applications/scripts/ascii_dof_pipeline.md
2026-05-11 22:18:31 -05:00

1.5 KiB

ASCII DoF WebGPU Q16.16 Pipeline

This is the concrete WebGPU adaptation surface for an ASCII depth-of-field pass. The compute pass writes one packed u32 per ASCII cell and the render pass treats the active buffer as a glyph lookup table.

Cell Word

ascii_dof_pack_q16.wgsl emits:

Bits Field Mask
31..19 depth13 0x1fff
18..12 luma7 0x7f
11..6 char6 0x3f
5..2 flags4 0xf
1..0 reserved 0x3

The render-side character decode is:

let char_index = (packed >> 6u) & 0x3Fu;

Buffer Rotation

Use four GPUBuffers with GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC. For frame n:

  • write buffer: n & 3
  • display/read buffer: (n + 3) & 3
  • queued buffers: (n + 2) & 3, (n + 1) & 3

The helper in ascii_dof_quad_buffer.ts keeps that rotation explicit and writes the uniform block expected by the compute shader.

Q16.16 Boundary

Depth enters as a normalized depth texture sample, then becomes unsigned Q16.16:

let depth_q16 = u32(clamp(depth_f, 0.0, 1.0) * 65536.0 + 0.5);

Focus, aperture, and CoC scale are passed as Q16.16 uniforms. The shader avoids u64 by using a bounded Q16 multiply for non-negative values in [0, 1], which is enough for normalized depth and blur controls.

Render Pass Contract

The render pass should bind the current read buffer as storage or readonly storage, decode char6, and sample an SDF glyph atlas. depth13, luma7, and flags4 are available for tone, opacity, debug overlays, or temporal rejection.