diff --git a/src/app/update.rs b/src/app/update.rs index 55647b9b2..c80634207 100644 --- a/src/app/update.rs +++ b/src/app/update.rs @@ -3069,6 +3069,7 @@ impl OpenCADStudio { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }; previews.push(guide); } @@ -3101,6 +3102,7 @@ impl OpenCADStudio { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }); } } diff --git a/src/entities/dimension.rs b/src/entities/dimension.rs index 14bac4271..b554658f5 100644 --- a/src/entities/dimension.rs +++ b/src/entities/dimension.rs @@ -1172,6 +1172,7 @@ fn tessellate_dimension_inner( plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }); } if !ext2.is_empty() { @@ -1192,6 +1193,7 @@ fn tessellate_dimension_inner( plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }); } } else { @@ -1212,6 +1214,7 @@ fn tessellate_dimension_inner( plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }); } } @@ -1233,6 +1236,7 @@ fn tessellate_dimension_inner( plinegen: true, vp_scissor: None, fill_tris: geom.arrow_fill, + fill_tris_low: Vec::new(), }); // DIMTFILL: 0=none, 1=drawing background (mask), 2=DIMTFILLCLR. @@ -1265,6 +1269,7 @@ fn tessellate_dimension_inner( plinegen: true, vp_scissor: None, fill_tris: rect, + fill_tris_low: Vec::new(), }); } } diff --git a/src/entities/leader.rs b/src/entities/leader.rs index c810312f9..643a4dc56 100644 --- a/src/entities/leader.rs +++ b/src/entities/leader.rs @@ -617,6 +617,7 @@ impl LeaderTess for Leader { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }; } @@ -716,6 +717,7 @@ impl LeaderTess for Leader { plinegen: true, vp_scissor: None, fill_tris, + fill_tris_low: Vec::new(), } } } diff --git a/src/entities/multileader.rs b/src/entities/multileader.rs index e8a53d2d2..9699cc642 100644 --- a/src/entities/multileader.rs +++ b/src/entities/multileader.rs @@ -1309,6 +1309,7 @@ impl MultiLeaderTess for MultiLeader { plinegen: true, vp_scissor: None, fill_tris: arrow_fill, + fill_tris_low: Vec::new(), }); // ── Block content ─────────────────────────────────────────────────────── @@ -1556,6 +1557,7 @@ impl MultiLeaderTess for MultiLeader { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }); } } else if lod_mode == 1 { @@ -1597,6 +1599,7 @@ impl MultiLeaderTess for MultiLeader { plinegen: true, vp_scissor: None, fill_tris: greek_tris, + fill_tris_low: Vec::new(), }); } } else { @@ -1636,6 +1639,7 @@ impl MultiLeaderTess for MultiLeader { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }); } } @@ -1694,6 +1698,7 @@ impl MultiLeaderTess for MultiLeader { plinegen: true, vp_scissor: None, fill_tris, + fill_tris_low: Vec::new(), }); } @@ -1723,6 +1728,7 @@ impl MultiLeaderTess for MultiLeader { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }); } } diff --git a/src/entities/table.rs b/src/entities/table.rs index 8c8959a96..bfb6a2788 100644 --- a/src/entities/table.rs +++ b/src/entities/table.rs @@ -716,6 +716,7 @@ pub fn tessellate_table( plinegen: true, vp_scissor: None, fill_tris, + fill_tris_low: Vec::new(), } }; diff --git a/src/modules/annotate/aligned_dim.rs b/src/modules/annotate/aligned_dim.rs index 507cdeb4f..6062929d9 100644 --- a/src/modules/annotate/aligned_dim.rs +++ b/src/modules/annotate/aligned_dim.rs @@ -108,6 +108,7 @@ impl CadCommand for AlignedDimensionCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } } @@ -149,6 +150,7 @@ fn preview_aligned(p1: Vec3, p2: Vec3, dim_pt: Vec3) -> WireModel { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), } } diff --git a/src/modules/annotate/angular_dim.rs b/src/modules/annotate/angular_dim.rs index 6f151747b..189196098 100644 --- a/src/modules/annotate/angular_dim.rs +++ b/src/modules/annotate/angular_dim.rs @@ -140,6 +140,7 @@ fn preview_wire(points: Vec) -> WireModel { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), } } diff --git a/src/modules/annotate/diameter_dim.rs b/src/modules/annotate/diameter_dim.rs index d3812c6d8..45b8c7037 100644 --- a/src/modules/annotate/diameter_dim.rs +++ b/src/modules/annotate/diameter_dim.rs @@ -111,6 +111,7 @@ fn preview_line(a: Vec3, b: Vec3) -> WireModel { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), } } diff --git a/src/modules/annotate/dim_baseline.rs b/src/modules/annotate/dim_baseline.rs index 1d05c5b43..a0f813d38 100644 --- a/src/modules/annotate/dim_baseline.rs +++ b/src/modules/annotate/dim_baseline.rs @@ -169,6 +169,7 @@ impl CadCommand for DimBaselineCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } } diff --git a/src/modules/annotate/dim_continue.rs b/src/modules/annotate/dim_continue.rs index 4ac5d5a73..630e1f308 100644 --- a/src/modules/annotate/dim_continue.rs +++ b/src/modules/annotate/dim_continue.rs @@ -149,6 +149,7 @@ impl CadCommand for DimContinueCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } } diff --git a/src/modules/annotate/dimjogline.rs b/src/modules/annotate/dimjogline.rs index 65ccda901..e8a8fa251 100644 --- a/src/modules/annotate/dimjogline.rs +++ b/src/modules/annotate/dimjogline.rs @@ -106,6 +106,7 @@ impl CadCommand for DimJogLineCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } } diff --git a/src/modules/annotate/dimtedit.rs b/src/modules/annotate/dimtedit.rs index ba39aae81..42512e9a0 100644 --- a/src/modules/annotate/dimtedit.rs +++ b/src/modules/annotate/dimtedit.rs @@ -120,6 +120,7 @@ impl CadCommand for DimTeditCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } diff --git a/src/modules/annotate/leader_cmd.rs b/src/modules/annotate/leader_cmd.rs index e58fe490b..4c4854136 100644 --- a/src/modules/annotate/leader_cmd.rs +++ b/src/modules/annotate/leader_cmd.rs @@ -179,6 +179,7 @@ fn preview_wire(pts: &[Vec3]) -> WireModel { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), } } diff --git a/src/modules/annotate/linear_dim.rs b/src/modules/annotate/linear_dim.rs index b56d8b7a5..0734a8d1c 100644 --- a/src/modules/annotate/linear_dim.rs +++ b/src/modules/annotate/linear_dim.rs @@ -147,6 +147,7 @@ fn preview_wire(points: Vec) -> WireModel { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), } } diff --git a/src/modules/annotate/mleader_cmd.rs b/src/modules/annotate/mleader_cmd.rs index 00c3d4769..1e4d93e52 100644 --- a/src/modules/annotate/mleader_cmd.rs +++ b/src/modules/annotate/mleader_cmd.rs @@ -165,6 +165,7 @@ fn preview_wire(pts: &[Vec3]) -> WireModel { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), } } diff --git a/src/modules/annotate/mleader_edit.rs b/src/modules/annotate/mleader_edit.rs index 2a3ff4f27..e06ad89a6 100644 --- a/src/modules/annotate/mleader_edit.rs +++ b/src/modules/annotate/mleader_edit.rs @@ -472,6 +472,7 @@ fn preview_wire(pts: &[Vec3]) -> WireModel { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), } } diff --git a/src/modules/annotate/qdim.rs b/src/modules/annotate/qdim.rs index 64a682ccf..9d5760a52 100644 --- a/src/modules/annotate/qdim.rs +++ b/src/modules/annotate/qdim.rs @@ -104,6 +104,7 @@ impl CadCommand for QdimCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } } diff --git a/src/modules/annotate/radius_dim.rs b/src/modules/annotate/radius_dim.rs index 9e56aca82..691d4fd04 100644 --- a/src/modules/annotate/radius_dim.rs +++ b/src/modules/annotate/radius_dim.rs @@ -116,6 +116,7 @@ fn preview_wire(points: Vec) -> WireModel { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), } } diff --git a/src/modules/annotate/table_cmd.rs b/src/modules/annotate/table_cmd.rs index 416109dad..8d3a94db3 100644 --- a/src/modules/annotate/table_cmd.rs +++ b/src/modules/annotate/table_cmd.rs @@ -164,6 +164,7 @@ impl CadCommand for TableCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } else { None diff --git a/src/modules/annotate/tolerance_cmd.rs b/src/modules/annotate/tolerance_cmd.rs index 395a7dd4e..92aaba3dc 100644 --- a/src/modules/annotate/tolerance_cmd.rs +++ b/src/modules/annotate/tolerance_cmd.rs @@ -106,6 +106,7 @@ impl CadCommand for ToleranceCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } } diff --git a/src/modules/draw/draw/attdef.rs b/src/modules/draw/draw/attdef.rs index dd56da3fd..cdf02b6f6 100644 --- a/src/modules/draw/draw/attdef.rs +++ b/src/modules/draw/draw/attdef.rs @@ -182,6 +182,7 @@ impl CadCommand for AttdefCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } } diff --git a/src/modules/draw/draw/ellipse.rs b/src/modules/draw/draw/ellipse.rs index 576a3a60e..022b7765b 100644 --- a/src/modules/draw/draw/ellipse.rs +++ b/src/modules/draw/draw/ellipse.rs @@ -627,6 +627,7 @@ fn line_wire(from: Vec3, to: Vec3) -> WireModel { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), } } diff --git a/src/modules/draw/draw/line.rs b/src/modules/draw/draw/line.rs index de3e6c4eb..beea71e97 100644 --- a/src/modules/draw/draw/line.rs +++ b/src/modules/draw/draw/line.rs @@ -92,6 +92,7 @@ impl CadCommand for LineCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } } diff --git a/src/modules/draw/draw/mline.rs b/src/modules/draw/draw/mline.rs index f4b8c9e34..15e7b09d1 100644 --- a/src/modules/draw/draw/mline.rs +++ b/src/modules/draw/draw/mline.rs @@ -147,6 +147,7 @@ impl CadCommand for MlineCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } } diff --git a/src/modules/draw/draw/raster_image.rs b/src/modules/draw/draw/raster_image.rs index cbd5e667e..75cb63b68 100644 --- a/src/modules/draw/draw/raster_image.rs +++ b/src/modules/draw/draw/raster_image.rs @@ -124,6 +124,7 @@ impl CadCommand for ImageCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } } diff --git a/src/modules/draw/draw/ray.rs b/src/modules/draw/draw/ray.rs index 7debccdd6..3bf37ca47 100644 --- a/src/modules/draw/draw/ray.rs +++ b/src/modules/draw/draw/ray.rs @@ -90,6 +90,7 @@ impl CadCommand for RayCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } } @@ -172,6 +173,7 @@ impl CadCommand for XLineCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } } diff --git a/src/modules/draw/draw/revcloud.rs b/src/modules/draw/draw/revcloud.rs index ef657d4e6..0a5d51a43 100644 --- a/src/modules/draw/draw/revcloud.rs +++ b/src/modules/draw/draw/revcloud.rs @@ -96,6 +96,7 @@ impl CadCommand for RevCloudCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } } diff --git a/src/modules/draw/draw/wipeout.rs b/src/modules/draw/draw/wipeout.rs index 4643efe20..a2b2899b1 100644 --- a/src/modules/draw/draw/wipeout.rs +++ b/src/modules/draw/draw/wipeout.rs @@ -136,6 +136,7 @@ impl CadCommand for WipeoutCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } WipeoutMode::Polygonal => { @@ -163,6 +164,7 @@ impl CadCommand for WipeoutCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } } diff --git a/src/modules/draw/inquiry/area.rs b/src/modules/draw/inquiry/area.rs index 6c2c402da..22c50e89f 100644 --- a/src/modules/draw/inquiry/area.rs +++ b/src/modules/draw/inquiry/area.rs @@ -80,6 +80,7 @@ impl CadCommand for AreaCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } } diff --git a/src/modules/draw/inquiry/dist.rs b/src/modules/draw/inquiry/dist.rs index 060f0cfed..c3a6ef29d 100644 --- a/src/modules/draw/inquiry/dist.rs +++ b/src/modules/draw/inquiry/dist.rs @@ -75,6 +75,7 @@ impl CadCommand for DistCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } } diff --git a/src/modules/layout/mview.rs b/src/modules/layout/mview.rs index 5a394d442..1f364d806 100644 --- a/src/modules/layout/mview.rs +++ b/src/modules/layout/mview.rs @@ -102,6 +102,7 @@ impl CadCommand for MviewCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } } diff --git a/src/modules/model/primitive_cmd.rs b/src/modules/model/primitive_cmd.rs index d5723524c..da6a263e3 100644 --- a/src/modules/model/primitive_cmd.rs +++ b/src/modules/model/primitive_cmd.rs @@ -321,5 +321,6 @@ fn wire(name: &str, points: Vec<[f32; 3]>) -> WireModel { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), } } diff --git a/src/modules/view/plot_window.rs b/src/modules/view/plot_window.rs index 412cdcc56..56d0d3c6c 100644 --- a/src/modules/view/plot_window.rs +++ b/src/modules/view/plot_window.rs @@ -73,6 +73,7 @@ impl CadCommand for PlotWindowCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } } diff --git a/src/modules/view/zoom_window.rs b/src/modules/view/zoom_window.rs index 21d478d5e..717fdb448 100644 --- a/src/modules/view/zoom_window.rs +++ b/src/modules/view/zoom_window.rs @@ -73,6 +73,7 @@ impl CadCommand for ZoomWindowCommand { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) } } diff --git a/src/scene/cache/block_cache.rs b/src/scene/cache/block_cache.rs index 45d9a01d6..58f2398a2 100644 --- a/src/scene/cache/block_cache.rs +++ b/src/scene/cache/block_cache.rs @@ -1130,6 +1130,7 @@ impl Batches { plinegen: b.plinegen, vp_scissor: None, fill_tris: b.fill_tris, + fill_tris_low: Vec::new(), } }) .collect() diff --git a/src/scene/convert/tessellate.rs b/src/scene/convert/tessellate.rs index 031994d9e..404c13983 100644 --- a/src/scene/convert/tessellate.rs +++ b/src/scene/convert/tessellate.rs @@ -239,6 +239,7 @@ pub fn tessellate( plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }]; } @@ -278,6 +279,7 @@ pub fn tessellate( plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }); } return out; @@ -324,6 +326,7 @@ pub fn tessellate( plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }]; } _ => {} @@ -358,6 +361,7 @@ pub fn tessellate( plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }]; } } @@ -390,6 +394,7 @@ pub fn tessellate( plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }]; } } @@ -409,11 +414,7 @@ pub fn tessellate( .into_iter() .map(|[x, y, z]| [(x - ox) as f32, (y - oy) as f32, (z - oz) as f32]) .collect(); - let fill_tris: Vec<[f32; 3]> = te - .fill_tris - .into_iter() - .map(|[x, y, z]| [(x - ox) as f32, (y - oy) as f32, (z - oz) as f32]) - .collect(); + let (fill_tris, fill_tris_low) = offset_to_ds(te.fill_tris, world_offset); return vec![WireModel { name, points: local_pts, @@ -431,6 +432,7 @@ pub fn tessellate( plinegen: true, vp_scissor: None, fill_tris, + fill_tris_low, }]; } @@ -460,6 +462,7 @@ pub fn tessellate( vp_scissor: None, aabb: WireModel::UNBOUNDED_AABB, fill_tris: vec![], + fill_tris_low: Vec::new(), }]; } @@ -501,6 +504,7 @@ pub fn tessellate( plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }] } diff --git a/src/scene/mod.rs b/src/scene/mod.rs index e1d18c888..30cebfae6 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -8210,6 +8210,7 @@ fn tessellate_entity( plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }; if let Some(cache) = block_cache { @@ -8422,6 +8423,7 @@ fn tessellate_entity( plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }]; } if h_px < 5.0 && aabb != WireModel::UNBOUNDED_AABB { @@ -8460,6 +8462,7 @@ fn tessellate_entity( plinegen: true, vp_scissor: None, fill_tris, + fill_tris_low: Vec::new(), }]; } } @@ -8569,6 +8572,7 @@ fn lod_stub_wire( plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), } } @@ -8628,6 +8632,7 @@ fn lod_stub_wire_3d( plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), } } diff --git a/src/scene/model/wire_model.rs b/src/scene/model/wire_model.rs index a6775c0cd..cc25f24bc 100644 --- a/src/scene/model/wire_model.rs +++ b/src/scene/model/wire_model.rs @@ -79,6 +79,9 @@ pub struct WireModel { /// Pre-triangulated solid fill: flat vertex list, 3 per triangle (world-offset applied). /// Non-empty only for PolyfaceMesh / PolygonMesh entities. pub fill_tris: Vec<[f32; 3]>, + /// Low residual paired with [`fill_tris`] (double-single). Empty = all-zero; + /// tessellation from CAD f64 fills it so fills stay precise at UTM scale. + pub fill_tris_low: Vec<[f32; 3]>, } impl WireModel { @@ -114,6 +117,7 @@ impl WireModel { plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), } } @@ -237,6 +241,7 @@ impl Default for WireModel { plinegen: true, vp_scissor: None, fill_tris: Vec::new(), + fill_tris_low: Vec::new(), } } } diff --git a/src/scene/pipeline/face3d_gpu.rs b/src/scene/pipeline/face3d_gpu.rs index c167ea1c8..3515e1745 100644 --- a/src/scene/pipeline/face3d_gpu.rs +++ b/src/scene/pipeline/face3d_gpu.rs @@ -33,30 +33,40 @@ pub struct Face3DVertex { /// applied as a small clip-z bias in the shader. 0.0 for true 3D mesh /// faces (PolyfaceMesh / PolygonMesh) so their real depth is preserved. pub draw_depth: f32, + /// Double-single low residual of `position` so fills stay precise at + /// UTM-scale coordinates (zero for 3DFACE quads built from key_vertices, + /// which don't carry a residual). + pub position_low: [f32; 3], } impl Face3DVertex { pub fn layout<'a>() -> wgpu::VertexBufferLayout<'a> { + const ATTRS: &[wgpu::VertexAttribute] = &[ + wgpu::VertexAttribute { + offset: std::mem::offset_of!(Face3DVertex, position) as u64, + shader_location: 0, + format: wgpu::VertexFormat::Float32x3, + }, + wgpu::VertexAttribute { + offset: std::mem::offset_of!(Face3DVertex, color) as u64, + shader_location: 1, + format: wgpu::VertexFormat::Float32x4, + }, + wgpu::VertexAttribute { + offset: std::mem::offset_of!(Face3DVertex, draw_depth) as u64, + shader_location: 2, + format: wgpu::VertexFormat::Float32, + }, + wgpu::VertexAttribute { + offset: std::mem::offset_of!(Face3DVertex, position_low) as u64, + shader_location: 3, + format: wgpu::VertexFormat::Float32x3, + }, + ]; wgpu::VertexBufferLayout { array_stride: std::mem::size_of::() as u64, step_mode: wgpu::VertexStepMode::Vertex, - attributes: &[ - wgpu::VertexAttribute { - offset: 0, - shader_location: 0, - format: wgpu::VertexFormat::Float32x3, - }, - wgpu::VertexAttribute { - offset: 12, - shader_location: 1, - format: wgpu::VertexFormat::Float32x4, - }, - wgpu::VertexAttribute { - offset: 28, - shader_location: 2, - format: wgpu::VertexFormat::Float32, - }, - ], + attributes: ATTRS, } } } @@ -120,6 +130,7 @@ impl Face3DGpu { position: p[i], color: fill_color, draw_depth: depth, + position_low: [0.0; 3], }; verts_3d.push(v(0)); verts_3d.push(v(1)); @@ -153,21 +164,23 @@ impl Face3DGpu { let fill_color = [r * 0.45, g * 0.45, b * 0.45, a]; // True 3D surface: keep real depth (no draw-order bias) so // hidden-surface shading is preserved. - for &position in &wire.fill_tris { + for (i, &position) in wire.fill_tris.iter().enumerate() { verts_3d.push(Face3DVertex { position, color: fill_color, draw_depth: 0.0, + position_low: wire.fill_tris_low.get(i).copied().unwrap_or([0.0; 3]), }); } } else { let fill_color = [r, g, b, a]; let depth = depth_of(wire); - for &position in &wire.fill_tris { + for (i, &position) in wire.fill_tris.iter().enumerate() { verts_2d.push(Face3DVertex { position, color: fill_color, draw_depth: depth, + position_low: wire.fill_tris_low.get(i).copied().unwrap_or([0.0; 3]), }); } } diff --git a/src/scene/text/complex_lt.rs b/src/scene/text/complex_lt.rs index 557686277..9abdda8c2 100644 --- a/src/scene/text/complex_lt.rs +++ b/src/scene/text/complex_lt.rs @@ -224,6 +224,7 @@ pub fn apply_along( plinegen: true, vp_scissor: None, fill_tris: vec![], + fill_tris_low: Vec::new(), }) .collect() } diff --git a/src/shaders/face3d.wgsl b/src/shaders/face3d.wgsl index 520db70ec..84439bd44 100644 --- a/src/shaders/face3d.wgsl +++ b/src/shaders/face3d.wgsl @@ -25,9 +25,10 @@ struct Uniforms { var u: Uniforms; struct VertexIn { - @location(0) position: vec3, - @location(1) color: vec4, - @location(2) draw_depth: f32, + @location(0) position: vec3, + @location(1) color: vec4, + @location(2) draw_depth: f32, + @location(3) position_low: vec3, }; struct VertexOut { @@ -42,7 +43,8 @@ const DRAW_ORDER_BIAS: f32 = 0.001; @vertex fn vs_main(v: VertexIn) -> VertexOut { var out: VertexOut; - out.clip_pos = u.view_rot * vec4((v.position - u.eye_high) - u.eye_low, 1.0); + let rel = (v.position - u.eye_high) + (v.position_low - u.eye_low); + out.clip_pos = u.view_rot * vec4(rel, 1.0); out.clip_pos.z = out.clip_pos.z - v.draw_depth * DRAW_ORDER_BIAS * out.clip_pos.w; out.color = v.color; return out;