#version 450 core // ---------- Vertex attributes (used in both modes) ---------- layout(location = 0) in vec2 v_position; layout(location = 1) in vec2 v_uv; layout(location = 2) in vec4 v_color; // ---------- Outputs to fragment shader ---------- layout(location = 0) out vec4 f_color; layout(location = 1) out vec2 f_local_or_uv; layout(location = 2) out vec4 f_params; layout(location = 3) out vec4 f_params2; layout(location = 4) flat out uint f_kind_flags; layout(location = 5) flat out float f_rotation; layout(location = 6) flat out vec4 f_uv_rect; // ---------- Uniforms (single block — avoids spirv-cross reordering on Metal) ---------- layout(set = 1, binding = 0) uniform Uniforms { mat4 projection; float dpi_scale; uint mode; // 0 = tessellated, 1 = SDF }; // ---------- SDF primitive storage buffer ---------- struct Primitive { vec4 bounds; // 0-15: min_x, min_y, max_x, max_y uint color; // 16-19: packed u8x4 (unpack with unpackUnorm4x8) uint kind_flags; // 20-23: kind | (flags << 8) float rotation; // 24-27: shader self-rotation in radians float _pad; // 28-31: alignment padding vec4 params; // 32-47: shape params part 1 vec4 params2; // 48-63: shape params part 2 vec4 uv_rect; // 64-79: u_min, v_min, u_max, v_max }; layout(std430, set = 0, binding = 0) readonly buffer Primitives { Primitive primitives[]; }; // ---------- Entry point ---------- void main() { if (mode == 0u) { // ---- Mode 0: Tessellated (legacy) ---- f_color = v_color; f_local_or_uv = v_uv; f_params = vec4(0.0); f_params2 = vec4(0.0); f_kind_flags = 0u; f_rotation = 0.0; f_uv_rect = vec4(0.0, 0.0, 1.0, 1.0); gl_Position = projection * vec4(v_position * dpi_scale, 0.0, 1.0); } else { // ---- Mode 1: SDF instanced quads ---- Primitive p = primitives[gl_InstanceIndex]; vec2 corner = v_position; // unit quad corners: (0,0)-(1,1) vec2 world_pos = mix(p.bounds.xy, p.bounds.zw, corner); vec2 center = 0.5 * (p.bounds.xy + p.bounds.zw); f_color = unpackUnorm4x8(p.color); f_local_or_uv = (world_pos - center) * dpi_scale; // shape-centered physical pixels f_params = p.params; f_params2 = p.params2; f_kind_flags = p.kind_flags; f_rotation = p.rotation; f_uv_rect = p.uv_rect; gl_Position = projection * vec4(world_pos * dpi_scale, 0.0, 1.0); } }