// 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); }