#extension GL_OES_standard_derivatives : enable precision highp float; uniform float time; uniform vec2 mouse; uniform vec2 resolution; /* Created by soma_arc - 2021 This work is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported. */ // from Syntopia http://blog.hvidtfeldts.net/index.php/2015/01/path-tracing-3d-fractals/ vec2 rand2n(vec2 co, float sampleIndex) { vec2 seed = co * (sampleIndex + 1.0); seed+=vec2(-1,1); // implementation based on: lumina.sourceforge.net/Tutorials/Noise.html return vec2(fract(sin(dot(seed.xy ,vec2(12.9898,78.233))) * 43758.5453), fract(cos(dot(seed.xy ,vec2(4.898,7.23))) * 23421.631)); } struct Plane{ vec3 p1; vec3 p2; vec3 p3; vec3 normal; }; const vec3 BLACK = vec3(0); const vec3 RED = vec3(1, 0, 0); const vec3 LIGHT_POS = vec3(100, 100, 100); const vec3 LIGHT_DIR = normalize(LIGHT_POS); const float AMBIENT_FACTOR = 0.1; const float EPSILON = 0.001; const float PI = 3.14159265; const float PI_2 = 3.14159265 / 2.; const float RT_3 = sqrt(3.); const float RT_3_INV = 1.0 / sqrt(3.); const Plane PL1 = Plane(vec3(0, 5, RT_3_INV), vec3(1, 1, 0), vec3(2, 2, -RT_3_INV), normalize(vec3(RT_3 * 0.5, 0, 1.5))); const Plane PL2 = Plane(vec3(0, 3, -RT_3_INV), vec3(1, 3, 0), vec3(2, 2, RT_3_INV), normalize(vec3(RT_3 * 0.5, 0, -1.5))); const Plane PL3 = Plane( vec3(-0.5, 0, 1), vec3(-0.5, 1, 0), vec3(-0.5, 2, 1), vec3(-1, 0, 0)); vec4 s2, s4, s6; vec4 s2A, s4A, s6A; vec4 s2B, s4B, s6B; vec4 s2C, s4C, s6C; vec4 gSpheres0, gSpheres1, gSpheres2, gSpheres3, gSpheres4, gSpheres5; vec4 inversionSphere; vec3 vertexes0, vertexes1, vertexes2, vertexes3, vertexes4,vertexes5, vertexes6, vertexes7; Plane dividePlane; vec4 convexSphere; float gInvNum = 0.; float gBoundingPlaneY = -9999999999.; const float DISPLAY_GAMMA_COEFF = 1. / 2.2; vec3 gammaCorrect(vec3 rgb) { return vec3((min(pow(rgb.r, DISPLAY_GAMMA_COEFF), 1.)), (min(pow(rgb.g, DISPLAY_GAMMA_COEFF), 1.)), (min(pow(rgb.b, DISPLAY_GAMMA_COEFF), 1.))); } vec3 Hsv2rgb(float h, float s, float v){ vec3 c = vec3(h, s, v); const vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); } void computeCubeSphairahedronA(float zb, float zc) { float r2 = 0.5 + (zb * zc) / 3.0; float r4 = 0.5 + (zb * zb - zb * zc) / 3.0; float r6 = 0.5 + (-zb * zc + zc * zc) / 3.0; s2 = s2A = vec4(1. - r2, 0, 0, r2); s4 = s4A = vec4(-(1. - r4) * 0.5, zb, sqrt(3.) * (1. - r4) * 0.5, r4); s6 = s6A = vec4(-(1. - r6) * 0.5, zc, -sqrt(3.) * (1. - r6) * 0.5, r6); inversionSphere = vec4(-s6.x, -s6.y, s6.z, s6.w); } void computeCubeSphairahedronB(float zb, float zc) { float r2 = (3. * RT_3 + 2. * RT_3 * zb * zc) / 9.0; float r4 = (3. * zb * zb - 4. * zb * zc + 3.) / 9.0; float r6 = (3. * zc * zc - 2. * zb * zc + 6.) / 9.0; s2 = s2B = vec4((2. - RT_3 * r2) * 0.5, 0, r2 * 0.5, r2); s4 = s4B = vec4(-(1. - r4) * 0.5, zb, RT_3 * (1. - r4) * 0.5, r4); s6 = s6B = vec4(-(1. - r6) * 0.5, zc, -RT_3 * (1. - r6) * 0.5, r6); inversionSphere = vec4(-s6.x, -s6.y, s6.z, s6.w); } void computeCubeSphairahedronC(float zb, float zc) { float r2 = (zb * zb + 2. * zb * zc + 6.) / (5. * RT_3); float r4 = (3. * zb * zb - 4. * zb * zc + 3.) / (5. * RT_3); float r6 = (-zb * zb - 2. * zb * zc + 5. * zc * zc + 9.) / 15.0; s2 = s2C = vec4((2. - RT_3 * r2) * 0.5, 0, r2 * 0.5, r2); s4 = s4C = vec4(-0.5, zb, RT_3 / 2. - r4, r4); s6 = s6C = vec4(-(1. - r6) * 0.5, zc, -RT_3 * (1. - r6) * 0.5, r6); inversionSphere = vec4(-s6.x, -s6.y, s6.z, s6.w); } float MAX_FLOAT = 1e20; const float THRESHOLD = 0.001; bool intersectBoundingPlane(const vec3 n, const vec3 p, const vec3 rayOrigin, const vec3 rayDir, inout float t0, inout float t1) { float d = -dot(p, n); float v = dot(n, rayDir); float t = -(dot(n, rayOrigin) + d) / v; if(THRESHOLD < t){ if(v < 0.) { t0 = max(t, t0); t1 = MAX_FLOAT; } else { t0 = t0; t1 = t; } return true; } t0 = t0; t1 = MAX_FLOAT; return (v < 0.); } /* float[12] pivoting(float[12] mat, int n, int k){ int col = k; float maxValue = abs(mat[k*4 + k]); for (int i = k + 1; i < n; i++) { if (abs(mat[i*4 + k]) > maxValue) { col = i; maxValue = abs(mat[i*4 + k]); } } if (k != col) { float tmp[4]; tmp[0] = mat[col*4 + 0]; tmp[1] = mat[col*4 + 1]; tmp[2] = mat[col*4 + 2]; tmp[3] = mat[col*4 + 3]; mat[col*4 + 0] = mat[k*4 + 0]; mat[col*4 + 1] = mat[k*4 + 1]; mat[col*4 + 2] = mat[k*4 + 2]; mat[col*4 + 3] = mat[k*4 + 3]; mat[k*4 + 0] = tmp[0]; mat[k*4 + 1] = tmp[1]; mat[k*4 + 2] = tmp[2]; mat[k*4 + 3] = tmp[3]; } return mat; } */ vec4 sphereFromPoints(vec3 p0, vec3 p1, vec3 p2, vec3 p3){ /* float coefficient[12]; for (int i = 0; i < 3; i++) { coefficient[i * 4 + 0] = 2. * (p[i + 1].x - p[i].x); coefficient[i * 4 + 1] = 2. * (p[i + 1].y - p[i].y); coefficient[i * 4 + 2] = 2. * (p[i + 1].z - p[i].z); coefficient[i * 4 + 3] = -(pow(p[i].x, 2.) + pow(p[i].y, 2.) + pow(p[i].z, 2.)) + pow(p[i + 1].x, 2.) + pow(p[i + 1].y, 2.) + pow(p[i + 1].z, 2.); } */ float coefficient0, coefficient1, coefficient2, coefficient3, coefficient4; float coefficient5, coefficient6, coefficient7, coefficient8, coefficient9; float coefficient10, coefficient11; coefficient0 = 2. * (p1.x - p0.x); coefficient1 = 2. * (p1.y - p0.y); coefficient2 = 2. * (p1.z - p0.z); coefficient3 = -(pow(p0.x, 2.) + pow(p0.y, 2.) + pow(p0.z, 2.)) + pow(p1.x, 2.) + pow(p1.y, 2.) + pow(p1.z, 2.); coefficient4 = 2. * (p2.x - p1.x); coefficient5 = 2. * (p2.y - p1.y); coefficient6 = 2. * (p2.z - p1.z); coefficient7 = -(pow(p1.x, 2.) + pow(p1.y, 2.) + pow(p1.z, 2.)) + pow(p2.x, 2.) + pow(p2.y, 2.) + pow(p2.z, 2.); coefficient8 = 2. * (p3.x - p2.x); coefficient9 = 2. * (p3.y - p2.y); coefficient10 = 2. * (p3.z - p2.z); coefficient11 = -(pow(p2.x, 2.) + pow(p2.y, 2.) + pow(p2.z, 2.)) + pow(p3.x, 2.) + pow(p3.y, 2.) + pow(p3.z, 2.); /* const int n = 3; for (int k = 0; k < n - 1; k++) { coefficient = pivoting(coefficient, n, k); float vkk = coefficient[k * 4 + k]; for (int i = k + 1; i < n; i++) { float vik = coefficient[i * 4 + k]; for (int j = k; j < n + 1; ++j) { coefficient[i * 4 + j] = coefficient[i*4 + j] - vik * (coefficient[k * 4 + j] / vkk); } } } coefficient[(n - 1) * 4 + n] = coefficient[(n - 1) * 4 + n] / coefficient[(n - 1) * 4 + n - 1]; for (int i = n - 2; i >= 0; i--) { float acc = 0.0; for (int j = i + 1; j < n; j++) { acc += coefficient[i * 4 + j] * coefficient[j * 4 + n]; } coefficient[i * 4 + n] = (coefficient[i * 4 + n] - acc) / coefficient[i * 4 + i]; } */ //coefficient = pivoting(coefficient, 3, 0); int col = 0; float maxValue = abs(coefficient0); if (abs(coefficient4) > maxValue) { col = 1; maxValue = abs(coefficient4); } if (abs(coefficient8) > maxValue) { col = 2; maxValue = abs(coefficient8); } if (col == 1) { float tmp0 = coefficient4; float tmp1 = coefficient5; float tmp2 = coefficient6; float tmp3 = coefficient7; coefficient4 = coefficient0; coefficient5 = coefficient1; coefficient6 = coefficient2; coefficient7 = coefficient3; coefficient0 = tmp0; coefficient1 = tmp1; coefficient2 = tmp2; coefficient3 = tmp3; } if (col == 2) { float tmp0 = coefficient8; float tmp1 = coefficient9; float tmp2 = coefficient10; float tmp3 = coefficient11; coefficient8 = coefficient0; coefficient9 = coefficient1; coefficient10 = coefficient2; coefficient11 = coefficient3; coefficient0 = tmp0; coefficient1 = tmp1; coefficient2 = tmp2; coefficient3 = tmp3; } float vkk = coefficient0; float vik = coefficient4; coefficient4 = coefficient4 - vik * (coefficient0 / vkk); coefficient5 = coefficient5 - vik * (coefficient1 / vkk); coefficient6 = coefficient6 - vik * (coefficient2 / vkk); coefficient7 = coefficient7 - vik * (coefficient3 / vkk); vik = coefficient8; coefficient8 = coefficient8 - vik * (coefficient0 / vkk); coefficient9 = coefficient9 - vik * (coefficient1 / vkk); coefficient10 = coefficient10 - vik * (coefficient2 / vkk); coefficient11 = coefficient11 - vik * (coefficient3 / vkk); //coefficient = pivoting(coefficient, 3, 1); col = 1; maxValue = abs(coefficient5); if (abs(coefficient9) > maxValue) { col = 2; maxValue = abs(coefficient9); } if (col == 2) { float tmp0 = coefficient8; float tmp1 = coefficient9; float tmp2 = coefficient10; float tmp3 = coefficient11; coefficient8 = coefficient4; coefficient9 = coefficient5; coefficient10 = coefficient6; coefficient11 = coefficient7; coefficient4 = tmp0; coefficient5 = tmp1; coefficient6 = tmp2; coefficient7 = tmp3; } vkk = coefficient5; vik = coefficient9; coefficient9 = coefficient9 - vik * (coefficient5 / vkk); coefficient10 = coefficient10 - vik * (coefficient6 / vkk); coefficient11 = coefficient11 - vik * (coefficient7 / vkk); coefficient11 = coefficient11 / coefficient10; float acc = 0.0; acc += coefficient6 * coefficient11; coefficient7 = (coefficient7 - acc) / coefficient5; acc = 0.0; acc += coefficient1 * coefficient7; acc += coefficient2 * coefficient11; coefficient3 = (coefficient3 - acc) / coefficient0; //vec3 center = vec3(coefficient[0 * 4 + 3], coefficient[1 * 4 + 3], coefficient[2 * 4 + 3]); vec3 center = vec3(coefficient3, coefficient7, coefficient11); float r = length(center - p0); return vec4(center, r); } vec3 invertOnPoint(vec4 sphere, vec3 p) { vec3 d = p - sphere.xyz; float len = length(d); return d * (sphere.r * sphere.r / (len * len)) + sphere.xyz; } vec4 invertOnSphere(vec4 invSphere, vec4 s) { float r = s.w; float coeffR = r * RT_3 / 3.; vec3 p1 = invertOnPoint(invSphere, s.xyz + vec3(coeffR, coeffR, coeffR)); vec3 p2 = invertOnPoint(invSphere, s.xyz + vec3(-coeffR, -coeffR, -coeffR)); vec3 p3 = invertOnPoint(invSphere, s.xyz + vec3(coeffR, -coeffR, -coeffR)); vec3 p4 = invertOnPoint(invSphere, s.xyz + vec3(coeffR, coeffR, -coeffR)); return sphereFromPoints(p1, p2, p3, p4); } vec4 invertOnPlane(vec4 invSphere, Plane p) { return sphereFromPoints(invertOnPoint(invSphere, p.p1), invertOnPoint(invSphere, p.p2), invertOnPoint(invSphere, p.p3), invSphere.xyz); } void computeGSpheres(){ gSpheres0 = invertOnPlane(inversionSphere, PL1); gSpheres1 = invertOnSphere(inversionSphere, s2); gSpheres2 = invertOnPlane(inversionSphere, PL2); gSpheres3 = invertOnSphere(inversionSphere, s4); gSpheres4 = invertOnPlane(inversionSphere, PL3); gSpheres5 = invertOnSphere(inversionSphere, s6); } vec3 computeVertex(vec4 a, vec4 b, vec4 c) { float AB = (dot(a.xyz, a.xyz) - dot(b.xyz, b.xyz) - a.w * a.w + b.w * b.w) * 0.5 - dot(a.xyz, a.xyz) + dot(a.xyz, b.xyz); float AC = (dot(a.xyz, a.xyz) - dot(c.xyz, c.xyz) - a.w * a.w + c.w * c.w) * 0.5 - dot(a.xyz, a.xyz) + dot(a.xyz, c.xyz); float x = -dot(a.xyz, a.xyz) - dot(b.xyz, b.xyz) + 2. * dot(a.xyz, b.xyz); float y = -dot(a.xyz, a.xyz) - dot(c.xyz, c.xyz) + 2. * dot(a.xyz, c.xyz); float z = -dot(a.xyz, a.xyz) + dot(a.xyz, b.xyz) + dot(a.xyz, c.xyz) - dot(b.xyz, c.xyz); float s = (AB * y - AC * z) / (x * y - z * z); float t = (AC * x - AB * z) / (x * y - z * z); return a.xyz + (b.xyz - a.xyz) * s + (c.xyz - a.xyz) * t; } /* 0, 1, 2, 0, 3, 4, 2, 4, 5, 0, 1, 3, 3, 4, 5, 1, 2, 5, 1, 3, 5, 0, 2, 4 */ void computeVertexes(){ vertexes0 = computeVertex(gSpheres0, gSpheres1, gSpheres2); vertexes1 = computeVertex(gSpheres0, gSpheres3, gSpheres4); vertexes2 = computeVertex(gSpheres2, gSpheres4, gSpheres5); vertexes3 = computeVertex(gSpheres0, gSpheres1, gSpheres3); vertexes4 = computeVertex(gSpheres3, gSpheres4, gSpheres5); vertexes5 = computeVertex(gSpheres1, gSpheres2, gSpheres5); vertexes6 = computeVertex(gSpheres1, gSpheres3, gSpheres5); vertexes7 = computeVertex(gSpheres0, gSpheres2, gSpheres4); /* for(int i = 0; i < 8; i++) { vertexes[i] = computeVertex(gSpheres[index[i*3 + 0]], gSpheres[index[i*3 + 1]], gSpheres[index[i*3 + 2]]); } */ } Plane computePlane() { vec3 p1 = invertOnPoint(inversionSphere, vertexes0); vec3 p2 = invertOnPoint(inversionSphere, vertexes1); vec3 p3 = invertOnPoint(inversionSphere, vertexes2); vec3 v1 = p2 - p1; vec3 v2 = p3 - p1; vec3 normal = normalize(cross(v1, v2)); if (normal.y < 0.) { normal = normal * -1.; } Plane p = Plane(p1, p2, p3, normal); return p; } vec4 computeConvexSphere(){ return invertOnPlane(inversionSphere, dividePlane); } // p: center of the plane // n: normal of the plane bool intersectPlane(vec3 p, vec3 n, vec3 rayOrigin, vec3 rayDir, inout float minDist, inout vec3 intersection, inout vec3 normal){ float d = -dot(p, n); float v = dot(n, rayDir); float t = -(dot(n, rayOrigin) + d) / v; if(EPSILON < t && t < minDist){ intersection = rayOrigin + t * rayDir; normal = n; minDist = t; return true; } return false; } vec2 opUnion(vec2 d1, vec2 d2) { return (d1.x < d2.x) ? d1 : d2; } float distSphere(vec3 p, vec4 sphere){ return distance(p, sphere.xyz) - sphere.w; } float distPlane(vec3 pos, vec3 p, vec3 n) { return dot(pos - p, n); } float distPrism(const vec3 pos) { float d = -1.; d = max(distPlane(pos, PL1.p1, PL1.normal), d); d = max(distPlane(pos, PL2.p1, PL2.normal), d); d = max(distPlane(pos, PL3.p1, PL3.normal), d); return d; } float distInfSphairahedra(const vec3 pos) { float d = distPrism(pos); d = max(distPlane(pos, dividePlane.p1, dividePlane.normal), d); d = max(-distSphere(pos, s2), d); d = max(-distSphere(pos, s4), d); d = max(-distSphere(pos, s6), d); return d; } void SphereInvert(inout vec3 pos, inout float dr, vec4 s) { vec3 diff = pos - s.xyz; float lenSq = dot(diff, diff); float k = (s.w * s.w) / lenSq; dr *= k; // (r * r) / lenSq pos = (diff * k) + s.xyz; } float distLimitSetTerrain(vec3 pos, out float invNum) { float dr = 1.; invNum = 0.; float d; for(int i = 0; i < 200; i++) { if(25 <= i) break; bool inFund = true; if(distance(pos, s2.xyz) < s2.w) { invNum ++; SphereInvert(pos, dr, s2); inFund = false; } if(distance(pos, s4.xyz) < s4.w) { invNum ++; SphereInvert(pos, dr, s4); inFund = false; } if(distance(pos, s6.xyz) < s6.w) { invNum ++; SphereInvert(pos, dr, s6); inFund = false; } pos -= PL1.p1; d = dot(pos, PL1.normal); if(d > 0.) { //invNum += 1.; pos -= 2. * d * PL1.normal; inFund = false; } pos += PL1.p1; pos -= PL2.p1; d = dot(pos, PL2.normal); if(d > 0.) { //invNum += 1.; pos -= 2. * d * PL2.normal; inFund = false; } pos += PL2.p1; pos -= PL3.p1; d = dot(pos, PL3.normal); if(d > 0.) { //invNum += 1.; pos -= 2. * d * PL3.normal; inFund = false; } pos += PL3.p1; if(inFund) break; } return distInfSphairahedra(pos) / abs(dr) * 0.1; } vec2 distFunc(vec3 p) { vec2 d = vec2(distLimitSetTerrain(p, gInvNum), 1); return d; } const vec2 NORMAL_COEFF = vec2(0.001, 0.); vec3 computeNormal(const vec3 p){ return normalize(vec3(distFunc(p + NORMAL_COEFF.xyy).x - distFunc(p - NORMAL_COEFF.xyy).x, distFunc(p + NORMAL_COEFF.yxy).x - distFunc(p - NORMAL_COEFF.yxy).x, distFunc(p + NORMAL_COEFF.yyx).x - distFunc(p - NORMAL_COEFF.yyx).x)); } const int MAX_MARCH = 300; int march (vec3 rayOrg, vec3 rayDir, inout float minDist, inout vec3 intersection, inout vec3 normal) { vec2 dist = vec2(-1); float rayLength = minDist; vec3 rayPos = rayOrg + rayDir * rayLength; for(int i = 0 ; i < MAX_MARCH ; i++){ dist = distFunc(rayPos); rayLength += dist.x; rayPos = rayOrg + rayDir * rayLength; if(dist.x < EPSILON){ int objId = int(dist.y); intersection = rayPos; normal = computeNormal(intersection); minDist = rayLength; return objId; } } return -1; } vec3 calcRay (const vec3 eye, const vec3 target, const vec3 up, const float fov, const float width, const float height, const vec2 coord){ float imagePlane = (height * .5) / tan(fov * .5); vec3 v = normalize(target - eye); vec3 xaxis = normalize(cross(v, up)); vec3 yaxis = normalize(cross(v, xaxis)); vec3 center = v * imagePlane; vec3 origin = center - (xaxis * (width *.5)) - (yaxis * (height * .5)); return normalize(origin + (xaxis * coord.x) + (yaxis * (height - coord.y))); } const vec4 K = vec4(1.0, .666666, .333333, 3.0); vec3 hsv2rgb(const vec3 c){ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); } vec3 getMatColor(int objId, vec3 normal, vec3 intersection, float t){ if(objId == 1){ vec3 col = Hsv2rgb((1., -0.01 + (gInvNum) * 0.02), 1., 1.);; return col; } return BLACK; } vec3 sky(vec3 rayDir){ return clamp(vec3(.7, .8, 1.) + exp(dot(rayDir, LIGHT_DIR))*0.1, 0.0, 1.0); } float computeShadowFactor (vec3 rayOrg, vec3 rayDir, float mint, float maxt, float k) { float shadowFactor = 1.0; float t = mint; for(int n = 0; n < 1000; n++){ if(t > maxt) break; float d = distFunc(rayOrg + rayDir * t).x; if(d < 0.0001) return 0.; shadowFactor = min(shadowFactor, k * d / t); t += d; } return clamp(shadowFactor, 0.0, 1.0); } float specular(vec3 n,vec3 l,vec3 e,float s) { return pow(clamp(dot(reflect(e,n),l),0.0, 1.),s); } const float FOG_START = 5.; const float FOG_END = 100.; const float FOG_END_START_RECIPROCAL = 1. / (FOG_END - FOG_START); const vec3 FOG_F = vec3(1.); vec3 calcColor(float time, vec3 eye, vec3 ray){ vec3 l = BLACK; float tmin = 0.; float t = 9999999.; const int maxLoop = 10; vec3 intersection, normal; bool isect; int objId = -1; bool hit = intersectBoundingPlane(vec3(0, 1, 0), vec3(0, gBoundingPlaneY, 0), eye, ray, tmin, t); if(hit && tmin < 30.) { objId = march(eye, ray, tmin, intersection, normal); if(objId != -1){ vec3 matColor = getMatColor(objId, normal, intersection, t); float k = computeShadowFactor(intersection + 0.0001 * normal, LIGHT_DIR, 0.001, 5., 100.); vec3 diffuse = clamp(dot(normal, LIGHT_DIR), 0., 1.) * matColor; vec3 ambient = matColor * AMBIENT_FACTOR; l += k * diffuse + ambient; l = mix(FOG_F, l, clamp((FOG_END - tmin) * FOG_END_START_RECIPROCAL, 0.1, 1.0)); } } else { l = mix( sky(ray), l, exp( -0.000000009*t * t ) ); } return l; } //w: start time //s: duration float scene(in float t, in float w, in float s){ return clamp(t - w, 0.0, s) / s; } float expEasingIn(float t){ return pow( 2., 13. * (t - 1.) ); } float circEasingIn(float t){ return - (sqrt(1. - t*t) - 1.); } float circEasingOut(float t){ return sqrt(1. - pow(t - 1., 2.)); } float circEasingInOut(float t){ t /= .5; if (t < 1.) return -.5 * (sqrt(1. - t*t) - 1.); t -= 2.; return .5 * (sqrt(1. - t*t) + 1.); } const vec3 target = vec3(0, 0, 0); vec3 up = vec3(0, 1, 0); float fov = radians(60.); const float SAMPLE_NUM = 2.; void main( ){ float t = mod(time, 31.); float rad = mix(0.0001, 1.0, circEasingInOut(scene(t, 1.0, 15.))); float rotationT = mix(0., 50., (scene(t, 0., 15.))); if(t < 21.) { float tb = rad * cos(rotationT); float tc = rad * sin(rotationT); tb = mix(tb, 0., circEasingInOut(scene(t, 15., 1.))); tc = mix(tc, 0., circEasingInOut(scene(t, 15., 1.))); tb = mix(tb, 1.2224464245160123, circEasingInOut(scene(t, 16., 1.))); tc = mix(tc, 0.612090457867328, circEasingInOut(scene(t, 16., 1.))); tb = mix(tb, -0.8661174154839888, circEasingInOut(scene(t, 17., 1.))); tc = mix(tc, 0., circEasingInOut(scene(t, 17., 1.))); tb = mix(tb, 0.61096041060052, circEasingInOut(scene(t, 18., 1.))); tc = mix(tc, -0.6110480831254523, circEasingInOut(scene(t, 18., 1.))); tb = mix(tb, -0.6144427845492827, circEasingInOut(scene(t, 19., 1.))); tc = mix(tc, 0.6155169219301033, circEasingInOut(scene(t, 19., 1.))); tb = mix(tb, -0.6492253932449349, circEasingInOut(scene(t, 20., 1.))); tc = mix(tc, -1.1670917737220714, circEasingInOut(scene(t, 20., 1.))); computeCubeSphairahedronA(tb, tc); } else if(t < 22.) { computeCubeSphairahedronA(-0.6492253932449349, -1.1670917737220714); computeCubeSphairahedronB(-1.4263771231354925, -0.4114778978502866); s2 = mix(s2A, s2B, circEasingInOut(scene(t, 21., 1.))); s4 = mix(s4A, s4B, circEasingInOut(scene(t, 21., 1.))); s6 = mix(s6A, s6B, circEasingInOut(scene(t, 21., 1.))); inversionSphere = vec4(-s6.x, -s6.y, s6.z, s6.w); } else if(t < 26.){ float tb = -1.4263771231354925; float tc = -0.4114778978502866; tb = mix(tb, 0.9480876782578194, circEasingInOut(scene(t, 22., 1.))); tc = mix(tc, -0.27487295833102093, circEasingInOut(scene(t, 22., 1.))); tb = mix(tb, -0.7341647058410344, circEasingInOut(scene(t, 23., 1.))); tc = mix(tc, -0.8016177852310659, circEasingInOut(scene(t, 23., 1.))); tb = mix(tb, -1.1021579831206387, circEasingInOut(scene(t, 24., 1.))); tc = mix(tc, 0., circEasingInOut(scene(t, 24., 1.))); tb = mix(tb, 0.7341944231647511, circEasingInOut(scene(t, 25., 1.))); tc = mix(tc, 0.8010951070853616, circEasingInOut(scene(t, 25., 1.))); computeCubeSphairahedronB(tb, tc); } else if(t < 27.){ computeCubeSphairahedronB(0.7341944231647511, 0.8010951070853616); computeCubeSphairahedronC(0.80897179163727, -0.6172090398213005); s2 = mix(s2B, s2C, circEasingInOut(scene(t, 26., 1.))); s4 = mix(s4B, s4C, circEasingInOut(scene(t, 26., 1.))); s6 = mix(s6B, s6C, circEasingInOut(scene(t, 26., 1.))); inversionSphere = vec4(-s6.x, -s6.y, s6.z, s6.w); } else if(t < 30.){ float tb = 0.80897179163727; float tc = -0.6172090398213005; tb = mix(tb, -1.0724597039839807, circEasingInOut(scene(t, 27., 1.))); tc = mix(tc, 0.10239062161550339, circEasingInOut(scene(t, 27., 1.))); tb = mix(tb, -0.4626628191468804, circEasingInOut(scene(t, 28., 1.))); tc = mix(tc, -0.7985798919860417, circEasingInOut(scene(t, 28., 1.))); tb = mix(tb, 1.0842163989231046, circEasingInOut(scene(t, 29., 1.))); tc = mix(tc, -0.09944669059450531, circEasingInOut(scene(t, 29., 1.))); computeCubeSphairahedronC(tb, tc); } else { computeCubeSphairahedronC(1.0842163989231046, -0.09944669059450531); computeCubeSphairahedronA(0., 0.); s2 = mix(s2C, s2A, circEasingInOut(scene(t, 30., 1.))); s4 = mix(s4C, s4A, circEasingInOut(scene(t, 30., 1.))); s6 = mix(s6C, s6A, circEasingInOut(scene(t, 30., 1.))); inversionSphere = vec4(-s6.x, -s6.y, s6.z, s6.w); } computeGSpheres(); computeVertexes(); dividePlane = computePlane(); convexSphere = computeConvexSphere(); gBoundingPlaneY = max(gBoundingPlaneY, s2.y + .01); gBoundingPlaneY = max(gBoundingPlaneY, s4.y + .01); gBoundingPlaneY = max(gBoundingPlaneY, s6.y + .01); vec3 eye = vec3(2. , 2., 2. ); eye = mix(eye, vec3(-2, 2, 2), circEasingInOut(scene(t, 15.0, 1.))); eye = mix(eye, vec3(-2, 2, -2), circEasingInOut(scene(t, 20.0, 1.))); eye = mix(eye, vec3(2, 2, -2), circEasingInOut(scene(t, 25.0, 1.))); eye = mix(eye, vec3(2, 2, 2), circEasingInOut(scene(t, 30.0, 1.))); vec3 sum = vec3(0); for(float i = 0. ; i < SAMPLE_NUM ; i++){ vec2 coordOffset = rand2n(gl_FragCoord.xy, i); vec3 ray = calcRay(eye, target, up, fov, resolution.x, resolution.y, gl_FragCoord.xy + coordOffset); sum += calcColor(t, eye, ray); } vec3 col = (sum/SAMPLE_NUM); gl_FragColor = vec4(gammaCorrect(col), 1.); }