// Line-draw shader for OSM ways.
// Vertices are in Mercator [0,1] space with pre-baked RGBA color.
// Uniforms carry zoom, pan offset, and viewport size so the VS can
// map directly to clip space without knowing the logical resolution at
// compile time.
struct Uniforms {
zoom: f32,
offset_x: f32,
offset_y: f32,
_pad: f32,
viewport_w: f32,
viewport_h: f32,
_pad2: vec2<f32>,
}
@group(0) @binding(0) var<uniform> u: Uniforms;
struct VertexOut {
@builtin(position) pos: vec4<f32>,
@location(0) col: vec4<f32>,
}
@vertex
fn vs_main(
@location(0) mercator: vec2<f32>,
@location(1) color: vec4<f32>,
) -> VertexOut {
// Mercator [0,1] → screen pixel (logical)
let sx = mercator.x * u.zoom + u.offset_x;
let sy = mercator.y * u.zoom + u.offset_y;
// Screen pixel → clip space [-1, 1]; y is flipped (screen y=0 is top)
let cx = sx / (u.viewport_w * 0.5) - 1.0;
let cy = 1.0 - sy / (u.viewport_h * 0.5);
return VertexOut(vec4<f32>(cx, cy, 0.0, 1.0), color);
}
@fragment
fn fs_main(in: VertexOut) -> @location(0) vec4<f32> {
return in.col;
}