// please zoom for details // 2160x2160
#define PI 3.141592653589793 #define TWO_PI 6.283185307179586 #define MAX_STEPS 64 #define DISTANCE_THRESHOLD 0.0001
float sphere(in vec3 p, in float r) { return length(p) - r; }
float plane(vec3 p, float height) { return p.z - height; }
float box(in vec3 p, in vec3 b) { vec3 q = abs(p) - b; return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0); }
float f( in vec3 p ) { float spacing = 2.0 * PI / 3.0;
vec3 sp0 = vec3(0.5, 0.5, 0.5);
vec3 w = vec3( fract(p.x / 4.0), fract(p.y / 4.0), fract(p.z / 4.0) );
float t = 1.0 / 16.0;
float v = 1.0 / 16.0;
float l = 3.0 / 16.0;
float d = box(sp0 - w, vec3(l, t, t));
d = min(d, box(sp0 - w, vec3(t, l, t)));
d = min(d, box(sp0 - w, vec3(t, t, l)));
return d;
}
vec3 get_normal( in vec3 p ) { // sample along 3 axes to get a normal
const float o = 0.0009765625;
float c = f(p);
const vec2 h = vec2(o, 0);
return normalize(vec3( f(p + h.xyy) - c,
f(p + h.yxy) - c,
f(p + h.yyx) - c) );
}
float cast_ray(inout vec3 p, in vec3 h) {
float depth = 0.0;
float d;
for (int a = 0; a < MAX_STEPS; a ++) {
d = f(p);
p += d * h;
depth += d;
if (d < DISTANCE_THRESHOLD) {
break;
}
}
return d;
}
int seed = 1; void srand(int s ) { seed = s; } int rand(void) { seed=seed*0x343fd+0x269ec3; return (seed>>16)&32767; } float frand(void) { return float(rand())/32767.0; }
int hash( int n ) { n=(n<<13)^n; return n*(nn15731+789221)+1376312589; }
vec3 spherical() { float z = frand() * 2.0 - 1.0; float angle = TWO_PI * frand(); return vec3( sqrt(1.0 - zz) * cos(angle), sqrt(1.0 - zz) * sin(angle), z ); }
void mainImage( out vec4 fragColor, in vec2 fragCoord ) { ivec2 q = ivec2(gl_FragCoord); srand(hash(q.x + hash(q.y + hash(int(1000.0 * iTime)))));
vec2 uv = 1.0 * (gl_FragCoord.xy - 0.5 * iResolution.xy) / iResolution.y;
float pitch = PI * 1.0 / 3.0 * sin(0.021193 * iTime);
float heading = PI * sin(0.082315 * iTime);
vec3 pos = vec3(iTime + 1.0, iTime, iTime + 3.0);
pos = 4.0 * vec3( fract( 0.25 * pos.x ),
fract( 0.25 * pos.y ),
fract( 0.25 * pos.z ) );
vec3 h = vec3( cos(heading) * cos(pitch),
sin(heading) * cos(pitch),
sin(pitch));
vec3 x_in_screen = vec3(0.0, 0.0, 1.0); // z axis
h = -normalize(h);
vec3 i = cross(h, x_in_screen); // x in screen
vec3 j = cross(i, h); // y in screen
h += i * uv.x; h += j * uv.y;
normalize(h);
vec3 light = vec3(0.5, 0.25, 0.5);
normalize(light);
float d = cast_ray(pos, h);
vec3 normal = get_normal(pos);
float s = 1.0;
for (float i = 0.0; i < 1.0; i += 0.25) {
float occlusion_offset = 0.1 * i * i;
s -= 32.0 * clamp(0.25 * ( (occlusion_offset + d)
- f(pos + occlusion_offset * normal) ),
0.0, 1.0);
}
float value = 0.25 * dot(h, normal);
float fog = (1.0 - 1.0 / (length(pos) * 0.005 + 1.0));
value += 1.0 / 8.0 * (frand() - 0.5);
value = value * s + fog;
fragColor = vec4( value, value, value, 1.0 );
}