From 17077ba8bf13925a69244722d60b270363876e4b Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Sat, 4 Jul 2026 21:04:37 +0300 Subject: [PATCH] fix(render): don't apply the draw-order z-bias to 3D mesh outline edges MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mesh (PolyfaceMesh / PolygonMesh) outline edges are drawn through the wire pipeline, whose shader pulls each wire toward the camera by draw_depth * DRAW_ORDER_BIAS (0.001) for 2-D draw-order layering. Every entity gets a draw_depth in [-1, 1], so a mesh's edges were pulled forward too — and when the mesh's depth extent projects to less than the bias (a small or distant mesh), its hidden back-face edges peeked through its own shaded fill. Solid feature edges use the mesh shader, which has no such bias, which is why only meshes showed it and why adjusting the fill's depth bias had no effect. 3-D mesh outline edges are real geometry occluded by true depth, so force their draw_depth to 0 (they are already grouped as `mesh_edge` in upload_wires). They now occlude exactly like solid edges. Co-Authored-By: Claude Opus 4.8 --- src/scene/pipeline/wire_gpu.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/scene/pipeline/wire_gpu.rs b/src/scene/pipeline/wire_gpu.rs index f47498709..708398e77 100644 --- a/src/scene/pipeline/wire_gpu.rs +++ b/src/scene/pipeline/wire_gpu.rs @@ -441,7 +441,12 @@ impl WireGpu { .par_iter() .enumerate() .map(|(idx, w)| { - emit_wire_native(w, idx as u32, w.color, wire_draw_depth(w, depth_map)) + // 3D mesh outline edges are real geometry occluded by true + // depth — they must NOT take the draw-order z-bias (which + // pulls 2D wires toward the camera), or the hidden edges of a + // small / distant mesh peek through its own shaded fill. + let dd = if mesh_edge { 0.0 } else { wire_draw_depth(w, depth_map) }; + emit_wire_native(w, idx as u32, w.color, dd) }) .collect(); let mut instances: Vec = @@ -474,7 +479,10 @@ impl WireGpu { let _ = const_bgl; let per: Vec> = wires .iter() - .map(|w| emit_wire_instances(w, w.color, wire_draw_depth(w, depth_map))) + .map(|w| { + let dd = if mesh_edge { 0.0 } else { wire_draw_depth(w, depth_map) }; + emit_wire_instances(w, w.color, dd) + }) .collect(); let mut instances: Vec = Vec::with_capacity(per.iter().map(Vec::len).sum());