#version 300 es layout(location = 0) in vec2 a_pos; layout(location = 1) in vec2 a_tex_coord; const float PI = 3.141592653589793; uniform mat4 u_projection_matrix; #define GLOBE_RADIUS 6371008.8 uniform highp vec4 u_projection_tile_mercator_coords; uniform highp vec4 u_projection_clipping_plane; uniform highp float u_projection_transition; uniform mat4 u_projection_fallback_matrix; vec3 globeRotateVector(vec3 vec,vec2 angles) { vec3 axisRight=vec3(vec.z,0.0,-vec.x); vec3 axisUp=cross(axisRight,vec); axisRight=normalize(axisRight); axisUp=normalize(axisUp); vec2 t=tan(angles); return normalize(vec+axisRight*t.x+axisUp*t.y); } mat3 globeGetRotationMatrix(vec3 spherePos) { vec3 axisRight=vec3(spherePos.z,0.0,-spherePos.x); vec3 axisDown=cross(axisRight,spherePos); axisRight=normalize(axisRight); axisDown=normalize(axisDown); return mat3(axisRight,axisDown,spherePos); } float circumferenceRatioAtTileY(float tileY) { float mercator_pos_y = u_projection_tile_mercator_coords.y + u_projection_tile_mercator_coords.w*tileY; float spherical_y = 2.0*atan(exp(PI-(mercator_pos_y*PI*2.0))) - PI*0.5;return cos(spherical_y); } float projectLineThickness(float tileY) { float thickness=1.0/circumferenceRatioAtTileY(tileY); if (u_projection_transition < 0.999) { return mix(1.0,thickness,u_projection_transition); } else { return thickness; } } vec3 projectToSphere(vec2 translatedPos,vec2 rawPos) { vec2 mercator_pos = u_projection_tile_mercator_coords.xy+u_projection_tile_mercator_coords.zw*translatedPos; vec2 spherical; spherical.x=mercator_pos.x*PI*2.0+PI; spherical.y=2.0*atan(exp(PI-(mercator_pos.y*PI*2.0)))-PI*0.5; float len=cos(spherical.y); vec3 pos=vec3(sin(spherical.x)*len,sin(spherical.y),cos(spherical.x)*len); if (rawPos.y <-32767.5) { pos = vec3(0.0,1.0,0.0); } if (rawPos.y > 32766.5) { pos=vec3(0.0,-1.0,0.0); } return pos; } vec3 projectToSphere(vec2 posInTile) { return projectToSphere(posInTile,vec2(0.0,0.0)); } float globeComputeClippingZ(vec3 spherePos) { return (1.0-(dot(spherePos,u_projection_clipping_plane.xyz)+u_projection_clipping_plane.w)); } vec4 interpolateProjection(vec2 posInTile,vec3 spherePos,float elevation) { vec3 elevatedPos=spherePos*(1.0+elevation/GLOBE_RADIUS); vec4 globePosition=u_projection_matrix*vec4(elevatedPos,1.0); globePosition.z=globeComputeClippingZ(elevatedPos)*globePosition.w; if (u_projection_transition > 0.999) {return globePosition;} vec4 flatPosition=u_projection_fallback_matrix*vec4(posInTile,elevation,1.0); const float z_globeness_threshold=0.2; vec4 result=globePosition;result.z=mix(0.0,globePosition.z,clamp((u_projection_transition-z_globeness_threshold)/(1.0-z_globeness_threshold),0.0,1.0));result.xyw=mix(flatPosition.xyw,globePosition.xyw,u_projection_transition);if ((posInTile.y <-32767.5) || (posInTile.y > 32766.5)) {result=globePosition;const float poles_hidden_anim_percentage=0.02;result.z=mix(globePosition.z,100.0,pow(max((1.0-u_projection_transition)/poles_hidden_anim_percentage,0.0),8.0));}return result;}vec4 interpolateProjectionFor3D(vec2 posInTile,vec3 spherePos,float elevation) {vec3 elevatedPos=spherePos*(1.0+elevation/GLOBE_RADIUS);vec4 globePosition=u_projection_matrix*vec4(elevatedPos,1.0); if (u_projection_transition > 0.999) {return globePosition;} vec4 fallbackPosition=u_projection_fallback_matrix*vec4(posInTile,elevation,1.0); return mix(fallbackPosition,globePosition,u_projection_transition); } vec4 projectTile(vec2 posInTile) { return interpolateProjection(posInTile,projectToSphere(posInTile),0.0); } vec4 projectTile(vec2 posInTile,vec2 rawPos) { return interpolateProjection(posInTile,projectToSphere(posInTile,rawPos),0.0); } vec4 projectTileWithElevation(vec2 posInTile,float elevation) { return interpolateProjection(posInTile,projectToSphere(posInTile),elevation); } vec4 projectTileFor3D(vec2 posInTile,float elevation) { vec3 spherePos=projectToSphere(posInTile,posInTile); return interpolateProjectionFor3D(posInTile,spherePos,elevation); } #define GLOBE out vec2 v_tex_coord; void main() { gl_Position = projectTile(a_pos); v_tex_coord = a_tex_coord; }