70 lines
3.2 KiB
GLSL
70 lines
3.2 KiB
GLSL
#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);
|
|
}
|