Bake ambient occlusion into the geometry #82

Closed
opened 2026-10-20 08:49:27 +00:00 by sermuns · 2 comments
Owner

A Soup is positions, per-face normals and UVs. There is no color channel,
and G.ambient adds the same value to every fragment, so every triangle of a
wall, slab or shell shades identically to its neighbours. Interiors, doorways and
the joints between a slab and a facade read as cardboard.

Two phases, in order:

  1. An analytic cavity term at build time: darken vertices near floor and slab
    junctions and in inward corners, and write it to a new vertex color attribute
    that multiplies light in the shared fragment. This is a vertex format change
    plus one term and already removes most of the flatness.
  2. A real bake: raycast against the soup or a coarse occupancy grid and store the
    result in the same channel. The bake CLI is the right place because it can
    afford the time and the result is deterministic.

Vertex color also gives the geometry a place for per-vertex variation later
(weathering, room tint, snow), so it is not a one-purpose attribute.

Related: #7 owns the lighting revamp this belongs to; #79 gives the ambient it
modulates, and #81 is the outdoor variant of the same problem.

A `Soup` is positions, per-face normals and UVs. There is no color channel, and `G.ambient` adds the same value to every fragment, so every triangle of a wall, slab or shell shades identically to its neighbours. Interiors, doorways and the joints between a slab and a facade read as cardboard. Two phases, in order: 1. An analytic cavity term at build time: darken vertices near floor and slab junctions and in inward corners, and write it to a new vertex color attribute that multiplies `light` in the shared fragment. This is a vertex format change plus one term and already removes most of the flatness. 2. A real bake: raycast against the soup or a coarse occupancy grid and store the result in the same channel. The bake CLI is the right place because it can afford the time and the result is deterministic. Vertex color also gives the geometry a place for per-vertex variation later (weathering, room tint, snow), so it is not a one-purpose attribute. Related: #7 owns the lighting revamp this belongs to; #79 gives the ambient it modulates, and #81 is the outdoor variant of the same problem.
sermuns added this to the Rendering milestone 2026-10-20 08:49:27 +00:00
Author
Owner

Phase 1 landed. Phase 2 has not.

The analytic cavity term is in: apply_cavity_ao darkens the vertices near the floor and slab junctions at build time and writes it into the soup, and the shared lit fragment scales the ambient by it. The same per-vertex channel also carries the baked room lamp spill, which is what the attribute was wanted for anyway.

What is missing is phase 2: a real bake, a raycast against the soup or a coarse occupancy grid, run in the bake CLI, which is where the time to afford it is.

Phase 1 landed. Phase 2 has not. The analytic cavity term is in: `apply_cavity_ao` darkens the vertices near the floor and slab junctions at build time and writes it into the soup, and the shared lit fragment scales the ambient by it. The same per-vertex channel also carries the baked room lamp spill, which is what the attribute was wanted for anyway. What is missing is phase 2: a real bake, a raycast against the soup or a coarse occupancy grid, run in the bake CLI, which is where the time to afford it is.
Author
Owner

Status check: unchanged. Phase 1 (apply_cavity_ao plus the ground-contact darkening, multiplied into ambient through soup.ao) is the shipped half; phase 2 — a raycast against the soup or a coarse occupancy grid in the bake CLI — is still absent from liuverse-fetch-map.

Status check: unchanged. Phase 1 (`apply_cavity_ao` plus the ground-contact darkening, multiplied into ambient through `soup.ao`) is the shipped half; phase 2 — a raycast against the soup or a coarse occupancy grid in the bake CLI — is still absent from `liuverse-fetch-map`.
Sign in to join this conversation.
No description provided.