// right-click: pause/start animation
// drag: rotate viewport
// fragment shader
// original: https://www.shadertoy.com/view/3dXfDr
float F(in vec3 p) {
p *= 0.5*(max(1.,10.*sin(4.0*iTime)-8.5)-max(0.,10.*cos(4.0*iTime-2.)-9.7))+0.5;
vec3 u = p*p;
float d = u.x+2.*u.y+u.z-1.;
if (d>3.0) return d;
return 4.*d*d-p.z*(5.*u.x*u.x-10.*u.x*u.z+u.z*u.z)-1.;
}
vec3 nGrad(vec3 p) {
const float e = 1e-5;
float a = F(p+vec3(e,e,e));
float b = F(p+vec3(e,-e,-e));
float c = F(p+vec3(-e,e,-e));
float d = F(p+vec3(-e,-e,e));
return vec3(a+b-c-d,a-b+c-d,a-b-c+d)*(.25/e);
}
const vec3 light = normalize(vec3(-0.3, 0.1, 1));
vec3 castRay(vec3 p, vec3 d) {
float t = 8., dt;
for (int i = 0; i < 128; i++) {
vec3 q = p+t*d;
dt = F(q) / length(nGrad(q));
t += 0.5*dt;
if (dt < .01) {
vec3 n = normalize(nGrad(q));
float dif = clamp(.3+.7*dot(n, light), 0., 1.);
vec3 col = vec3(1.0,0.9,0.9)-sqrt(q.y*q.y+0.5)*vec3(0.1,0.4,0.9);
return (0.7*dif+0.2*pow(max(dot(d, light),0.),4.)+.5)*col;
}
if (t > 15.) break;
}
vec3 col = sin(20.*d.x)+sin(20.*d.y)+sin(20.*d.z)>0.?vec3(0.6,0.8,1.0): vec3(0.8,0.6,1.0);
t = max(dot(d,light), 0.);
return (0.5+0.5*t)*col;
}
#define AA 1
void main() {
float rx = iRotate.x, rz = iRotate.y;
vec3 w = vec3(cos(rx)*vec2(-sin(rz),cos(rz)), sin(rx));
vec3 u=vec3(-cos(rz),-sin(rz),0);
vec3 v=cross(w,u);
mat3 M=-mat3(u,v,w);
vec3 pos = 10.0 * w;
vec3 col = vec3(0.0);
for (int i=0;i< AA;i++) for (int j=0;j< AA;j++) {
vec3 d=M*vec3(0.5*iResolution-(gl_FragCoord.xy+vec2(i,j)/float(AA)),length(iResolution));
col += clamp(castRay(pos,normalize(d)),vec3(0),vec3(1));
}
col/=float(AA*AA);
float gma = .7;
col.x=pow(col.x,gma),col.y=pow(col.y,gma),col.z=pow(col.z,gma);
col = col*1.1-0.1;
gl_FragColor = vec4(col,1.0);
}