The ground gets cast: per-pixel floor and ceiling, both paintable

True floor-casting replaces the gradients and the projected seam lines:
every screen row lies at one depth, walked with a constant world-space
step and sampled from floor.png underfoot and ceiling.png overhead —
each maze cell wearing exactly one tile, so the artist's border IS the
cell seam. Distance shade and fog fold into the same per-pixel pass,
pixel buffers cache per texture (re-read when a painted file lands),
and the whole frame still clears 60fps with room to spare. Flagstones
and dark slabs ship as the starter files beside the other masonry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Eric Wagoner
2026-08-23 13:05:46 -04:00
co-authored by Claude Fable 5
parent b2a6809a92
commit 0f01f8c356
5 changed files with 95 additions and 41 deletions
+28
View File
@@ -79,6 +79,34 @@ export function proceduralTextures(): Record<string, HTMLCanvasElement> {
c.fillRect(h2(i, 1) * TEX, TEX - h2(i, 7) * TEX, w, h2(i, 7) * TEX);
}
}),
floor: bake((c) => {
// Flagstones: a 2x2 of worn slabs per cell, the mortar border carrying
// the tile seam so every cell reads as one square of the maze.
c.fillStyle = "#3a3226";
c.fillRect(0, 0, TEX, TEX);
for (let r = 0; r < 2; r++) {
for (let q = 0; q < 2; q++) {
const jit = 0.8 + 0.3 * h2(r * 3 + 1, q * 7 + 2);
c.fillStyle = `rgb(${74 * jit | 0},${64 * jit | 0},${48 * jit | 0})`;
c.fillRect(q * (TEX / 2) + 2, r * (TEX / 2) + 2, TEX / 2 - 4, TEX / 2 - 4);
}
}
c.strokeStyle = "rgba(16,12,8,0.9)";
c.lineWidth = 3;
c.strokeRect(0.5, 0.5, TEX - 1, TEX - 1);
}),
ceiling: bake((c) => {
// Heavy dark slabs overhead, barely catching the torchlight.
c.fillStyle = "#161310";
c.fillRect(0, 0, TEX, TEX);
for (let r = 0; r < 2; r++) {
for (let q = 0; q < 2; q++) {
const jit = 0.75 + 0.3 * h2(r * 5 + 3, q * 11 + 4);
c.fillStyle = `rgb(${34 * jit | 0},${30 * jit | 0},${26 * jit | 0})`;
c.fillRect(q * (TEX / 2) + 1, r * (TEX / 2) + 1, TEX / 2 - 2, TEX / 2 - 2);
}
}
}),
warp: bake((c) => {
const grad = c.createLinearGradient(0, 0, TEX, TEX);
grad.addColorStop(0, "#2c1a4e");