#version 450 #extension GL_ARB_separate_shader_objects : enable layout(set = 0, binding = 0) uniform NodeData { mat4 world; } node; layout(set = 1, binding = 0) uniform CameraData { mat4 viewProjection; mat4 view; mat4 projection; vec4 camPos; float nearPlane; float farPlane; float width; float height; float fov; float aspect; float scaleFactor; float pixelScaleFactor; } cam; layout(set = 4, binding = 0) uniform LabelData { vec4 color; vec2 textSize; vec2 bboxCenter; float radius; float arrowLength; float arrowWidth; bool hasRoundedCorners; bool hasArrow; bool isBillboardFixedSize; } labelInfo; layout(location = 0) out vec4 color; layout(location = 1) out vec2 textureCoordinates; // Background plane positions are in clipped space const vec4 PLANE[4] = vec4[]( vec4(-0.5, -0.5, 0, 1), vec4(0.5, -0.5, 0, 1), vec4(-0.5, 0.5, 0, 1), vec4(0.5, 0.5, 0, 1) ); const vec2 TEX_COORDS[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(0, 1), vec2(1, 1)); void main() { vec4 position = PLANE[gl_VertexIndex]; position.xy *= labelInfo.textSize; position.xy += labelInfo.bboxCenter; position.z = - 0.001; textureCoordinates = TEX_COORDS[gl_VertexIndex] * labelInfo.textSize; if (!labelInfo.isBillboardFixedSize) { mat4 mv = cam.view * node.world; mv[0][0] = 1; mv[0][1] = 0; mv[0][2] = 0; mv[1][0] = 0; mv[1][1] = 1; mv[1][2] = 0; mv[2][0] = 0; mv[2][1] = 0; mv[2][2] = 1; gl_Position = cam.projection * mv * vec4(position.xyz, 1); } else { vec4 billboardPos = vec4(0.5, 0.5, 0, 1); vec4 viewPos = cam.view * node.world * billboardPos; float dist = - viewPos.z; gl_Position = cam.projection * (viewPos + vec4(position.xy *dist * 0.2, 0, 0)); } }