#version 430 core layout(location = 0) in vec2 aPos; // screen pixels, origin top-left layout(location = 1) in vec2 aUv; layout(location = 2) in vec4 aColor; // Campaign V slice V6d: uScreenSize moved into the pinned GpuPushConstants // block's two spare scalars — uParamA is the framebuffer width in pixels, // uParamB its height. Vulkan has no default uniform block, so a loose // `uniform vec2` cannot exist there; the block's fields are the only uniforms // a shader can read, and the two unclaimed scalars are exactly the right shape. // // The arithmetic below is byte-for-byte what it was: the same two divisions and // the same NDC mapping, reading two floats instead of one vec2. uniform float uParamA; uniform float uParamB; out vec2 vUv; out vec4 vColor; void main() { // Convert pixel coords (origin top-left, +Y down) to NDC (origin center, +Y up). // This is GL-convention NDC on both backends: the Vulkan backend renders with // a negative viewport height, so it consumes the same +Y-up clip space and no // renderer performs a flip of its own. vec2 ndc = vec2( aPos.x / uParamA * 2.0 - 1.0, 1.0 - aPos.y / uParamB * 2.0); gl_Position = vec4(ndc, 0.0, 1.0); vUv = aUv; vColor = aColor; }