|
| 1 | +#ifdef GL_ES |
| 2 | +precision mediump float; |
| 3 | +precision mediump int; |
| 4 | +#endif |
| 5 | + |
| 6 | +uniform vec3 iResolution; // viewport resolution (in pixels) |
| 7 | +uniform float iTime; // shader playback time (in seconds) |
| 8 | + |
| 9 | + |
| 10 | +float opSmoothUnion( float d1, float d2, float k ) |
| 11 | +{ |
| 12 | + float h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 ); |
| 13 | + return mix( d2, d1, h ) - k*h*(1.0-h); |
| 14 | +} |
| 15 | + |
| 16 | +float sdSphere( vec3 p, float s ) |
| 17 | +{ |
| 18 | + return length(p)-s; |
| 19 | +} |
| 20 | + |
| 21 | +float map(vec3 p) |
| 22 | +{ |
| 23 | + float d = 2.0; |
| 24 | + for (int i = 0; i < 16; i++) { |
| 25 | + float fi = float(i); |
| 26 | + float time = iTime * (fract(fi * 412.531 + 0.513) - 0.5) * 2.0; |
| 27 | + d = opSmoothUnion( |
| 28 | + sdSphere(p + sin(time + fi * vec3(52.5126, 64.62744, 632.25)) * vec3(2.0, 2.0, 0.8), mix(0.5, 1.0, fract(fi * 412.531 + 0.5124))), |
| 29 | + d, |
| 30 | + 0.4 |
| 31 | + ); |
| 32 | + } |
| 33 | + return d; |
| 34 | +} |
| 35 | + |
| 36 | +vec3 calcNormal( in vec3 p ) |
| 37 | +{ |
| 38 | + const float h = 1e-5; // or some other value |
| 39 | + const vec2 k = vec2(1,-1); |
| 40 | + return normalize( k.xyy*map( p + k.xyy*h ) + |
| 41 | + k.yyx*map( p + k.yyx*h ) + |
| 42 | + k.yxy*map( p + k.yxy*h ) + |
| 43 | + k.xxx*map( p + k.xxx*h ) ); |
| 44 | +} |
| 45 | + |
| 46 | +void main(void) |
| 47 | +{ |
| 48 | + vec2 uv = gl_FragCoord.xy/iResolution.xy; |
| 49 | + |
| 50 | + // screen size is 6m x 6m |
| 51 | + vec3 rayOri = vec3((uv - 0.5) * vec2(iResolution.x/iResolution.y, 1.0) * 6.0, 3.0); |
| 52 | + vec3 rayDir = vec3(0.0, 0.0, -1.0); |
| 53 | + |
| 54 | + float depth = 0.0; |
| 55 | + vec3 p; |
| 56 | + |
| 57 | + for(int i = 0; i < 64; i++) { |
| 58 | + p = rayOri + rayDir * depth; |
| 59 | + float dist = map(p); |
| 60 | + depth += dist; |
| 61 | + if (dist < 1e-6) { |
| 62 | + break; |
| 63 | + } |
| 64 | + } |
| 65 | + |
| 66 | + depth = min(6.0, depth); |
| 67 | + vec3 n = calcNormal(p); |
| 68 | + float b = max(0.0, dot(n, vec3(0.577))); |
| 69 | + vec3 col = (0.5 + 0.5 * cos((b + iTime * 3.0) + uv.xyx * 2.0 + vec3(0,2,4))) * (0.85 + b * 0.35); |
| 70 | + col *= exp( -depth * 0.15 ); |
| 71 | + |
| 72 | + // maximum thickness is 2m in alpha channel |
| 73 | + gl_FragColor = vec4(col, 1.0 - (depth - 0.5) / 2.0); |
| 74 | +} |
0 commit comments