// Copyright © 2022 rimina. // All rights to the likeness of the visuals reserved. // Any individual parts of the code that produces the visuals is // available in the public domain or licensed under the MIT license, // whichever suits you best under your local legislation. // This is to say: you can NOT use the code as a whole or the visual // output it produces for any purposes without an explicit permission, // nor can you remix or adapt the work itself without a permission.* // You absolutely CANNOT mint any NFTs based on the Work or part of it. // You CAN however use any individual algorithms or parts of the Code // for any purpose, commercial or otherwise, without attribution. // *(In practice, for most reasonable requests, I will gladly grant // any wishes to remix or adapt this work :)). //sdVerticalCapsule and sdEllipsoid function is from IQ //https://iquilezles.org/articles/distfunctions //thank you for your inspiring work <3 //also huge thanks to the live coding community in general I've learned so much from you! #define PI 3.14159265 //float fft = texture(texFFTIntegrated, 0.5).r; const float E = 0.001; const float FAR = 500.0; const int STEPS = 60; int M = 0; struct Material{ vec3 l; vec3 s; float sh; }; vec3 glow = vec3(0.0); Material getMaterial(int index){ Material m; if(index == 0){//tulip petals m.l = vec3(0.8, 0.6, 0.5); m.s = vec3(1.0, 0.3, 0.5); m.sh = 40.0; } else if(index == 1){//stem m.l = vec3(0.2, 0.8, 0.5); m.s = vec3(0.5, 0.9, 0.7); m.sh = 25.0; } else if(index == 2){//center of the tulip m.l = vec3(0.8, 0.6, 0.7); m.s = vec3(0.9, 0.9, 0.9); m.sh = 10.0; } else{//this could be just omitted m.l = vec3(0.8, 0.5, 0.8); m.s = vec3(1.0, 0.0, 1.0); m.sh = 40.0; } return m; } float sphere(vec3 p, float r){ return length(p)-r; } float box(vec3 p, vec3 b){ vec3 d = abs(p)-b; return length(max(d, 0.0)) + min(max(d.x, max(d.y, d.z)), 0.0); } //https://iquilezles.org/articles/distfunctions float sdEllipsoid( vec3 p, vec3 r ){ float k0 = length(p/r); float k1 = length(p/(r*r)); return k0*(k0-1.0)/k1; } //https://iquilezles.org/articles/distfunctions float sdVerticalCapsule( vec3 p, float h, float r ){ p.y -= clamp( p.y, 0.0, h ); return length( p ) - r; } void rot(inout vec2 p, float a){ p = cos(a)*p + sin(a)*vec2(p.y, -p.x); } float tulipBase(vec3 p){ vec3 pp = p; float tulip = sdEllipsoid(pp, vec3(1.0, 1.5, 1.0)); float inside = sdEllipsoid(pp-vec3(0.0, 0.25, 0.0), vec3(0.82, 1.7, 0.82)); pp.xz = abs(pp.xz) - vec2(0.6, 0.6); pp.y -= 1.0; rot(pp.xy, PI*0.25); rot(pp.yz, PI*0.25); float cube = box(pp, vec3(0.5, 0.5, 0.5)); tulip = max(tulip, -cube); tulip = max(tulip, -inside); return tulip; } float tulip(vec3 p){ vec3 pp = p; float tulip = tulipBase(pp); rot(pp.xz, PI*0.25); pp *= 1.03; tulip = min(tulip, tulipBase(pp)); pp.y += 0.75; float center = sphere(pp, 0.5); glow += vec3(0.4, 0.1, 0.5) *0.01 / (abs(center)+0.01); pp.y += 5.8; float varsi = sdVerticalCapsule(pp, 5.0, 0.25); M = 0; if(varsi < tulip && varsi < center){ M = 1; } else if(center < varsi && center < tulip){ M = 2; } tulip = min(tulip, center); tulip = min(tulip, varsi); return tulip; } float scene(vec3 p){ vec3 pp = p; rot(pp.xz, /*fft*0.5+*/iTime*0.1); for(int i = 0; i < 5; ++i){ pp.xz = abs(pp.xz)-vec2(1., 1.); rot(pp.xz, PI/5.5); rot(pp.xy, -0.02); } pp.xz = mod(pp.xz+4.0, vec2(8.0))-4.0; rot(pp.xy, sin(iTime)*0.01); rot(pp.yz, cos(iTime)*0.01); float tulppaani = tulip(pp); return tulppaani; } float march(vec3 ro, vec3 rd){ vec3 p = ro; float t = E; for(int i = 0; i < STEPS; ++i){ float d = scene(p); t += d; p = ro + rd * t; if(d < E || t > FAR){ break; } } return t; } vec3 normals(vec3 p){ vec3 e = vec3(E, 0.0, 0.0); return normalize(vec3( scene(p+e.xyy) - scene(p-e.xyy), scene(p+e.yxy) - scene(p-e.yxy), scene(p+e.yyx) - scene(p-e.yyx) )); } vec3 shade(vec3 rd, vec3 p, vec3 ld, Material m){ vec3 n = normals(p); float l = max(dot(ld, n), 0.0); float a = max(dot(reflect(rd, ld), n), 0.0); float s = pow(a, m.sh); return m.s*l + m.l*s; } void mainImage( out vec4 fragColor, in vec2 fragCoord ) { // Normalized pixel coordinates (from 0 to 1) vec2 uv = fragCoord/iResolution.xy; vec2 q = -1.0 + 2.0*uv; q.x *= iResolution.x/iResolution.y; vec3 ro = vec3(10.0*sin(iTime*0.5), 10.0, 2.0*cos(iTime*0.5)); vec3 rt = vec3(0.0, -10.0, 0.0); vec3 z = normalize(rt-ro); vec3 x = normalize(cross(z, vec3(0.0, 1.0, 0.0))); vec3 y = normalize(cross(x, z)); vec3 rd = normalize(mat3(x, y, z)*vec3(q, 1.0/radians(120.0))); float t = march(ro, rd); vec3 p = ro + rd * t; vec3 ld = -rd; vec3 fogc = vec3(0.3, 0.5, 0.45); vec3 col = fogc; if(t < FAR){ Material m = getMaterial(M); col = shade(rd, p, ld, m); } col += glow*0.75; float d = length(p-ro); float amount = 1.0-exp(-d*0.01); col = mix(col, fogc, amount); // Output to screen fragColor = vec4(col,1.0); }