From e17c298284cbad75702c4bcfb0840f77124d0170 Mon Sep 17 00:00:00 2001 From: Wassim SAMAD Date: Tue, 16 Jun 2026 11:10:34 -0400 Subject: [PATCH] fix(shelf): recess plates 1mm to stop z-fighting with the frame MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Open-rack / no-sides shelves span their boards across the full footprint, so a board's end / front / back faces land exactly on the corner posts' outer faces (and, with a back panel, on its rear face). Coplanar surfaces the depth buffer can't order flicker as z-fighting (visible as seams where plates meet posts). Recess every board 1mm on width + depth via a `boardGeometry` helper so each plate sits just inside the frame — the meshes still overlap (no visible gap), but no two faces are coplanar. Frame parts (posts/sides/back/dividers/brackets) keep their full size as the silhouette. Co-Authored-By: Claude Opus 4.8 (1M context) --- packages/nodes/src/shelf/geometry.ts | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/packages/nodes/src/shelf/geometry.ts b/packages/nodes/src/shelf/geometry.ts index 56dbfa1f..f51834a6 100644 --- a/packages/nodes/src/shelf/geometry.ts +++ b/packages/nodes/src/shelf/geometry.ts @@ -63,6 +63,21 @@ function stampShelfSlot(mesh: Mesh, slotId: ShelfSlotId): Mesh { return mesh } +// Plates (boards) span the full footprint, so their end / front / back faces +// land exactly on the frame's (posts / sides / back) outer faces — coplanar +// surfaces the depth buffer can't separate, which flickers as z-fighting. Recess +// every board 1mm on width + depth so it sits just inside the frame: the meshes +// still overlap (no visible gap), but no two faces are coplanar. +const BOARD_INSET = 0.001 + +function boardGeometry(width: number, thickness: number, depth: number): BoxGeometry { + return new BoxGeometry( + Math.max(width - 2 * BOARD_INSET, 0.001), + thickness, + Math.max(depth - 2 * BOARD_INSET, 0.001), + ) +} + export function buildShelfGeometry( rawNode: ShelfNode, ctx?: GeometryContext, @@ -113,7 +128,7 @@ export function buildShelfGeometry( function buildWallShelf(group: Group, node: ShelfNode, materials: ShelfSlotMaterials) { for (const y of boardCenterYs(node)) { const board = stampShelfSlot( - new Mesh(new BoxGeometry(node.width, node.thickness, node.depth), materials.shelves), + new Mesh(boardGeometry(node.width, node.thickness, node.depth), materials.shelves), 'shelves', ) board.name = `shelf-board-${boardRowIndex(node, y)}` @@ -155,7 +170,7 @@ function buildBookshelf(group: Group, node: ShelfNode, materials: ShelfSlotMater // Top + bottom + intermediate boards for (const y of boardCenterYs(node)) { const board = stampShelfSlot( - new Mesh(new BoxGeometry(innerWidth, node.thickness, node.depth), materials.shelves), + new Mesh(boardGeometry(innerWidth, node.thickness, node.depth), materials.shelves), 'shelves', ) board.name = `shelf-board-${boardRowIndex(node, y)}` @@ -165,7 +180,7 @@ function buildBookshelf(group: Group, node: ShelfNode, materials: ShelfSlotMater if (node.withBottom) { const bottom = stampShelfSlot( - new Mesh(new BoxGeometry(innerWidth, node.thickness, node.depth), materials.shelves), + new Mesh(boardGeometry(innerWidth, node.thickness, node.depth), materials.shelves), 'shelves', ) bottom.name = 'shelf-board-bottom' @@ -226,7 +241,7 @@ function buildOpenRack(group: Group, node: ShelfNode, materials: ShelfSlotMateri for (const y of boardCenterYs(node)) { const board = stampShelfSlot( - new Mesh(new BoxGeometry(innerWidth, boardThickness, node.depth), materials.shelves), + new Mesh(boardGeometry(innerWidth, boardThickness, node.depth), materials.shelves), 'shelves', ) board.name = `shelf-board-${boardRowIndex(node, y)}` @@ -264,7 +279,7 @@ function buildCubby(group: Group, node: ShelfNode, materials: ShelfSlotMaterials for (const y of boardCenterYs(node)) { const board = stampShelfSlot( - new Mesh(new BoxGeometry(innerWidth, node.thickness, node.depth), materials.shelves), + new Mesh(boardGeometry(innerWidth, node.thickness, node.depth), materials.shelves), 'shelves', ) board.name = `shelf-board-${boardRowIndex(node, y)}` @@ -274,7 +289,7 @@ function buildCubby(group: Group, node: ShelfNode, materials: ShelfSlotMaterials if (node.withBottom) { const bottom = stampShelfSlot( - new Mesh(new BoxGeometry(innerWidth, node.thickness, node.depth), materials.shelves), + new Mesh(boardGeometry(innerWidth, node.thickness, node.depth), materials.shelves), 'shelves', ) bottom.name = 'shelf-board-bottom'