{"starVertex":"precision highp float;uniform mat4 projectionMatrix;uniform mat3 uView;uniform float uPixelRatio;uniform float uViewScale;uniform float uFovDeg;uniform float uNightMode;attribute vec3 position;attribute vec3 color;attribute vec3 tint;attribute vec2 light;attribute float size;varying vec3 vColor;varying float vAmp;varying float vSpike;uniform vec2 uSkyProjection;float skyPerspectiveRadius(float theta,float d){return(1.0 + d)*sin(theta)/(d + cos(theta));}vec3 skyWarpView(vec3 mv){float d=uSkyProjection.x;if(d<=0.0)return mv;float dist=length(mv);float r=length(mv.xy);float theta=atan(r,-mv.z);if(d + cos(theta)<0.02)return vec3(0.0,0.0,dist);float s=uSkyProjection.y;float t=skyPerspectiveRadius(theta,d)/skyPerspectiveRadius(s,d)*tan(s);float k=r>1e-12?t*dist/r:0.0;return vec3(mv.xy*k,-dist);}vec4 skyProject(vec4 mv){return projectionMatrix*vec4(skyWarpView(mv.xyz),1.0);}const float STAR_EXPOSURE=0.62;float starAmplitude(float m){float a=pow(10.0,-0.4*(m - 2.7)*0.42);return max(a/(1.0 + a/3.0),0.16);}float starZoomScale(float fovDeg){return clamp(pow(clamp(fovDeg,4.0,85.0)/75.0,0.25),0.56,1.06);}float starMagnification(float fovDeg){return clamp(pow(30.0/max(fovDeg,1.0),0.5),1.0,1.5);}float starSpritePx(float basePx,float fovDeg){float zoom=starZoomScale(fovDeg);float grow=starMagnification(fovDeg);float knee=5.0*grow;float px=basePx*grow;return px<=knee?px:knee +(px - knee)*zoom/grow;}float starSpike(float appMag){return clamp((2.6 - appMag)/3.2,0.0,1.0);}float starSprite(float size,float spike,float magGain,float fovDeg){float gained=min(size*min(pow(10.0,0.05*magGain),1.3),5.2);return max(starSpritePx(gained*2.4*(1.0 + spike*0.7),fovDeg),3.0);}vec3 starChroma(vec3 rgb,float appMag){float lum=dot(rgb,vec3(0.2126,0.7152,0.0722));float k=mix(0.18,1.0,1.0 - smoothstep(0.4,4.8,appMag))*(1.0 + 0.8*(1.0 - smoothstep(0.0,2.5,appMag)));float least=min(rgb.r,min(rgb.g,rgb.b));if(k>1.0&&least<lum)k=min(k,max(1.0,0.9*lum/(lum - least)));return mix(vec3(lum),rgb,k);}uniform vec4 uSlew;uniform vec2 uViewport;varying float vRadiusPx;varying vec2 vSigmaPx;varying vec2 vSpreadGain;varying vec3 vStreak;varying vec3 vStreakNorm;varying vec3 vGlare;float starErf(float x){float t=1.0/(1.0 + 0.3275911*x);return 1.0 - t*(0.254829592 + t*(-0.284496736 + t*(1.421413741 + t*(-1.453152027 + t*1.061405429))))*exp(-x*x);}float starStreakNorm(float sigma,float radius,float len,float ramp){float disc=1.0 - exp(-(radius*radius)/(2.0*sigma*sigma));float body=0.7978845608028654*starErf(radius/(1.4142135623730951*sigma))/(sigma*disc);return 2.0/((2.0 - ramp)+ body*len*(1.0 - 0.5*ramp));}vec2 starGlareOf(float lit){float t=clamp((2.0 - lit)/2.5,0.0,1.0);return vec2(t,mix(4.0,10.0,t));}float starSpread(float px){vec2 meant=vec2(0.25,0.5)*(0.5*px);vSigmaPx=max(meant,0.65);vSpreadGain=(meant/vSigmaPx)*(meant/vSigmaPx);float drawn=max(px,4.0);vRadiusPx=0.5*drawn;vGlare=vec3(1.0,0.0,1.0);return drawn;}float starGlare(float drawn,float lit,float cssPx,float night){vec2 glare=starGlareOf(lit);float w=0.08*glare.x*(1.0 - night);if(w<=0.0)return drawn;float sigma=glare.y*cssPx;float grown=max(drawn,6.0*sigma);vGlare=vec3(sigma,w,grown/drawn);vRadiusPx=0.5*grown;return grown;}float starStreak(float drawn,vec3 mv,float amp,float pixelRatio,inout vec4 clip){vStreak=vec3(0.0);vStreakNorm=vec3(1.0,1.0,0.0);if(uSlew==vec4(0.0)||amp<=0.0016||clip.w<=0.0)return drawn;vec4 then=skyProject(vec4(mv + cross(uSlew.xyz,mv),1.0));if(then.w<=0.0)return drawn;vec4 axis=projectionMatrix*vec4(0.0,0.0,-1.0,1.0);vec2 centre=axis.xy/axis.w;vec2 now=clip.xy/clip.w;vec2 was=centre +(then.xy/then.w - centre)*exp(uSlew.w);vec2 tail=(was - now)*0.5*uViewport;float raw=length(tail);float rest=drawn/vGlare.z;float len=min(raw*smoothstep(1.5,4.0,raw/pixelRatio),rest*1.0);if(len<0.01)return drawn;tail*=len/raw;clip.xy +=tail/uViewport*clip.w;float ramp=0.75*min(1.0,len/(rest*1.0));vStreak=vec3(tail.x,-tail.y,0.5*(drawn + len));vStreakNorm=vec3(starStreakNorm(vSigmaPx.x,vRadiusPx,len,ramp),starStreakNorm(vSigmaPx.y,vRadiusPx,len,ramp),ramp);return drawn + len;}void main(){float appMag=light.x;vAmp=starAmplitude(appMag)*light.y;vColor=starChroma(color,appMag)*tint*STAR_EXPOSURE;vSpike=starSpike(appMag);float drawn=starSpread(starSprite(size,vSpike,0.0,uFovDeg)*uPixelRatio*uViewScale);if(vAmp>0.0016)drawn=starGlare(drawn,appMag,uPixelRatio*uViewScale,uNightMode);vec3 mv=uView*position*500.0;vec4 clip=skyProject(vec4(mv,1.0));gl_PointSize=starStreak(drawn,mv,vAmp,uPixelRatio,clip);gl_Position=clip;}","starFragment":"precision highp float;uniform float uNightMode;varying vec3 vColor;varying float vAmp;varying float vSpike;varying float vRadiusPx;varying vec2 vSigmaPx;varying vec2 vSpreadGain;varying vec3 vStreak;varying vec3 vStreakNorm;varying vec3 vGlare;float starGlareAt(float d2){return vGlare.y>0.0?vGlare.y*exp(-d2/(2.0*vGlare.x*vGlare.x)):0.0;}float starPsf(vec2 coord){float d2=dot(coord,coord)*vRadiusPx*vRadiusPx;return vSpreadGain.x*exp(-d2/(2.0*vSigmaPx.x*vSigmaPx.x))+ 0.14*vSpreadGain.y*exp(-d2/(2.0*vSigmaPx.y*vSigmaPx.y))+ starGlareAt(d2);}vec2 starHead(vec2 coord){return(vStreak.z<=0.0?coord:(coord*vStreak.z + 0.5*vStreak.xy)/vRadiusPx)*vGlare.z;}float starLight(vec2 coord){if(vStreak.z<=0.0)return starPsf(coord);vec2 p=coord*vStreak.z + 0.5*vStreak.xy;float t=clamp(dot(p,vStreak.xy)/dot(vStreak.xy,vStreak.xy),0.0,1.0);vec2 off=p - t*vStreak.xy;float d2=dot(off,off);if(d2>vRadiusPx*vRadiusPx)discard;return(1.0 - vStreakNorm.z*t)*(vSpreadGain.x*vStreakNorm.x*exp(-d2/(2.0*vSigmaPx.x*vSigmaPx.x))+ 0.14*vSpreadGain.y*vStreakNorm.y*exp(-d2/(2.0*vSigmaPx.y*vSigmaPx.y)))+ starGlareAt(dot(p,p));}float starSpikes(vec2 coord,float spike){if(spike<=0.01)return 0.0;vec2 h=starHead(coord);float w=0.055;vec2 d=vec2(h.x + h.y,h.x - h.y)*0.70711;float s=max(max(exp(-h.y*h.y/w)*(1.0 - abs(h.x)),exp(-h.x*h.x/w)*(1.0 - abs(h.y))),max(exp(-d.y*d.y/w)*(1.0 - abs(d.x))*0.6,exp(-d.x*d.x/w)*(1.0 - abs(d.y))*0.6));return max(s,0.0)*spike*spike*0.30*(vStreak.z>0.0?vStreakNorm.x:1.0);}vec3 bootTone(vec3 c,float night){float top=mix(1.0,0.5,night);float m=max(c.r,max(c.g,c.b));float knee=0.6*top;if(m<=knee)return c;float span=top - knee;return c*((knee + span*(1.0 - exp(-(m - knee)/span)))/m);}void main(){if(vAmp<=0.0016)discard;vec2 coord=(gl_PointCoord - 0.5)*2.0;if(length(coord)>1.0)discard;float psf=starLight(coord)+ starSpikes(coord,vSpike);vec3 rgb=vColor*vAmp*psf;float nightLum=dot(rgb,vec3(0.299,0.587,0.114));rgb=bootTone(mix(rgb,vec3(nightLum,0.0,0.0),uNightMode),uNightMode);rgb=clamp(rgb,0.0,1.0);vec3 srgb=mix(rgb*12.92,1.055*pow(rgb,vec3(1.0/2.4))- 0.055,step(0.0031308,rgb));gl_FragColor=vec4(srgb,max(srgb.r,max(srgb.g,srgb.b)));}","lineVertex":"precision highp float;uniform mat4 projectionMatrix;uniform mat3 uView;uniform mat3 uSky;uniform vec2 uViewport;attribute vec3 position;attribute vec3 other;attribute vec2 corner;attribute float ext;varying float vExt;varying float vAlong;varying float vLength;varying float vHeight;uniform vec2 uSkyProjection;float skyPerspectiveRadius(float theta,float d){return(1.0 + d)*sin(theta)/(d + cos(theta));}vec3 skyWarpView(vec3 mv){float d=uSkyProjection.x;if(d<=0.0)return mv;float dist=length(mv);float r=length(mv.xy);float theta=atan(r,-mv.z);if(d + cos(theta)<0.02)return vec3(0.0,0.0,dist);float s=uSkyProjection.y;float t=skyPerspectiveRadius(theta,d)/skyPerspectiveRadius(s,d)*tan(s);float k=r>1e-12?t*dist/r:0.0;return vec3(mv.xy*k,-dist);}vec4 skyProject(vec4 mv){return projectionMatrix*vec4(skyWarpView(mv.xyz),1.0);}void main(){vHeight=mix((uSky*position).y,(uSky*other).y,corner.x);vExt=ext;vec4 p=skyProject(vec4(uView*position*500.0,1.0));vec4 q=skyProject(vec4(uView*other*500.0,1.0));if(p.w<=0.0||q.w<=0.0){gl_Position=vec4(2.0,2.0,2.0,1.0);return;}vec2 a=p.xy/p.w*0.5*uViewport;vec2 b=q.xy/q.w*0.5*uViewport;vec2 dir=normalize(b - a + 1e-6);vLength=length(b - a);vAlong=corner.x*vLength;vec2 at=mix(a,b,corner.x)+ vec2(-dir.y,dir.x)*corner.y*0.65;gl_Position=vec4(at/(0.5*uViewport),0.0,1.0);}","lineFragment":"precision highp float;uniform vec3 uInk;varying float vAlong;varying float vLength;varying float vHeight;varying float vExt;void main(){if(vHeight<0.0)discard;float end=min(vAlong,vLength - vAlong);vec3 lin=uInk*smoothstep(4.0,10.0,end)*vExt;if(lin.r + lin.g + lin.b<=0.0)discard;vec3 srgb=mix(lin*12.92,1.055*pow(lin,vec3(1.0/2.4))- 0.055,step(0.0031308,lin));gl_FragColor=vec4(srgb,max(srgb.r,max(srgb.g,srgb.b)));}"}