blob: a9aab7a28ea19169390b2da7855cf0a21687ab85 [file] [log] [blame]
#version 450
#extension GL_ARB_separate_shader_objects : enable
// Untransformed vertex positions in clockwise order, starting
// at the top left corner.
vec2 positions[4] = vec2[](
vec2(0,0),
vec2(1,0),
vec2(1,1),
vec2(0,1)
);
// This shader avoids the need for binding index and vertex buffers; this array
// plays a key role.
//
// Index buffers are avoided by using vkCmdDraw() instead of vkCmdDrawIndexed().
// This array is used to remap gl_VertexIndex into the range [0-3], because a
// rectangle has 4 vertices, not 6.
//
// Vertex buffers are avoided by using the remapped index to look up the
// position/UV coords corresponding to the current vertex. Position coords
// are hardcoded into the shader, and UV coords are provided as push constants.
uint remapped_indices[6] = uint[](
0,1,2,0,2,3
);
// Push constants needed to render each RectangleRenderable.
layout(push_constant) uniform PushConstant {
// Normalizing bounds for the renderable.
// This is the only per-batch value; the others below
// are updated per-renderable.
layout(offset=0) vec3 bounds;
// Renderable origin (top-left corner).
layout(offset=16) vec3 origin;
// Width and height of the renderable.
layout(offset=32) vec2 extent;
// UV coords in clockwise order, starting at top left.
layout(offset=40) vec2 uvs[4];
};
// UV Coordinates used for the renderable texture in
// the fragment shader.
layout(location = 0) out vec2 outUVCoords;
// Use gl_VertexIndex to index into the hardcoded rectangle
// positions array. These positions are then transformed
// into clip-space based on the PushConstant data for a
// particular rectangle instance.
void main() {
const uint index = remapped_indices[gl_VertexIndex];
// Transform and normalize the position and output the
// result to gl_Position.
vec2 pos = positions[index] * extent + origin.xy;
vec3 clip_pos = vec3(pos.xy - bounds.xy, origin.z) / bounds;
gl_Position = vec4(clip_pos, 1.0);
// We copy to a local array because gl_VertexIndex isn't
// dynamically uniform, therefore neither is the remapped index,
// so it can't be used as an index into the push constant array.
vec2 local_uvs[4] = vec2[](uvs[0], uvs[1], uvs[2], uvs[3]);
outUVCoords = local_uvs[index];
}