Showroom · Build notes

How Kōrei was made

Floating stones, a ring gate, a still sea — and not a single 3D model. The whole landscape is one mathematical function, evaluated for every pixel by one WebGL2 fragment shader.

View the site →

What it demonstrates

Raymarched signed distance fields: geometry described as formulas instead of meshes. Each shape answers one question — how far is this point from my surface? — and a ray walked out of the camera can safely jump exactly that far each step. Seven spheres and a torus, blended with a smooth minimum, become stones that melt together and a gate half-standing in the water. Because the scene is math, the three light moods are just different constants fed to the same function.

Techniques, honestly named

Recreate it

Free sample
This site's prompt is one of the showroom's free samples — the same file the premium sites sell for $5. Copy it below, paste it into a capable AI coding tool, and iterate from what comes back.

Recreation prompt · korei.md
# Kōrei (raymarched SDF dreamscape)

Build a single self-contained `index.html`: a contemplative full-screen
dreamscape — floating stones and a half-submerged ring gate over a still
sea — rendered entirely by one WebGL2 fragment shader. No 3D models, no
libraries, no textures: every pixel is computed by raymarching signed
distance fields. Beneath the canvas, a short essay explains the technique
in plain language. Tone: quiet, Japanese-garden minimalism.

## Fonts and palette

Google Fonts: **Shippori Mincho** (500/600) for display, **Inter**
(400/500) for UI and body.

- night `#0c111f`, ink `#e9ecf5`, muted `#9aa3b8`, hairline `#232c42`,
  focus ring `#9db7ff`, hero subtitle `#c3cbdd`

Three light moods as shader uniform sets (RGB floats), eased toward at
0.045 per frame so switching feels like weather, not a toggle:

- **Dawn** — skyTop (.545,.639,.831), horizon (.949,.796,.659), sun
  (1,.863,.722), water (.145,.196,.318), stone (.271,.302,.373), sun
  direction (-.34,.20,.92), no stars.
- **Dusk** — skyTop (.357,.329,.533), horizon (.910,.624,.553), sun
  (1,.616,.463), water (.129,.129,.251), stone (.243,.227,.310), sun
  direction (.42,.12,.90) — the light swings to the other side.
- **Night** — skyTop (.043,.063,.157), horizon (.153,.200,.353), moonlit
  sun (.863,.902,1), water (.047,.071,.149), stone (.137,.165,.239), sun
  direction (-.26,.38,.89), stars ON (hash a `floor(rd*260)` grid,
  `step(0.9975, …)`, brightness faded near the horizon).

## The hero technique (name it honestly on the page)

One WebGL2 program drawn as a single fullscreen triangle — no vertex
buffers; derive the corners from `gl_VertexID`:
`vec2 v = vec2(float(gl_VertexID<<1&2), float(gl_VertexID&2))*2.0-1.0;`
which yields (-1,-1)(3,-1)(-1,3). (The naive ±1 version covers only half
the screen — a classic bug; verify a full-frame render.)

Scene SDF (`map`):
- **Seven floating stones** — spheres placed on a golden-angle spiral
  (`ang = i*2.39996`, radius `1.7+1.7*hash(i)`), radii `0.26+0.30*hash`,
  squashed vertically (`q.y *= 1.22`), each bobbing slowly
  (`y += 0.16*sin(t*0.35 + i*1.7)`), all blended with a **smooth minimum**
  (k = 0.42) so near stones melt together like wet clay.
- **The gate** — a vertical torus at (0, 0.55, 7.2), major radius 2.35,
  tube 0.20, standing half in the sea.

Rendering per pixel:
- **Sphere tracing**: 92 steps desktop / 70 on small screens, hit epsilon
  scaled by distance (`d < 0.0012*s`), far plane 55.
- The **sea is an analytic plane** (y = 0): intersect by division, not
  marching. Ripples only perturb the shading normal (two crossed sine
  waves, amplitude 0.013).
- **Soft shadows**: a second march toward the sun, penumbra from
  `min(res, 9*d/s)`, up to 24 steps.
- **Reflections**: reflect the ray at the water, march again (up to 40
  steps); mix with sky by fresnel (`0.06 + 0.94*(1-cosθ)^5`); add sun
  glitter `pow(dot(refl, sun), 700)` gated by the shadow term.
- Normals by central differences (tetrahedron trick, e = 0.0015).
- Stone shading: diffuse×shadow, ambient from `0.5+0.5*n.y`, rim
  `(1-dot(n,-rd))^3`, Blinn-Phong speck (pow 48), sky-tint fill; distance
  fog `1-exp(-0.0022*t²)` toward the sky color.
- Finish: filmic-ish tonemap `col/(1+col)`, gamma 1/2.2, gentle vignette,
  ±0.007 hash film grain.

Camera: origin sways `0.42*sin(t*0.06)` at height 1.18, z −4.4; the
look-at target follows the pointer softly (±0.55 x, ±0.28 y) — parallax,
not control.

## Performance ladder (build all four rungs)

1. Full loop on real GPUs, `devicePixelRatio` capped at 1.5 (1.4 on small
   screens), rAF only, loop paused on `visibilitychange`.
2. Detect software rasterizers via `WEBGL_debug_renderer_info` (match
   /swiftshader|llvmpipe|softpipe|software/i) → render **one still frame**
   at half resolution with reduced step counts instead of looping.
3. `prefers-reduced-motion: reduce` → same still-frame mode; re-render
   once on mood change and resize (time frozen at t = 12).
4. No WebGL2 at all → remove the canvas, show a dignified text fallback
   panel. Also handle `webglcontextlost`/`restored`: pause, rebuild the
   program, resume; only surface a message if restore never comes (3 s).

## Layout, top to bottom

1. **Masthead** (absolute over the canvas) — wordmark "Kōrei"
   letterspaced .42em, right-side tagline "Rendered by distance".
2. **Stage** — 100svh canvas (`aria-label` describing the scene); a
   centered title block: "Kōrei" in Shippori Mincho
   `clamp(44px, 7vw, 84px)` plus the line "No 3D models. Every pixel is a
   distance, measured."; a top scrim
   (`linear-gradient(rgba(7,10,20,.52), transparent)`, top 38%) so text
   stays readable over the bright dawn sky.
3. **Mood pills** bottom-center — a `fieldset` legend "Light" and three
   buttons Dawn / Dusk / Night with `aria-pressed`, min-height 44px,
   translucent dark fill + `backdrop-filter: blur(6px)`.
4. **Essay** — heading "A landscape with no geometry", a lede, then three
   ruled columns: Distance fields / Sphere tracing / Light, twice more —
   each explaining its concept in two sentences, no jargon left undefined.
5. **Footer** — one line stating the whole landscape lives in one fragment
   shader; links to the build notes and the hub.

## Quality bar

Keyboard: moods are real `button`s with visible `:focus-visible` outlines
(3px, `#9db7ff`). AA contrast everywhere (the scrim is what buys it on the
hero). No horizontal scroll; fully usable and composed at 390px (fewer
march steps + lower DPR there). Honest copy: never claim models or assets
— the point of the page is that there are none.