#version 330 core in vec2 vUv; uniform sampler2D uScene; uniform sampler2D uDepth; uniform int uStarCount; uniform float uAspect; uniform vec3 uStarPosition[2]; // UV position, logarithmic front depth uniform vec3 uStarShape[2]; // apparent radius, intensity, minimum core radius uniform vec3 uStarHalo[2]; // halo radius, halo strength, ray strength uniform vec3 uStarRays[2]; // ray length, ray count, ray sharpness uniform vec3 uStarGhosts[2]; // strength, spacing, chromatic aberration uniform vec3 uStarColors[2]; uniform float uStarRotation[2]; out vec4 fragColor; float starVisibility(int i) { vec2 center=uStarPosition[i].xy; if(any(lessThan(center,vec2(0)))||any(greaterThan(center,vec2(1))))return 0.0; float visible=0.0,total=0.0; for(int y=-1;y<=1;y++)for(int x=-1;x<=1;x++) { vec2 uv=center+vec2(x/uAspect,y)*uStarShape[i].x*.55; if(any(lessThan(uv,vec2(0)))||any(greaterThan(uv,vec2(1))))continue; float weight=(x==0 && y==0)?4.0:1.0; visible+=step(uStarPosition[i].z-.000002,texture(uDepth,uv).r)*texture(uScene,uv).a*weight;total+=weight; } return visible/max(1.0,total); } float aperture(vec2 p,float radius) { float angle=atan(p.y,p.x); float hex=cos(floor(.5+angle/1.04719755)*1.04719755-angle)*length(p); return (1.0-smoothstep(radius*.86,radius,hex))*.12+exp(-pow((hex-radius*.88)/(radius*.09),2.0))*.24; } vec3 sunGlare(int i) { float intensity=uStarShape[i].y*starVisibility(i); if(intensity<.00001)return vec3(0.0); vec2 metric=vec2(uAspect,1.0),center=uStarPosition[i].xy; vec2 p=(vUv-center)*metric; float r=length(p),angle=atan(p.y,p.x)+uStarRotation[i]; float core=max(uStarShape[i].z,uStarShape[i].x*.075); float halo=uStarHalo[i].x; float central=14.0*exp(-r*r/max(1e-12,core*core)); float glow=exp(-r/max(.0001,halo))*uStarHalo[i].y/(1.0+r/max(core*16.0,.0001)); float rays=pow(.5+.5*cos(angle*uStarRays[i].y),uStarRays[i].z); float smallRays=pow(.5+.5*cos(angle*(uStarRays[i].y+6.0)+1.1),uStarRays[i].z*1.5)*.25; float taper=exp(-r/max(.0001,uStarRays[i].x))/(1.0+r/max(core*5.0,.0001)); vec3 color=uStarColors[i]*(central+glow+(rays+smallRays)*taper*uStarHalo[i].z); vec2 axis=vec2(.5)-center; float axisLength=length(axis*metric); float ghostWeight=smoothstep(.025,.15,axisLength)*uStarGhosts[i].x; for(int ghost=0;ghost<6;ghost++) { float g=float(ghost); vec2 ghostCenter=center+axis*(.7+g*uStarGhosts[i].y); float radius=.013+.006*g; vec2 q=(vUv-ghostCenter)*metric; float chroma=uStarGhosts[i].z; vec3 tint=.45+.45*cos(vec3(.1,2.2,4.3)+g*1.37); vec3 spectral=vec3(aperture(q,radius*(1.0-chroma*.15)),aperture(q,radius),aperture(q,radius*(1.0+chroma*.15))); color+=spectral*tint*ghostWeight/(1.0+g*.3); } vec2 ringCenter=vec2(.5)+axis*.25; float ringDistance=length((vUv-ringCenter)*metric); float rainbow=exp(-pow((ringDistance-.27)/.012,2.0)); color+=rainbow*(.5+.5*cos(vec3(0,2,4)+ringDistance*160.0))*ghostWeight*.035; return color*intensity; } void main() { vec3 color=texture(uScene,vUv).rgb; for(int i=0;i<2;i++){if(i>=uStarCount)break;color+=sunGlare(i);} fragColor=vec4(color,1.0); }