forked from 1b-agent/opencadstudio-upstream
feat(lwpolyline): render the wide-polyline band via the wire shader
A wide polyline's flat band was drawn by the hatch pipeline: a solid fill with only draw-order depth. It ignored the entity linetype (the width "crushed" the dash pattern) and showed through 3-D geometry in a tilted view. Draw the band from the polyline's own centre-line wire instead. A new `WireModel.world_width` (drawing units) makes the wire vertex shader expand the quad by `world_half_width / world_per_pixel` (clamped to a hairline), so the band is sized in world units and tracks zoom. Because it is now a wire: - the GPU dash shader dashes the band by arc-length — the linetype applies; - it is depth-tested at the polyline elevation — no draw-order see-through; - no CPU band triangles or per-dash geometry are generated. `world_half_width` rides in `WireConst` (native, replacing a pad) and the web `WireInstance` (loc 14); both wire shaders branch on it. The tessellator sets `world_width` from the LwPolyline width on the Contour / SegmentedLines arms, and the model-space fill loop no longer emits a hatch band for any LwPolyline. Pick still uses the band polygon (`pick_tris`). Blocks keep the hatch band: `LocalWire` carries no `world_width` (finalize zeroes it), so a scaled insert still scales its band correctly. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
3d37e1f8d8
commit
bd1a5affd7
44 files changed
+158
-17
No files matched your search
+14
-2
@@ -59,6 +59,8 @@ struct InstanceIn {
|
||||
// "A"-type endpoint alignment: end-dash length + total wire length.
|
||||
@location(12) align_end: f32,
|
||||
@location(13) align_total: f32,
|
||||
// World-space half-width for a wide-polyline band. 0 = normal wire.
|
||||
@location(14) world_half_width: f32,
|
||||
}
|
||||
|
||||
// Draw-order depth bias: shifts clip-space z so 2D entities of different
|
||||
@@ -129,8 +131,18 @@ struct VertexOut {
|
||||
// Select the clip-space position for this vertex's endpoint.
|
||||
let clip_pos = mix(clip_a, clip_b, which_end);
|
||||
|
||||
// LWDISPLAY off → collapse to a 1-pixel-wide line (half_width = 0.5).
|
||||
let hw = select(0.5, in.half_width, u.lwdisplay_enable > 0.5);
|
||||
// A wide polyline carries its band width in world units: expand the quad by
|
||||
// `world_half_width / world_per_pixel` (pixels) so the band tracks zoom. A
|
||||
// normal wire (world_half_width == 0) uses the screen-pixel half-width,
|
||||
// honouring the LWDISPLAY toggle (off → collapse to a 1-pixel line).
|
||||
var hw: f32;
|
||||
if in.world_half_width > 0.0 {
|
||||
// Clamp to a half-pixel so a zoomed-out band never drops below a
|
||||
// hairline (its centre-line) instead of vanishing.
|
||||
hw = max(in.world_half_width / u.world_per_pixel, 0.5);
|
||||
} else {
|
||||
hw = select(0.5, in.half_width, u.lwdisplay_enable > 0.5);
|
||||
}
|
||||
|
||||
// Offset in clip space (multiply by w to un-apply perspective division).
|
||||
let ndc_offset = perp_ndc * hw * side;
|
||||
|
||||
@@ -30,7 +30,7 @@ struct WireConst {
|
||||
draw_depth: f32,
|
||||
align_end: f32,
|
||||
align_total: f32,
|
||||
_pad0: f32,
|
||||
world_half_width: f32,
|
||||
_pad1: f32,
|
||||
_pad2: f32,
|
||||
}
|
||||
@@ -93,7 +93,18 @@ struct VertexOut {
|
||||
|
||||
let clip_pos = mix(clip_a, clip_b, which_end);
|
||||
|
||||
let hw = select(0.5, c.half_width, u.lwdisplay_enable > 0.5);
|
||||
// A wide polyline carries its band width in world units: expand the quad
|
||||
// by `world_half_width / world_per_pixel` (screen pixels) so the band grows
|
||||
// and shrinks with zoom. A normal wire (world_half_width == 0) uses the
|
||||
// screen-pixel half-width, honouring the LWDISPLAY toggle.
|
||||
var hw: f32;
|
||||
if c.world_half_width > 0.0 {
|
||||
// Clamp to a half-pixel so a zoomed-out band never drops below a
|
||||
// hairline (its centre-line) instead of vanishing.
|
||||
hw = max(c.world_half_width / u.world_per_pixel, 0.5);
|
||||
} else {
|
||||
hw = select(0.5, c.half_width, u.lwdisplay_enable > 0.5);
|
||||
}
|
||||
|
||||
let ndc_offset = perp_ndc * hw * side;
|
||||
let final_clip = clip_pos + vec4<f32>(ndc_offset * clip_pos.w, 0.0, 0.0);
|
||||
|
||||
Reference in new issue
Block a user