Pass 1 renders eight plasma sheets into an atlas with linear depth in alpha; pass 2 marches the refracted ray to each sheet and absorbs it by real path length, so near and far layers separate under pointer parallax. Plasma cycle repeats exactly every 30 s; - / = change speed.
39 lines
1.2 KiB
GLSL
39 lines
1.2 KiB
GLSL
precision highp float;
|
|
uniform vec2 u_res; uniform float u_time; uniform vec2 u_mouse;
|
|
float sdSphere(vec3 p,float r){return length(p)-r;}
|
|
float map(vec3 p){
|
|
float d=sdSphere(p,1.0);
|
|
for(int i=0;i<3;i++){
|
|
float fi=float(i);
|
|
vec3 q=p; float a=u_time*0.5+fi*2.1;
|
|
q.xz=mat2(cos(a),-sin(a),sin(a),cos(a))*q.xz;
|
|
d=min(d,sdSphere(q-vec3(0.75,0.0,0.0),0.34));
|
|
}
|
|
return d;
|
|
}
|
|
void main(){
|
|
vec2 uv=(gl_FragCoord.xy-0.5*u_res)/u_res.y;
|
|
vec3 ro=vec3(0.0,0.0,3.6), rd=normalize(vec3(uv,-1.6));
|
|
float tt=0.0; int hit=0;
|
|
for(int i=0;i<80;i++){
|
|
float d=map(ro+rd*tt);
|
|
if(d<0.001){hit=1;break;}
|
|
tt+=d;
|
|
if(tt>8.0)break;
|
|
}
|
|
vec3 col=vec3(0.03,0.04,0.07)+0.15*pow(1.0-abs(uv.y),3.0);
|
|
if(hit==1){
|
|
vec3 pos=ro+rd*tt;
|
|
vec3 n=normalize(vec3(map(pos+vec3(0.001,0,0))-map(pos-vec3(0.001,0,0)),
|
|
map(pos+vec3(0,0.001,0))-map(pos-vec3(0,0.001,0)),
|
|
map(pos+vec3(0,0,0.001))-map(pos-vec3(0,0,0.001))));
|
|
vec3 l=normalize(vec3(0.6,0.8,0.5));
|
|
float dif=max(dot(n,l),0.0);
|
|
float fre=pow(1.0-max(dot(n,-rd),0.0),3.0);
|
|
vec3 alb=0.5+0.5*cos(6.2831*(pos*0.6+vec3(0.0,0.33,0.67)));
|
|
col=alb*(0.15+0.85*dif)+vec3(0.6,0.8,1.0)*fre*1.2;
|
|
col*=0.9+0.1*sin(pos.y*40.0+u_time*4.0);
|
|
}
|
|
gl_FragColor=vec4(pow(col,vec3(0.4545)),1.0);
|
|
}
|