#include "shared.h"
#include "renderer_types.h"
[vk::push_constant]
DebugLinesPushConstants pc;
struct DebugLineOut {
vec4 position : SV_Position;
vec4 color : TEXCOORD0;
};
// thick lines: each input (2 verts) protrudes to a camera-facing quad
// (6 verts / 2 triangles), widht is per-vertex px, averaged over endpoints
[shader("vertex")]
DebugLineOut vsThickMain(u32 vertexID: SV_VertexID) {
DebugLineOut o;
u32 line_idx = vertexID / 6;
u32 corner = vertexID % 6;
DebugLineVertexGPU va = pc.lines[line_idx * 2 + 0];
DebugLineVertexGPU vb = pc.lines[line_idx * 2 + 1];
FrameUBO frame = *pc.frame;
vec4 ca = vec4(va.pos, 1.0) * frame.view_proj;
vec4 cb = vec4(vb.pos, 1.0) * frame.view_proj;
f32 wa = asfloat(va.width_bits);
f32 wb = asfloat(vb.width_bits);
f32 half_px = (wa + wb) * 0.25f;
// degen: behind camera
if (ca.w <= 0.0f || cb.w <= 0.0f || half_px <= 0.0f) {
o.position = vec4(0.0, 0.0, 2.0, 1.0); // w=1, z beyond far -> clipped
o.color = va.color;
return o;
}
vec2 na = ca.xy / ca.w;
vec2 nb = cb.xy / cb.w;
// screen space direction (aspect-correct) for a stable perpendicular.
vec2 pa = vec2(na.x * pc.viewport_w, na.y * pc.viewport_h);
vec2 pb = vec2(nb.x * pc.viewport_w, nb.y * pc.viewport_h);
vec2 d = pb - pa;
f32 len = length(d);
if (len < 1e-4) {
o.position = vec4(0.0, 0.0, 2.0, 1.0);
o.color = va.color;
return o;
}
vec2 n = vec2(-d.y, d.x) / len;
// grab endpoint + side for this corner.
// tri 1: a+n, a-n, b+n | Tri 2: b+n, a-n, b-n
vec4 c;
vec2 off;
f32 pick_w;
if (corner == 0) {
c = ca;
off = n;
pick_w = ca.w;
} else if (corner == 1) {
c = ca;
off = -n;
pick_w = ca.w;
} else if (corner == 2) {
c = cb;
off = n;
pick_w = cb.w;
} else if (corner == 3) {
c = cb;
off = n;
pick_w = cb.w;
} else if (corner == 4) {
c = ca;
off = -n;
pick_w = ca.w;
} else {
c = cb;
off = -n;
pick_w = cb.w;
}
vec2 off_clip = vec2(off.x * half_px / (pc.viewport_w * 0.5), off.y * half_px / (pc.viewport_h * 0.5)) * pick_w;
o.position = vec4(c.xy + off_clip, c.zw);
o.color = (corner == 2 || corner == 3 || corner == 5) ? vb.color : va.color;
return o;
}
[shader("fragment")]
vec4 fsMain(DebugLineOut input) : SV_Target {
return input.color;
}