Hatch/wipeout boundary sub-loops were separated by NaN vertices that the fill shaders detected with `p.x == p.x`. Intel Mesa folds that NaN self-compare to `true` under fast math, so separators read as real vertices, the ray-cast crossing count broke, and fills bled outside their boundary — only on Intel iGPUs. GPU uploads now rewrite the separators to a finite 1e30 sentinel (GPU_BOUNDARY_SEP) and the shaders test `abs(x) < 1e29`, which every driver evaluates identically. The CPU-side NaN representation is unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
0c578b03f3
commit
805da6428a
7 changed files with 46 additions and 10 deletions
|
|
@ -310,12 +310,14 @@ impl WipeoutGpu {
|
|||
.take(MAX_HATCH_BOUNDARY_VERTS)
|
||||
.enumerate()
|
||||
{
|
||||
// Preserve NaN separators — they signal path breaks to the
|
||||
// in_polygon ray-cast, must not be shifted into finite numbers.
|
||||
// Path-break separators go up as the finite GPU sentinel, not
|
||||
// NaN — the shader NaN self-compare is folded to `true` on some
|
||||
// drivers (#386, #416) — and must not be shifted by `drift`.
|
||||
if x.is_finite() && y.is_finite() {
|
||||
boundary_data.verts[i] = [x + drift[0], y + drift[1], 0.0, 0.0];
|
||||
} else {
|
||||
boundary_data.verts[i] = [f32::NAN, f32::NAN, 0.0, 0.0];
|
||||
let s = crate::scene::model::hatch_model::GPU_BOUNDARY_SEP;
|
||||
boundary_data.verts[i] = [s, s, 0.0, 0.0];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue