#version 450 #extension GL_AMD_gpu_shader_int16 : enable layout(location = 0) in ivec2 position; layout(location = 1) in ivec2 normal; layout(location = 2) in uint feature; layout(location = 0) out vec4 outColor; layout(location = 1) out float d; layout(std140) struct LayerData { vec4 background_color; vec4 outline_color; float border_width; uint line_width; float z_index; }; layout(std140, set = 0, binding = 0) uniform Locals { vec2 canvas_size; vec2 _unused; LayerData layer_datas[1000]; }; layout(std140) struct TileData { mat4 transform; float extent; float _unused; float _unused2; float _unused3; }; layout(std140, set = 0, binding = 1) uniform Transform { TileData tile_datas[200]; }; void main() { // Are we handling an outline? bool is_outline = (gl_InstanceIndex & 0x01) == 0; // The current tile. uint tile_id = (gl_InstanceIndex >> 1); uint feature_id = feature & 0xFFFF; uint feature_type = (feature >> 16) & 0x3; // Shortcut the array indexing. LayerData layer_data = layer_datas[feature_id]; TileData tile_data = tile_datas[tile_id]; // Is the line we are currently handling sized in world coordinates or pixels? bool is_world_scale_line = (layer_data.line_width & 0x02) == 1; bool is_line = feature_type == 1; float line_width = layer_data.line_width >> 2; // Calculate the tile normal normal in [0.0, 1.0] coordinates. vec2 local_normal = normal / tile_data.extent; if(is_line) { d = sign(local_normal.y); } else { d = 0; } vec4 tile_local_position = vec4(position / tile_data.extent, 0.0, 1.0); // // If we have a world scale line, add the normal to the vertex before the world transform. // if(is_line && is_world_scale_line) { // vec2 n = local_normal / tile_data.extent * line_width; // tile_local_position.xy += n; // } // Transform the vertex. gl_Position = tile_data.transform * tile_local_position; // If we have a pixel scale line, add the normal to the vertex after the world transform. if(is_line && !is_world_scale_line) { gl_Position.xy += local_normal / canvas_size * line_width; } // If we handle an outline, add the normal to the vertex (always pixel space) and pick the appropriate color. if(is_outline){ gl_Position.xy += local_normal / canvas_size * layer_data.border_width * 2; outColor = layer_data.outline_color; } else { outColor = layer_data.background_color; } // Feather gl_Position.xy += local_normal / canvas_size * 2; gl_Position.z = layer_data.z_index / 1000 + 0.001; }