Clip lines at the near plane so the ground grid stays visible at low angles (#305)
A line whose end lies behind the eye has no screen point: vs_line divided by a non-positive w, which flipped the segment or dropped it whole. At a low perspective angle the grid lines running along the view direction reach behind the camera and vanished. Cut each segment at clip z = 0 before the screen-space expansion. Fixes #182 Co-authored-by: Vitali M. <6042958+vitalibr@users.noreply.github.com>
This commit is contained in:
1 parent
250d8a2c04
commit
516d80ae8d
1 file changed
+18
-4
@@ -518,8 +518,22 @@ struct LOut {
|
|||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
fn vs_line(@builtin(vertex_index) vi: u32, @location(0) a: vec3<f32>, @location(1) b: vec3<f32>, @location(2) c: vec4<f32>, @location(3) w: f32) -> LOut {
|
fn vs_line(@builtin(vertex_index) vi: u32, @location(0) a: vec3<f32>, @location(1) b: vec3<f32>, @location(2) c: vec4<f32>, @location(3) w: f32) -> LOut {
|
||||||
let ca = u.vp * vec4<f32>(a, 1.0);
|
var pa = a;
|
||||||
let cb = u.vp * vec4<f32>(b, 1.0);
|
var pb = b;
|
||||||
|
var ca = u.vp * vec4<f32>(a, 1.0);
|
||||||
|
var cb = u.vp * vec4<f32>(b, 1.0);
|
||||||
|
// An end behind the near plane (clip z < 0) has no screen point: its divide flips the
|
||||||
|
// line or drops it whole (ground grid lines running past the eye at a low angle). Cut
|
||||||
|
// the segment at the plane instead; clip space is linear in the world point.
|
||||||
|
if (ca.z < 0.0 && cb.z > 0.0) {
|
||||||
|
let k = ca.z / (ca.z - cb.z);
|
||||||
|
ca = mix(ca, cb, k);
|
||||||
|
pa = mix(a, b, k);
|
||||||
|
} else if (cb.z < 0.0 && ca.z > 0.0) {
|
||||||
|
let k = cb.z / (cb.z - ca.z);
|
||||||
|
cb = mix(cb, ca, k);
|
||||||
|
pb = mix(b, a, k);
|
||||||
|
}
|
||||||
let half = u.screen.xy * 0.5;
|
let half = u.screen.xy * 0.5;
|
||||||
let sa = ca.xy / max(ca.w, 1e-6) * half;
|
let sa = ca.xy / max(ca.w, 1e-6) * half;
|
||||||
let sb = cb.xy / max(cb.w, 1e-6) * half;
|
let sb = cb.xy / max(cb.w, 1e-6) * half;
|
||||||
@@ -535,9 +549,9 @@ fn vs_line(@builtin(vertex_index) vi: u32, @location(0) a: vec3<f32>, @location(
|
|||||||
let base = select(ca, cb, t > 0.5);
|
let base = select(ca, cb, t > 0.5);
|
||||||
let off = nrm * s * w * 0.5 + dir * (t * 2.0 - 1.0) * w * 0.5;
|
let off = nrm * s * w * 0.5 + dir * (t * 2.0 - 1.0) * w * 0.5;
|
||||||
var o: LOut;
|
var o: LOut;
|
||||||
o.pos = vec4<f32>(base.xy + off / half * base.w, biased_z(select(a, b, t > 0.5), base, 1.0), base.w);
|
o.pos = vec4<f32>(base.xy + off / half * base.w, biased_z(select(pa, pb, t > 0.5), base, 1.0), base.w);
|
||||||
o.c = c;
|
o.c = c;
|
||||||
o.wp = select(a, b, t > 0.5);
|
o.wp = select(pa, pb, t > 0.5);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user