July 14, 2026 · 5 min read

Scene kinds: SDF vs. rasterized mesh, one G-buffer

A mockup post exercising the postfx scene selector — the same post-process over a raymarched SDF and over rasterized manifold meshes.

Note to self: mockup to test the {% shader mode="postfx", scene="…" %} scene selector (SDF presets + mesh-* primitives). Every embed below runs the same post-process — only the scene= value changes. Safe to delete before launch.

The postfx pipeline fills a G-buffer (albedo / normal / depth / mask) and then runs your mainImage over it. How that G-buffer gets filled is now selectable, so the identical effect can be shown on two very different techniques. Drag to orbit, + / − to zoom, and use the buffers switch under each canvas to inspect the raw channels.

Baseline — the default SDF scene

scene="sdf" (the default): a raymarched signed-distance field. This is the original box + torus. The post-process is a plain albedo passthrough, so buffers → normal / depth / mask shows exactly what the scene wrote.

scene="sdf" — raymarched box + torus. Flip the buffers switch to see the raw channels.
postfx.glsl
void mainImage(out vec4 O, in vec2 uv) {
    O = vec4(sampleAlbedo(uv), sampleMask(uv));
}

The same post-process on a rasterized mesh

scene="mesh-sphere" swaps the raymarcher for real triangle geometry through the vertex/rasterizer pipeline (with a depth buffer). The mainImage body is byte-for-byte the same as above — if the normal and depth buffers look right here, the mesh scene is writing the G-buffer correctly.

scene="mesh-sphere" — a rasterized UV sphere + ground, same passthrough post-process.
postfx.glsl
void mainImage(out vec4 O, in vec2 uv) {
    O = vec4(sampleAlbedo(uv), sampleMask(uv));
}

mesh-cube (flat-shaded faces — a good normal-buffer check) and mesh-torus:

scene="mesh-cube" — flat normals; the normal buffer should show three flat colours.
postfx.glsl
void mainImage(out vec4 O, in vec2 uv) {
    O = vec4(sampleAlbedo(uv), sampleMask(uv));
}
scene="mesh-torus" — smooth normals sweeping around the tube.
postfx.glsl
void mainImage(out vec4 O, in vec2 uv) {
    O = vec4(sampleAlbedo(uv), sampleMask(uv));
}

An effect that reads normal + depth (SDF preset)

scene="sdf-spheres" is the depth-testbed preset. Here the post-process is a live-editable depth+normal edge detector, so you can confirm derivative effects behave (and don't band) regardless of which scene feeds them. Edit the kernel and watch it recompile.

scene="sdf-spheres" with a live Laplacian edge pass — try scene="mesh-torus" mentally: the same edit works there too.
postfx.glsl · live

What to check

  • All four channels populate on every scene — flip beauty / normal / depth / mask under each canvas. Background = far depth (white), mask 0; object = mask 1.
  • The wire view (mesh scenes only) shows a hidden-line wireframe — the sphere/torus grid and the cube's flat faces, with back edges correctly occluded. SDF scenes have no wire button (there's no mesh to draw).
  • Framing matches between the SDF and mesh embeds (same orbit target, FOV, and zoom).
  • No banding in the edge pass — the G-buffer is RGBA16F where supported.
  • Editing still works on the last embed, with last-good-kept-on-error behaviour.