feat(render): double-single vertex positions for the wire pipeline

Vertices now carry the low residual alongside the high half all the way
to the GPU: tessellation splits the offset-relative f64 coordinate into
(high, low) f32 (TruckTessResult::Lines/Point, the Text path, Lines /
SegmentedLines, and the block-cache instance transform), WireModel and
the block batch carry a paired points_low buffer, WireInstance gains
pos_a_low/pos_b_low (locations 10/11), and wire.wgsl reconstructs
rel = (pos_high - eye_high) + (pos_low - eye_low).

This is the piece the camera-only RTE was missing: at UTM-scale
coordinates the single-f32 vertex was quantized to ~0.5 m, so it snapped
each time the eye crossed an f32 boundary on pan. With the low half the
position is exact and the cross-drawing-paste jitter is gone.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-06-23 17:44:09 +03:00
commit 6a74f12a92
6 changed files with 237 additions and 151 deletions

View file

@ -53,6 +53,9 @@ struct InstanceIn {
@location(7) pat0: vec4<f32>,
@location(8) pat1: vec4<f32>,
@location(9) draw_depth: f32,
// Double-single low residuals of the endpoints.
@location(10) pos_a_low: vec3<f32>,
@location(11) pos_b_low: vec3<f32>,
}
// Draw-order depth bias: shifts clip-space z so 2D entities of different
@ -85,13 +88,14 @@ struct VertexOut {
let which_end = which_end_arr[vid];
let side = side_arr[vid];
// Relative-to-eye: subtract the eye (high+low) from each endpoint, then
// transform by the rotation-only view-projection. (pos − eye_high) is exact
// in f32 when both are the same magnitude (Sterbenz), and eye_low corrects
// the eye's sub-f32 residual — so the position tracks the camera smoothly
// at large coordinates instead of snapping onto the f32 grid each frame.
let rel_a = (in.pos_a - u.eye_high) - u.eye_low;
let rel_b = (in.pos_b - u.eye_high) - u.eye_low;
// Double-single relative-to-eye: subtract the eye from each endpoint with
// both halves of the f64-emulating pair, then transform by the rotation-only
// view-projection. (pos_high − eye_high) is exact in f32 for same-magnitude
// operands (Sterbenz); adding (pos_low − eye_low) restores the residual both
// the vertex and the eye would otherwise lose — so geometry stays put at
// UTM-scale coordinates and after a cross-drawing paste, with no jitter.
let rel_a = (in.pos_a - u.eye_high) + (in.pos_a_low - u.eye_low);
let rel_b = (in.pos_b - u.eye_high) + (in.pos_b_low - u.eye_low);
let clip_a = u.view_rot * vec4<f32>(rel_a, 1.0);
let clip_b = u.view_rot * vec4<f32>(rel_b, 1.0);