Selected Student Works
This is a small selection of student works from the 2023 class “Advanced Computer Graphics”. The objective was to create an image of a sea slug using a single fragment shader. You can see the full homework description if interested.
//credit: Kojun //sea slug: Hypselodoris bullocki vec3 mod289(vec3 x) {return x - floor(x * (1.0 / 289.0)) * 289.0;} vec2 mod289(vec2 x) {return x - floor(x * (1.0 / 289.0)) * 289.0;} vec4 mod289(vec4 x) {return x - floor(x * (1.0 / 289.0)) * 289.0;} vec3 mod7(vec3 x) { return x - floor(x * (1.0 / 7.0)) * 7.0; } vec4 permute(vec4 x) {return mod289(((x*34.0)+10.0)*x);} vec3 permute(vec3 x) {return mod289(((x*34.0)+10.0)*x);} vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;} float snoise(vec3 v){ const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); vec3 i = floor(v + dot(v, C.yyy) );vec3 x0 = v - i + dot(i, C.xxx) ;vec3 g = step(x0.yzx, x0.xyz); vec3 l = 1.0 - g;vec3 i1 = min( g.xyz, l.zxy );vec3 i2 = max( g.xyz, l.zxy ); vec3 x1 = x0 - i1 + C.xxx;vec3 x2 = x0 - i2 + C.yyy; vec3 x3 = x0 - D.yyy; i = mod289(i); vec4 p = permute( permute( permute( i.z + vec4(0.0, i1.z, i2.z, 1.0 )) + i.y + vec4(0.0, i1.y, i2.y, 1.0 ))+ i.x + vec4(0.0, i1.x, i2.x, 1.0 )); float n_ = 0.142857142857; vec3 ns = n_ * D.wyz - D.xzx;vec4 j = p - 49.0 * floor(p * ns.z * ns.z); vec4 x_ = floor(j * ns.z);vec4 y_ = floor(j - 7.0 * x_ );vec4 x = x_ *ns.x + ns.yyyy; vec4 y = y_ *ns.x + ns.yyyy;vec4 h = 1.0 - abs(x) - abs(y);vec4 b0 = vec4( x.xy, y.xy ); vec4 b1 = vec4( x.zw, y.zw );vec4 s0 = floor(b0)*2.0 + 1.0;vec4 s1 = floor(b1)*2.0 + 1.0; vec4 sh = -step(h, vec4(0.0));vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;vec3 p0 = vec3(a0.xy,h.x); vec3 p1 = vec3(a0.zw,h.y);vec3 p2 = vec3(a1.xy,h.z);vec3 p3 = vec3(a1.zw,h.w); vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); p0 *= norm.x;p1 *= norm.y;p2 *= norm.z;p3 *= norm.w; vec4 m = max(0.5 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); m = m * m;return 105.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),dot(p2,x2), dot(p3,x3) ) );} float snoise(vec2 v){const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439);vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx);vec2 i1;i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); vec4 x12 = x0.xyxy + C.xxzz;x12.xy -= i1;i = mod289(i); // Avoid truncation effects in permutation vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))+ i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ;m = m*m ; vec3 x = 2.0 * fract(p * C.www) - 1.0;vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5);vec3 a0 = x - ox;m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); vec3 g;g.x = a0.x * x0.x + h.x * x0.y;g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g);} float cro(in vec2 a, in vec2 b ) { return a.x*b.y - a.y*b.x; } float sdUnevenCapsule( in vec2 p, in vec2 pa, in vec2 pb, in float ra, in float rb ){ p -= pa; pb -= pa; float h = dot(pb,pb);vec2 q = vec2( dot(p,vec2(pb.y,-pb.x)), dot(p,pb) )/h; q.x = abs(q.x);float b = ra-rb;vec2 c = vec2(sqrt(h-b*b),b);float k = cro(c,q); float m = dot(c,q);float n = dot(q,q);if( k < 0.0 ) return sqrt(h*(n )) - ra; else if( k > c.x ) return sqrt(h*(n+1.0-2.0*q.y)) - rb; return m - ra;} float sdSegment( in vec2 p, in vec2 a, in vec2 b ){ vec2 pa = p-a, ba = b-a;float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); return length( pa - ba*h );} float turb_fract( vec3 p ) {float f = -0.2, scale;for (int i=0; i<4; i++) { scale = pow( pow(3.0, 1.75), float(i) );f += abs(snoise( p * scale )) / scale;} return f;} float turb_fract( vec2 p ) {float f = -0.2, scale;for (int i=0; i<4; i++) { scale = pow( pow(5.0, 1.75), float(i) );f += abs(snoise( p * scale )) / scale;} return f;} vec2 random2( vec2 p ) { return fract(sin(vec2(dot(p,vec2(127.1,311.7)),dot(p,vec2(269.5,183.3))))*43758.5453); } //////////////////////// #ifdef GL_ES precision mediump float; #endif uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec2 mt = u_mouse.xy/u_resolution.xy; vec3 uv = vec3( .5 * st - 0.5, 0.1*u_time ); float noise = 0.6*turb_fract( uv )+0.2; colour_out = vec4( vec3(0.076,0.174,0.230), noise ); //体 vec3 co_dark = vec3(0.026,0.060,0.150);//体色 vec3 co_pat = vec3(0.706,0.048,0.089);//斑点色 float mask = 1.0; float n = turb_fract( st / 0.25 + 0.1 * mt.x);//斑点 mask *= step( 0.03, sdUnevenCapsule(st - vec2(0.570,0.580), vec2(-0.350,-0.220), vec2(0.200,-0.090), 0.1, .2));//体1 mask *= step( 0.023, sdUnevenCapsule(st - vec2(0.240,0.430), vec2(0.280,0.040), vec2(-0.010,-0.020), 0.1, .2));//体2 vec3 co = mix(co_dark, co_pat, vec3(step(0.7, n * 0.5+ 0.5)));//see slug //背景 vec3 color = vec3(0.071,0.778,1.000); vec2 i_st = floor(st*4.); vec2 f_st = fract(st*4.); float m_dist = 1.; // minimum distance for (int y= -1; y <= 1; y++) { for (int x= -1; x <= 1; x++) { // Neighbor place in the grid vec2 neighbor = vec2(float(x),float(y)); // Random position from current + neighbor place in the grid vec2 point = random2(i_st + neighbor); // Animate the point point = -0.060 + 0.5*sin(u_time + 6.2831*point); // Vector between the pixel and the point vec2 diff = neighbor + point - f_st; // Distance to the point float dist = length(diff); // Keep the closer distance m_dist = min(m_dist, dist);}} // Draw the min distance (distance field) color += m_dist; // Draw cell center color += 1.-step(.02, m_dist); colour_out += mix(vec4(co, 1.0), vec4(color,1.0), mask);//背景 //影 mask = 1.0; mask *= smoothstep( .0, .20, sdUnevenCapsule(st - vec2(0.870,0.330), vec2(-0.640,-0.090), vec2(0.0), 0.01, 0.03) ); colour_out *= mix(vec4(0.7), vec4(1.0), mask); //触覚 mask = 1.0; co = mix(vec3(0.00), vec3(7.000,0.528,0.127), vec3(step(0.4, n * 0.5 + 0.5))); mask *= step( 0.03, sdSegment(st, vec2(0.160,0.730), vec2(0.100,0.540)) ); mask *= step( 0.03, sdSegment(st, vec2(0.320,0.720), vec2(0.220,0.520)) ); colour_out *= mix(vec4(co, 1.0), vec4(1.0, 1.0, 1.0, 1.0), mask); //しっぽ mask = 1.0; //1 mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.655,0.77))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.660,0.76))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.666,0.74))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.670, 0.74))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.676,0.73))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.690,0.72))); mask *= step(0.03, distance(st - 0.01 * (mt - vec2(.3, .7)), vec2(0.700,0.71))); //2 mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.710, 0.81))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.717,0.81))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.710,0.80))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.710,0.77))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.720, 0.76))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.720,0.73))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.730,0.72))); mask *= step(0.03, distance(st - 0.01 * (mt - vec2(.3, .7)), vec2(0.730,0.71))); //3 mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.755,0.810))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.755,0.78))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.755,0.77))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.750,0.76))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.740, 0.75))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.740,0.74))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.740,0.73))); mask *= step(0.03, distance(st - 0.01 * (mt - vec2(.3, .7)), vec2(0.73,0.70))); //4 mask *= step(0.018, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.790, 0.79))); mask *= step(0.018, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.787,0.78))); mask *= step(0.018, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.780,0.77))); mask *= step(0.018, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.780,0.76))); mask *= step(0.018, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.770, 0.75))); mask *= step(0.018, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.760,0.74))); mask *= step(0.018, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.760,0.73))); mask *= step(0.028, distance(st - 0.01 * (mt - vec2(.3, .7)), vec2(0.760,0.70))); //5 mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.825,0.77))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.820,0.76))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.820,0.74))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.8120, 0.74))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.816,0.73))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.810,0.72))); mask *= step(0.03, distance(st - 0.01 * (mt - vec2(.3, .7)), vec2(0.800,0.71))); colour_out += mix(vec4(0.975,0.450,0.055,1.000), vec4(.0), mask); }
Hypselodoris bullocki by Kojun
// credit: ununtrium // sea slug: Hypselodoris festiva uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; // rotation function mat3 rotate(float angle){ float s = sin(angle); float c = cos(angle); mat3 m = mat3( c,-s, 0.0, s, c, 0.0, 0.0, 0.0, 1.0); return m; } // Julia set float julia_set(vec2 xy, vec2 trans, float rot, float scale, float shape){ vec2 p = (rotate(rot) * vec3((xy * scale - u_resolution) / min(u_resolution.x, u_resolution.y)-5.0*trans, 1.0)).rg; int j = 0; vec2 x = vec2(0.040,0.190); vec2 y = vec2(0.110,0.310); vec2 z = p; for(int i = 0; i < 30; i++){ j++; if(length(z) > 2.0){break;} z = vec2(z.x * z.x - z.y * z.y, shape * z.x * z.y) + x + y; } vec2 st = xy/u_resolution.xy; float h = abs(mod(15.000 - float(j), 360.000) / 360.000); h = step(0.1, h); return h; } // UnevenCapsule // The MIT License // Copyright © 2018 Inigo Quilez // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. float sdUnevenCapsule( vec2 p, float r1, float r2, float h, vec2 trans, float angle ) { p -= trans; p = (rotate(angle)*vec3(p,1.0)).xy; p.x = abs(p.x); float b = (r1-r2)/h; float a = sqrt(1.0-b*b); float k = dot(p,vec2(-b,a)); if( k < 0.0 ) return length(p) - r1; if( k > a*h ) return length(p-vec2(0.0,h)) - r2; return dot(p, vec2(a,b) ) - r1; } // Arc // The MIT License // Copyright © 2019 Inigo Quilez // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. float sdArc( in vec2 p, in vec2 sc, in float ra, float rb, vec2 trans, float angle) { p = (rotate(angle)*vec3(p,1.0)).xy; p -= trans*3.0; // sc is the sin/cos of the arc's aperture p.x = abs(p.x); return ((sc.y*p.x>sc.x*p.y) ? length(p-sc*ra) : abs(length(p)-ra)) - rb; } //// ↓noise // // GLSL textureless classic 2D noise "cnoise", // Author: Stefan Gustavson (stefan.gustavson@liu.se) // Version: 2011-08-22 // // Many thanks to Ian McEwan of Ashima Arts for the // ideas for permutation and gradient selection. // // Copyright (c) 2011 Stefan Gustavson. All rights reserved. // Distributed under the MIT license. See LICENSE file. // https://github.com/stegu/webgl-noise // vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 permute(vec4 x) { return mod289(((x*34.0)+10.0)*x); } vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } vec2 fade(vec2 t) { return t*t*t*(t*(t*6.0-15.0)+10.0); } // Classic Perlin noise float cnoise(vec2 P) { vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0); vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0); Pi = mod289(Pi); // To avoid truncation effects in permutation vec4 ix = Pi.xzxz; vec4 iy = Pi.yyww; vec4 fx = Pf.xzxz; vec4 fy = Pf.yyww; vec4 i = permute(permute(ix) + iy); vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0 ; vec4 gy = abs(gx) - 0.5 ; vec4 tx = floor(gx + 0.5); gx = gx - tx; vec2 g00 = vec2(gx.x,gy.x); vec2 g10 = vec2(gx.y,gy.y); vec2 g01 = vec2(gx.z,gy.z); vec2 g11 = vec2(gx.w,gy.w); vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); g00 *= norm.x; g01 *= norm.y; g10 *= norm.z; g11 *= norm.w; float n00 = dot(g00, vec2(fx.x, fy.x)); float n10 = dot(g10, vec2(fx.y, fy.y)); float n01 = dot(g01, vec2(fx.z, fy.z)); float n11 = dot(g11, vec2(fx.w, fy.w)); vec2 fade_xy = fade(Pf.xy); vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x); float n_xy = mix(n_x.x, n_x.y, fade_xy.y); return 2.3 * n_xy; } // // Description : Array and textureless GLSL 2D/3D/4D simplex // noise functions. // Author : Ian McEwan, Ashima Arts. // Maintainer : stegu // Lastmod : 20201014 (stegu) // License : Copyright (C) 2011 Ashima Arts. All rights reserved. // Distributed under the MIT License. See LICENSE file. // https://github.com/ashima/webgl-noise // https://github.com/stegu/webgl-noise // vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } float snoise(vec3 v) { const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); // First corner vec3 i = floor(v + dot(v, C.yyy) ); vec3 x0 = v - i + dot(i, C.xxx) ; // Other corners vec3 g = step(x0.yzx, x0.xyz); vec3 l = 1.0 - g; vec3 i1 = min( g.xyz, l.zxy ); vec3 i2 = max( g.xyz, l.zxy ); vec3 x1 = x0 - i1 + C.xxx; vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y // Permutations i = mod289(i); vec4 p = permute( permute( permute( i.z + vec4(0.0, i1.z, i2.z, 1.0 )) + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); // Gradients: 7x7 points over a square, mapped onto an octahedron. // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) float n_ = 0.142857142857; // 1.0/7.0 vec3 ns = n_ * D.wyz - D.xzx; vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) vec4 x_ = floor(j * ns.z); vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) vec4 x = x_ *ns.x + ns.yyyy; vec4 y = y_ *ns.x + ns.yyyy; vec4 h = 1.0 - abs(x) - abs(y); vec4 b0 = vec4( x.xy, y.xy ); vec4 b1 = vec4( x.zw, y.zw ); vec4 s0 = floor(b0)*2.0 + 1.0; vec4 s1 = floor(b1)*2.0 + 1.0; vec4 sh = -step(h, vec4(0.0)); vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; vec3 p0 = vec3(a0.xy,h.x); vec3 p1 = vec3(a0.zw,h.y); vec3 p2 = vec3(a1.xy,h.z); vec3 p3 = vec3(a1.zw,h.w); //Normalise gradients vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); p0 *= norm.x; p1 *= norm.y; p2 *= norm.z; p3 *= norm.w; // Mix final noise value vec4 m = max(0.5 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); m = m * m; return 105.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) ); } //// ↑noise // snoise color float s_color(vec2 xy) { return 0.596 * snoise(vec3(xy, u_time*0.2)); } void main(void){ vec2 st = (gl_FragCoord.xy/u_resolution.xy -vec2(0.5,0.5))*2.0; // hirahira // julia_set(xy, trans, rotate, scale, change_shape) float j1 = julia_set(gl_FragCoord.xy, vec2(-0.025+sin(u_time)*0.02,0.2), 2.7+0.2*cos(u_time), 4.0, 3.0); float j2 = julia_set(gl_FragCoord.xy, vec2(0.070,0.380), 4.0+0.2*sin(u_time), 5.0, 3.0); // sea weed float j3 = step(0.232, julia_set(gl_FragCoord.xy, vec2(0.080,-0.180), 4.0+0.1*sin(u_time), 2.5, 2.0)); // body // Arc(xy, saki, curve, thick, trans, rotate) float a1 = 1.0 - step(0.0, sdArc(st, vec2(0.320,0.950), 1.812+0.1*sin(u_time), 0.188, vec2(0.030,-0.680),5.836+0.05*sin(u_time))); float a2 = 1.0 - sdArc(st, vec2(0.280,0.960), 2.276+0.1*sin(u_time), 0.252+0.02*abs(sin(u_time)), vec2(0.020,-0.790),-0.444+0.05*sin(u_time+10.0)); // horn // UnevenCapsule(xy, scala_up, scala_down, scala_long, trans, rotate) float u1 = 1.0 - step(0.1, sdUnevenCapsule(st.xy, -0.040,-0.060,0.400, vec2((cos(u_time)-0.1)*0.05+0.6,(sin(u_time))*0.05-0.5), cos(u_time)*0.5+3.8)); float u2 = 1.0 - step(0.1, sdUnevenCapsule(st.xy, -0.040,-0.060,0.400, vec2((cos(u_time)-0.1)*0.05+0.620,(sin(u_time))*0.05-0.3), sin(u_time)*0.5+5.408)); if ((j1==1.0 && st.y>0.0)||(j2==1.0 && st.x<-0.47)){ // hirahira vec3 rgb = vec3(1.000,5.0*sin(st.y)*0.293,0.158); colour_out = vec4(rgb,1.0); }else if(u1 == 1.0 || u2 == 1.0){ // horn vec3 rgb = vec3(1.0,0.4,cos((st.y)*5.0)*0.7); colour_out = vec4(rgb,1.0); }else if(a2>1.04){ // body if(s_color(st.xy*5.0)>0.3){ vec3 rgb = vec3(0.960,0.930,0.553); colour_out = vec4(rgb, 1.0); }else if(s_color((st.xy-vec2(0.5,0.5))*5.0)>0.3){ vec3 rgb = vec3(0.0); colour_out = vec4(rgb, 1.0); }else{ vec3 rgb = vec3(0.275,0.329,0.825); colour_out = vec4(rgb, 1.0); } }else if(a2 > 1.0){ vec3 rgb = vec3(0.960,0.930,0.553); colour_out = vec4(rgb, 1.0); }else if(a1==1.0){ vec3 rgb = vec3(cnoise(st.xy*30.000)*1.0,0.577,0.825); colour_out = vec4(rgb, 1.0); }else { if (j3==1.0){ // sea weed vec3 rgb = vec3(cnoise(st*30.0)*5.0,0.696,cnoise(st*100.0)*5.0); colour_out = vec4(rgb, 1.0); }else{ // sea vec3 rgb = s_color(st)*3.0*vec3(0.014,0.335,1.000); colour_out = vec4(rgb, 1.0); } } }
Hypselodoris festiva by ununtrium
// credit: zhu // sea slug uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; // // Description : Array and textureless GLSL 2D simplex noise function. // Author : Ian McEwan, Ashima Arts. // Maintainer : stegu // Lastmod : 20110822 (ijm) // License : Copyright (C) 2011 Ashima Arts. All rights reserved. // Distributed under the MIT License. See LICENSE file. // https://github.com/ashima/webgl-noise // https://github.com/stegu/webgl-noise // vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 permute(vec3 x) { return mod289(((x*34.0)+10.0)*x); } float snoise(vec2 v) { const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) -0.577350269189626, // -1.0 + 2.0 * C.x 0.024390243902439); // 1.0 / 41.0 // First corner vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); // Other corners vec2 i1; //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 //i1.y = 1.0 - i1.x; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); // x0 = x0 - 0.0 + 0.0 * C.xx ; // x1 = x0 - i1 + 1.0 * C.xx ; // x2 = x0 - 1.0 + 2.0 * C.xx ; vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; // Permutations i = mod289(i); // Avoid truncation effects in permutation vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; // Gradients: 41 points uniformly over a line, mapped onto a diamond. // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; // Normalise gradients implicitly by scaling m // Approximation of: m *= inversesqrt( a0*a0 + h*h ); m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); // Compute final noise value at P vec3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } float sdEllipse( in vec2 p, in vec2 ab ) { p = abs(p); if( p.x > p.y ) {p=p.yx;ab=ab.yx;} float l = ab.y*ab.y - ab.x*ab.x; float m = ab.x*p.x/l; float m2 = m*m; float n = ab.y*p.y/l; float n2 = n*n; float c = (m2+n2-1.0)/3.0; float c3 = c*c*c; float q = c3 + m2*n2*2.0; float d = c3 + m2*n2; float g = m + m*n2; float co; if( d<0.0 ) { float h = acos(q/c3)/3.0; float s = cos(h); float t = sin(h)*sqrt(3.0); float rx = sqrt( -c*(s + t + 2.0) + m2 ); float ry = sqrt( -c*(s - t + 2.0) + m2 ); co = (ry+sign(l)*rx+abs(g)/(rx*ry)- m)/2.0; } else { float h = 2.0*m*n*sqrt( d ); float s = sign(q+h)*pow(abs(q+h), 1.0/3.0); float u = sign(q-h)*pow(abs(q-h), 1.0/3.0); float rx = -s - u - c*4.0 + 2.0*m2; float ry = (s - u)*sqrt(3.0); float rm = sqrt( rx*rx + ry*ry ); co = (ry/sqrt(rm-rx)+2.0*g/rm-m)/2.0; } vec2 r = ab * vec2(co, sqrt(1.0-co*co)); return length(r-p) * sign(p.y-r.y); } float sdOrientedBox( in vec2 p, in vec2 a, in vec2 b, float th ) { float l = length(b-a); vec2 d = (b-a)/l; vec2 q = (p-(a+b)*0.5); q = mat2(d.x,-d.y,d.y,d.x)*q; q = abs(q)-vec2(l,th)*0.5; return length(max(q,0.0)) + min(max(q.x,q.y),0.0); } vec2 rotate( vec2 v, float a ) { float s = sin(a); float c = cos(a); mat2 m = mat2(c,-s,s,c); return m*v; } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec2 posparams[10] = vec2[10]( vec2(0.5, 0.4), vec2(0.6, 0.7), vec2(0.4, 0.7), vec2(0.3, 0.3), vec2(0.7, 0.3), vec2(0.3, 0.6), vec2(0.7, 0.6), vec2(0.5, 0.2), vec2(0.5, 0.8), vec2(0.5, 0.5) ); float PI = 3.1415; float rotparams[10] = float[10]( 0.2233461037801064, 2.001346354336402, 1.4679388529120532, 1.3685408012576143, 0.9926512279720201, 2.873918692889804, 0.4254639299635069, 2.3032786037019606, 1.3584553728153652, 0.6613299790099506 ); float sizeparams[10] = float[10]( 0.9026858071489114, 0.3999867953106939, 0.7895833118750084, 0.24781006431329144, 0.4816870884046909, 0.6680503885050741, 0.5083456681447074, 0.3944068654633692, 0.64749891730475, 0.6158968781845998 ); // background green material // grass? float noise_bg = snoise(st * 30.0); for (int i = 0; i < 10; i++) { vec2 pos = rotate(st - posparams[i], rotparams[i]); float d = sdEllipse(pos, vec2(sizeparams[i] * 0.1, sizeparams[i] * 0.3)); if (d < 0.0) { colour_out = vec4(noise_bg, (1.0 + d * 7.0), 0.0, 0.8); } } for (int i = 0; i < 10; i++) { vec2 pos = rotate(st - vec2(posparams[i].x, 1.0 - posparams[i].y), rotparams[i] + PI / 2.0); float d = sdEllipse(pos, vec2(sizeparams[i] * 0.1, sizeparams[i] * 0.3)); if (d < 0.0) { colour_out = vec4(noise_bg, (1.0 + d * 7.0), 0.0, 0.8); } } // sea slug body vec2 pos1 = rotate(st - vec2(0.5, 0.4), -0.4); float d1 = sdEllipse(pos1, vec2(0.1, 0.15)); vec2 pos2 = rotate(st - vec2(0.6, 0.7), -0.2); float d2 = sdEllipse(pos2, vec2(0.05, 0.2)); float bodynoise = 1.0 - snoise(st * 50. + u_time * 0.15); if (d1 < 0.0 || d2 < 0.0) { colour_out = vec4(bodynoise, bodynoise, 0.1, 1.0); } else if (d1 < 0.01 || d2 < 0.01) { colour_out = vec4(1.0); } // sea slug eyes float timenoise = snoise(vec2(u_time * 0.5, 0.0)); float eyecl = 1.0 - snoise(st * 30.); vec2 mov = vec2(timenoise * 0.1 - 0.05, timenoise * 0.06 - 0.03); float eye1 = sdOrientedBox(st, vec2(0.4, 0.3), vec2(0.3, 0.26) + mov, 0.03); float eye2 = sdOrientedBox(st, vec2(0.52, 0.29), vec2(0.5, 0.1) + mov, 0.03); if (eye1 < 0.0 || eye2 < 0.0) { colour_out = vec4(eyecl, eyecl, 1.0, 1.0); } }
sea slug by zhu
// credit: lk // sea slug: Hypselodoris variobranchia // https://seaslug.world/species/hypselodoris_variobranchia uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; float M_PI = 3.1415926535; vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 mod289(vec4 x){ return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 permute(vec4 x){ return mod289(((x*34.0)+10.0)*x); } vec4 taylorInvSqrt(vec4 r){ return 1.79284291400159 - 0.85373472095314 * r; } vec2 fade(vec2 t) { return t*t*t*(t*(t*6.0-15.0)+10.0); } float snoise(vec3 v){ const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); // First corner vec3 i = floor(v + dot(v, C.yyy) ); vec3 x0 = v - i + dot(i, C.xxx) ; // Other corners vec3 g = step(x0.yzx, x0.xyz); vec3 l = 1.0 - g; vec3 i1 = min( g.xyz, l.zxy ); vec3 i2 = max( g.xyz, l.zxy ); // x0 = x0 - 0.0 + 0.0 * C.xxx; // x1 = x0 - i1 + 1.0 * C.xxx; // x2 = x0 - i2 + 2.0 * C.xxx; // x3 = x0 - 1.0 + 3.0 * C.xxx; vec3 x1 = x0 - i1 + C.xxx; vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y // Permutations i = mod289(i); vec4 p = permute( permute( permute( i.z + vec4(0.0, i1.z, i2.z, 1.0 )) + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); // Gradients: 7x7 points over a square, mapped onto an octahedron. // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) float n_ = 0.142857142857; // 1.0/7.0 vec3 ns = n_ * D.wyz - D.xzx; vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) vec4 x_ = floor(j * ns.z); vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) vec4 x = x_ *ns.x + ns.yyyy; vec4 y = y_ *ns.x + ns.yyyy; vec4 h = 1.0 - abs(x) - abs(y); vec4 b0 = vec4( x.xy, y.xy ); vec4 b1 = vec4( x.zw, y.zw ); //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; vec4 s0 = floor(b0)*2.0 + 1.0; vec4 s1 = floor(b1)*2.0 + 1.0; vec4 sh = -step(h, vec4(0.0)); vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; vec3 p0 = vec3(a0.xy,h.x); vec3 p1 = vec3(a0.zw,h.y); vec3 p2 = vec3(a1.xy,h.z); vec3 p3 = vec3(a1.zw,h.w); //Normalise gradients vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); p0 *= norm.x; p1 *= norm.y; p2 *= norm.z; p3 *= norm.w; // Mix final noise value vec4 m = max(0.5 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); m = m * m; return 105.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) ); } // Classic Perlin noise float cnoise(vec2 P){ vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0); vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0); Pi = mod289(Pi); // To avoid truncation effects in permutation vec4 ix = Pi.xzxz; vec4 iy = Pi.yyww; vec4 fx = Pf.xzxz; vec4 fy = Pf.yyww; vec4 i = permute(permute(ix) + iy); vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0 ; vec4 gy = abs(gx) - 0.5 ; vec4 tx = floor(gx + 0.5); gx = gx - tx; vec2 g00 = vec2(gx.x,gy.x); vec2 g10 = vec2(gx.y,gy.y); vec2 g01 = vec2(gx.z,gy.z); vec2 g11 = vec2(gx.w,gy.w); vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); g00 *= norm.x; g01 *= norm.y; g10 *= norm.z; g11 *= norm.w; float n00 = dot(g00, vec2(fx.x, fy.x)); float n10 = dot(g10, vec2(fx.y, fy.y)); float n01 = dot(g01, vec2(fx.z, fy.z)); float n11 = dot(g11, vec2(fx.w, fy.w)); vec2 fade_xy = fade(Pf.xy); vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x); float n_xy = mix(n_x.x, n_x.y, fade_xy.y); return 2.4 * n_xy; } float sdEllipse(vec2 p, vec2 ab){ p = abs(p); if( p.x > p.y ) {p=p.yx;ab=ab.yx;} float l = ab.y*ab.y - ab.x*ab.x; float m = ab.x*p.x/l; float m2 = m*m; float n = ab.y*p.y/l; float n2 = n*n; float c = (m2+n2-1.0)/3.0; float c3 = c*c*c; float q = c3 + m2*n2*2.0; float d = c3 + m2*n2; float g = m + m*n2; float co; if( d<0.0 ){ float h = acos(q/c3)/3.0; float s = cos(h); float t = sin(h)*sqrt(3.0); float rx = sqrt( -c*(s + t + 2.0) + m2 ); float ry = sqrt( -c*(s - t + 2.0) + m2 ); co = (ry+sign(l)*rx+abs(g)/(rx*ry)- m)/2.0; }else{ float h = 2.0*m*n*sqrt( d ); float s = sign(q+h)*pow(abs(q+h), 1.0/3.0); float u = sign(q-h)*pow(abs(q-h), 1.0/3.0); float rx = -s - u - c*4.0 + 2.0*m2; float ry = (s - u)*sqrt(3.0); float rm = sqrt( rx*rx + ry*ry ); co = (ry/sqrt(rm-rx)+2.0*g/rm-m)/2.0; } vec2 r = ab * vec2(co, sqrt(1.0-co*co)); return length(r-p) * sign(p.y-r.y); } float sdEquilateralTriangle(vec2 p){ const float k = sqrt(3.0); p.x = abs(p.x) - 1.0; p.y = p.y + 1.0/k; if( p.x+k*p.y>0.0 ) p = vec2(p.x-k*p.y,-k*p.x-p.y)/2.0; p.x -= clamp( p.x, -2.0, 0.0 ); return -length(p)*sign(p.y); } float sdbody1(vec2 P, vec2 slides, float theta) { theta = 2.0 * M_PI * theta / 360.0; mat2 R = mat2(cos(theta), -sin(theta), sin(theta), cos(theta)); return sdEllipse(R * (P - slides), vec2(0.67,0.3)); } float sdbody2(vec2 P, vec2 slides, float theta) { theta = 2.0 * M_PI * theta / 360.0; mat2 R = mat2(cos(theta), -sin(theta), sin(theta), cos(theta)); return sdEquilateralTriangle(5.232 * R * (P - slides)) - 0.5; } float sdtale1(vec2 P, vec2 slides, float theta) { theta = 2.0 * M_PI * theta / 360.0; mat2 R = mat2(cos(theta), -sin(theta), sin(theta), cos(theta)); return sdEllipse(R * (P - slides), vec2(0.06, 0.35)); } float sdtale2(vec2 P, vec2 slides, float theta) { theta = 2.0 * M_PI * theta / 360.0; mat2 R = mat2(cos(theta), -sin(theta), sin(theta), cos(theta)); return sdEllipse(R * (P - slides), vec2(0.05, 0.3)); } float sdtale3(vec2 P, vec2 slides, float theta) { theta = 2.0 * M_PI * theta / 360.0; mat2 R = mat2(cos(theta), -sin(theta), sin(theta), cos(theta)); return sdEllipse(R * (P - slides), vec2(0.05, 0.3)); } float sdtale4(vec2 P, vec2 slides, float theta) { theta = 2.0 * M_PI * theta / 360.0; mat2 R = mat2(cos(theta), -sin(theta), sin(theta), cos(theta)); return sdEllipse(R * (P - slides), vec2(0.05, 0.3)); } float sdtale5(vec2 P, vec2 slides, float theta) { theta = 2.0 * M_PI * theta / 360.0; mat2 R = mat2(cos(theta), -sin(theta), sin(theta), cos(theta)); return sdEllipse(R * (P - slides), vec2(0.23, 0.04)); } float sdhorn1(vec2 P, vec2 slides, float theta) { theta = 2.0 * M_PI * theta / 360.0; mat2 R = mat2(cos(theta), -sin(theta), sin(theta), cos(theta)); return sdEllipse(R * (P - slides), vec2(0.23, 0.04)); } float sdhorn2(vec2 P, vec2 slides, float theta) { theta = 2.0 * M_PI * theta / 360.0; mat2 R = mat2(cos(theta), -sin(theta), sin(theta), cos(theta)); return sdEllipse(R * (P - slides), vec2(0.23, 0.04)); } vec3 get_bg_color() { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec2 uv = vec2(gl_FragCoord.x * 0.5 + 0.5, gl_FragCoord.y * 0.5 + 0.5); float v1 = pow(snoise(vec3(uv * 0.2, 0.0)), 0.8) * 0.19; float v2 = pow(snoise(vec3(uv * 0.3, 1.0)), 0.8) * 0.2; float v3 = pow(snoise(vec3(uv * 0.3, u_time * 0.4)), 0.8) * 0.2; float v4 = pow(snoise(vec3(uv * 0.3, u_time * 1.2)), 0.8) * 0.2; float v = v1 + v2 + v3 + v4; vec3 out_color; if(st.y < 0.3){ out_color = vec3(st.y + 0.35 + v, st.y + 0.35 + v , st.y + 0.4 + v); }else{ out_color = vec3(0.65 + v, 0.65 + v, 0.70 + v); } return out_color; } vec3 get_slug_color(vec2 P) { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec3 out_color; vec3 bluepurple = vec3(0.4,0.0,0.9); vec3 redpurple = vec3(0.6,0.0,0.88); vec3 orange = vec3(0.75, 0.7, 0.0); vec3 yellow = vec3(0.77, 0.77, 0.0); vec3 white = vec3(0.95,0.95,0.99); float t = step(0.2, cnoise(10.0 * P)); out_color = mix(bluepurple, redpurple, t); if(st.y < 0.5 && st.y > 0.485){ t = step(0.65, cnoise(4.0 * P)); out_color = mix(white, bluepurple, t); } if(0.2 < st.x && st.x < 0.45 && 0.63 < st.y ){ t = step(0.1, cnoise(5.720 * P)); out_color = mix(yellow, orange, t); } return out_color; } float get_slug_mask(vec2 P) { P = P * 2.0 - 1.0; // -1.0 <= P <= 1.0 float mask = 1.0; mask *= step(0.0, sdbody1(P, vec2(0.090,-0.120), -1.0)); mask *= step(0.0, sdbody2(P, vec2(0.490,0.090), -22.840)); mask *= step(0.0, sdtale1(P, vec2(0.360,0.510), 40.0)); mask *= step(0.0, sdtale2(P, vec2(0.480,0.560), 20.0)); mask *= step(0.0, sdtale3(P, vec2(0.720,0.470), -30.0)); mask *= step(0.0, sdtale4(P, vec2(0.620,0.520), -18.0)); mask *= step(0.0, sdtale5(P, vec2(0.540,0.600), -80.0)); mask *= step(0.0, sdhorn1(P, vec2(-0.410,0.230), -80.0)); mask *= step(0.0, sdhorn2(P, vec2(-0.210,0.250), -100.0)); return mask; } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec4 bg_color = vec4(get_bg_color(), 1.0); vec4 slug_color = vec4(get_slug_color(st), 1.0); float mask = get_slug_mask(st.xy); colour_out = mix(slug_color, bg_color, mask); }
Hypselodoris variobranchia by lk
// credit: jikihakase (will show up on website) // sea slug: Blue_dragon-glaucus atlanticus uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; float area(vec2 center,float radius,vec2 pos,vec2 dir,float val){ vec2 dir2=pos-center; float c=dot(dir,dir2)/(length(dir2)*length(dir)); float theta=acos(c)*val; return step( radius*cos(theta)/(1.5*abs(acos(c))), distance( pos.xy, center.xy)-0.1); } vec3 hsvToRgb(float h, float s, float v) { // h: 0.0 - 360.0, s: 0.0 - 1.0, v: 0.0 - 1.0 float c = v * s; // float c = v * s; float h2 = h / 60.0; float x = c * (1.0 - abs(mod(h2, 2.0) - 1.0)); vec3 rgb = (v - c) * vec3(1.0, 1.0, 1.0); if (0.0 <= h2 && h2 < 1.0) { rgb += vec3(c, x, 0.0); } else if (1.0 <= h2 && h2 < 2.0) { rgb += vec3(x, c, 0.0); } else if (2.0 <= h2 && h2 < 3.0) { rgb += vec3(0.0, c, x); } else if (3.0 <= h2 && h2 < 4.0) { rgb += vec3(0.0, x, c); } else if (4.0 <= h2 && h2 < 5.0) { rgb += vec3(x, 0.0, c); } else if (5.0 <= h2 && h2 < 6.0) { rgb += vec3(c, 0.0, x); } return rgb; } vec4 color(vec2 pos,float time){ vec2 center=vec2(0.460,0.360); float h=sin(time-length(pos.xy-center.xy))*180.0+180.0; return vec4( hsvToRgb(h,1.0,1.0), 1.0 ); } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; float mask = 1.0; mask *= area(vec2(0.250,0.390),0.18,st.xy,vec2(-0.510,0.530),12.0); mask *= area(vec2(0.660,0.360),0.18,st.xy,vec2(0.480,0.240),12.0); mask *= area(vec2(0.500,0.620),0.35,st.xy,vec2(-0.070,-0.480),3.0); colour_out = color(st,u_time); colour_out *= 1.0-mask; }
Blue_dragon-glaucus atlanticus by
anonymous
// credit: will (will show up on website) // sea slug: Nembrotha_aurea uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; void main() { // vec2 st = gl_FragCoord.xy/u_resolution.xy; // float mask = 1.0; // mask *= step( 0.3, distance( st.xy, vec2(0.5, 0.4) ) ); // mask *= step( 0.25, distance( st.xy, vec2(0.6, 0.7) ) ); // mask *= step( 0.25, distance( st.xy, vec2(0.4, 0.7) ) ); // colour_out = vec4( 1.0, 1.0, 1.0, 1.0 ); // colour_out *= 1.0-mask; vec2 st = gl_FragCoord.xy / u_resolution.xy; vec3 color = vec3(0.0); vec2 pos = vec2(0.8, 0.5) - st; vec2 pos2 = vec2(0.4, 0.5) - st; float r = length(pos) * 3.5; float r2 = length(pos) * 4.5; float r3 = length(pos) * 5.5; float r4 = length(pos2) * 3.5; float a = atan(pos.y, pos.x); float a2 = atan(pos2.y, pos2.x); float f = cos(a * 3. + 0.5 * sin(u_time)); float f2 = cos(a * 3. + 0.5 * sin(u_time)); float f3 = cos(a * 3. + 0.5 * sin(u_time)); float f4 = cos(a2 * 3.) * .6; float f5 = cos(a2 * 3.) * .4; color = vec3(1. - smoothstep(f, f + 0.03, r)) * vec3(1.000,0.059,0.040); color += vec3(1. - smoothstep(f2, f2 + 0.03, r2)) * vec3(0.156,0.422,0.960); // use sine function to control the border of the body float wave_y_upper = 0.02 * sin(0.06 * gl_FragCoord.x); float wave_y_lower = (0.1 - 0.02 * sin(0.06 * gl_FragCoord.x)); float normalized_wave_upper = wave_y_upper + 0.63; float normalized_wave_lower = wave_y_lower + 0.23; vec2 center8 = vec2(0.48, 0.5); float radius8 = 0.33; float distance_8 = distance(center8, st); if (distance_8 <= radius8 && st.y <= normalized_wave_upper && st.y >= normalized_wave_lower) { color = vec3(0.044,0.201,0.553); } normalized_wave_upper = wave_y_upper + 0.63; normalized_wave_lower = wave_y_lower + 0.25; vec2 center = vec2(0.5, 0.5); float radius = 0.33; float distance_1 = distance(center, st); if (distance_1 <= radius && st.y <= normalized_wave_upper && st.y >= normalized_wave_lower) { color = vec3(0.275,0.455,0.686); } normalized_wave_upper = wave_y_upper + 0.61; normalized_wave_lower = wave_y_lower + 0.27; vec2 center2 = vec2(0.5, 0.5); float radius2 = 0.31; float distance_2 = distance(center2, st); if (distance_2 <= radius2 && st.y <= normalized_wave_upper && st.y >= normalized_wave_lower) { color = vec3(0.553,0.467,0.439); } normalized_wave_upper = wave_y_upper + 0.59; normalized_wave_lower = wave_y_lower + 0.29; vec2 center3 = vec2(0.5, 0.5); float radius3 = 0.31; float distance_3 = distance(center3, st); if (distance_3 <= radius3 && st.y <= normalized_wave_upper && st.y >= normalized_wave_lower) { color = vec3(0.325,0.082,0.051); } normalized_wave_upper = wave_y_upper + 0.57; normalized_wave_lower = wave_y_lower + 0.32; vec2 center7 = vec2(0.5, 0.5); float radius7 = 0.31; float distance_7 = distance(center7, st); if (distance_7 <= radius7 && st.y <= normalized_wave_upper && st.y >= normalized_wave_lower) { color = vec3(0.502,0.51,0.427); } normalized_wave_upper = wave_y_upper + 0.54; normalized_wave_lower = wave_y_lower + 0.34; vec2 center4 = vec2(0.5, 0.5); float radius4 = 0.31; float distance_4 = distance(center4, st); if (distance_4 <= radius4 && st.y <= normalized_wave_upper && st.y >= normalized_wave_lower) { color = vec3(0.169,0.035,0.027); } normalized_wave_upper = wave_y_upper + 0.52; normalized_wave_lower = wave_y_lower + 0.36; vec2 center5 = vec2(0.5, 0.5); float radius5 = 0.31; float distance_5 = distance(center5, st); if (distance_5 <= radius5 && st.y <= normalized_wave_upper && st.y >= normalized_wave_lower) { color = vec3(0.502,0.51,0.427); } normalized_wave_upper = wave_y_upper + 0.51; normalized_wave_lower = wave_y_lower + 0.37; vec2 center6 = vec2(0.5, 0.5); float radius6 = 0.31; float distance_6 = distance(center6, st); if (distance_5 <= radius5 && st.y <= normalized_wave_upper && st.y >= normalized_wave_lower) { color = vec3(0.18,0.031,0.031); } color += vec3(1. - smoothstep(f4, f4 + 0.02, r4)) * vec3(1.000,0.024,0.129); color += vec3(1. - smoothstep(f5, f5 + 0.02, r4)) * vec3(1.000,0.749,0.768); colour_out = vec4(color, 1.0); }
Nembrotha_aurea by will
// credit: Lachlan Moore // sea slug: Jorunna parva 'Sea Bunny' // photo link: https://www.treehugger.com/thmb/T_GgefX_8EQPCYbQlWvhEc0OtlE=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/sea-bunny-nudi-c8711bfe348b410ea48aad5260821f50.jpg uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; mat2 Rot(float a) { float s = sin(a); float c = cos(a); return mat2(c, -s, s, c); } float rand(vec2 a) { return fract(sin(dot(a.xy ,vec2(16.40294,32.456))) * 64048.481); } // Created by inigo quilez - iq/2014 // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. vec2 hash( vec2 p ) { p = vec2( dot(p,vec2(2127.1,81.17)), dot(p,vec2(1269.5,283.37)) ); return fract(sin(p)*43758.5453); } float noise( in vec2 p ) { vec2 i = floor( p ); vec2 f = fract( p ); vec2 u = f*f*(3.0-2.0*f); float n = mix( mix( dot( -1.0+2.0*hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ), dot( -1.0+2.0*hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x), mix( dot( -1.0+2.0*hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ), dot( -1.0+2.0*hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y); return 0.5 + 0.5*n; } float sdArc( in vec2 p, in vec2 sc, in float ra, float rb ) { // sc is the sin/cos of the arc's aperture p.x = abs(p.x); return ((sc.y*p.x>sc.x*p.y) ? length(p-sc*ra) : abs(length(p)-ra)) - rb; } float sdOrientedVesica( vec2 p, vec2 a, vec2 b, float w ) { float r = 0.5*length(b-a); float d = 0.5*(r*r-w*w)/w; vec2 v = (b-a)/r; vec2 c = (b+a)*0.5; vec2 q = 0.5*abs(mat2(v.y,v.x,-v.x,v.y)*(p-c)); vec3 h = (r*q.x<d*(q.y-r)) ? vec3(0.0,r,0.0) : vec3(-d,0.0,d+w); return length( q-h.xy) - h.z; } void main() { // set up vars vec2 st = (2.0*gl_FragCoord.xy-u_resolution.xy)/u_resolution.y; float ratio = u_resolution.x / u_resolution.y; vec3 col = vec3(0.0, 0.0, 0.0); vec2 tuv = st; tuv -= .5; // rotate with Noise float degree = noise(vec2(u_time*.1, tuv.x*tuv.y)); tuv.y *= 1./ratio; tuv *= Rot(radians((degree-.5)*720.+180.)); tuv.y *= ratio; // Wave warp with sin float frequency = 5.; float amplitude = 30.; float speed = u_time * 2.; tuv.x += sin(tuv.y*frequency+speed)/amplitude; tuv.y += sin(tuv.x*frequency*1.5+speed)/(amplitude*.5); // body simple arc float d = sdArc(st + vec2(0.01,0.79), vec2(0.7,0.7), 0.772, 0.316) - 0.1; // ears float k = sdOrientedVesica(st +vec2(-0.050,0.450), vec2(0.630,0.750), vec2(0.700,0.300), 0.108); k = min(k, sdOrientedVesica(st +vec2(0.320,0.650), vec2(0.340,0.580), vec2(0.700,0.300), 0.108)); k = min(k, sdOrientedVesica(st +vec2(1.2,0.4), vec2(0.280,0.610), vec2(0.390,0.340), 0.052)); k = min(k, sdOrientedVesica(st +vec2(1.25,0.4), vec2(0.280,0.610), vec2(0.390,0.340), 0.052)); k = min(k, sdOrientedVesica(st +vec2(1.15,0.35), vec2(0.280,0.610), vec2(0.390,0.340), 0.052)); k = min(k, sdOrientedVesica(st +vec2(1.1,0.35), vec2(0.280,0.610), vec2(0.390,0.340), 0.052)); // colour if(d > 0.0 && k > 0.0) { vec3 b1 = vec3(0.036,0.220,0.985); vec3 b2 = vec3(0.097,0.727,0.985); vec3 l1 = mix(b1, b2, smoothstep(-0.868, 0.744, (tuv*Rot(radians(-5.0))).x)); vec3 w1 = vec3(0.353,0.794,0.985); vec3 w2 = vec3(0.441,0.664,0.985); vec3 l2 = mix(w1, w2, smoothstep(-0.492, 0.632, (tuv*Rot(radians(-5.0))).x)); col = mix(l1, l2, smoothstep(-0.876, 1.756, tuv.y)); } else if (k < 0.0) { vec3 start = vec3(1.0, 1.0, 1.0); vec3 end = vec3(0.0, 0.0, 0.0); col = mix(start, end, smoothstep(-0.3, 0.3, st.y)); } else { vec2 uv = gl_FragCoord.xy / 20.0; uv -= u_time * 0.3; vec2 g = fract(uv) - 0.4; float off = rand(ceil(uv)); float t = u_time * (off - 0.5); float angle = 1.1 + t*7.0 + off ; g += vec2(sin(angle),cos(angle)) * 0.3; float w = (sin((noise(uv))+t)+1.0)*0.24; float e = 1.0-smoothstep(length(g)*2.5,length(g)*2.5+0.1,w); col = vec3(e); } colour_out = vec4(col,1.0); }
Jorunna parva 'Sea Bunny' by Lachlan Moore
// // Name you want to appear with your shader (can be real name or pseudonym): hoangxcao // 【optional】Scientific name of the sea slug: Felimare Californiensis // precision mediump float; uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; vec2 rotate(vec2 point, float angle) { mat2 rotationMatrix = mat2(cos(angle), -sin(angle), sin(angle), cos(angle)); return rotationMatrix * point; } // // Description : Array and textureless GLSL 2D simplex noise function. // Author : Ian McEwan, Ashima Arts. // Maintainer : stegu // Lastmod : 20110822 (ijm) // License : Copyright (C) 2011 Ashima Arts. All rights reserved. // Distributed under the MIT License. See LICENSE file. // https://github.com/ashima/webgl-noise // https://github.com/stegu/webgl-noise // vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 permute(vec3 x) { return mod289(((x*34.0)+10.0)*x); } float snoise(vec2 v) { const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) -0.577350269189626, // -1.0 + 2.0 * C.x 0.024390243902439); // 1.0 / 41.0 // First corner vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); // Other corners vec2 i1; //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 //i1.y = 1.0 - i1.x; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); // x0 = x0 - 0.0 + 0.0 * C.xx ; // x1 = x0 - i1 + 1.0 * C.xx ; // x2 = x0 - 1.0 + 2.0 * C.xx ; vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; // Permutations i = mod289(i); // Avoid truncation effects in permutation vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; // Gradients: 41 points uniformly over a line, mapped onto a diamond. // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; // Normalise gradients implicitly by scaling m // Approximation of: m *= inversesqrt( a0*a0 + h*h ); m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); // Compute final noise value at P vec3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } // // Description : Array and textureless GLSL 2D/3D/4D simplex // noise functions. // Author : Ian McEwan, Ashima Arts. // Maintainer : stegu // Lastmod : 20201014 (stegu) // License : Copyright (C) 2011 Ashima Arts. All rights reserved. // Distributed under the MIT License. See LICENSE file. // https://github.com/ashima/webgl-noise // https://github.com/stegu/webgl-noise // vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 permute(vec4 x) { return mod289(((x*34.0)+10.0)*x); } vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } float snoise(vec3 v) { const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); // First corner vec3 i = floor(v + dot(v, C.yyy) ); vec3 x0 = v - i + dot(i, C.xxx) ; // Other corners vec3 g = step(x0.yzx, x0.xyz); vec3 l = 1.0 - g; vec3 i1 = min( g.xyz, l.zxy ); vec3 i2 = max( g.xyz, l.zxy ); // x0 = x0 - 0.0 + 0.0 * C.xxx; // x1 = x0 - i1 + 1.0 * C.xxx; // x2 = x0 - i2 + 2.0 * C.xxx; // x3 = x0 - 1.0 + 3.0 * C.xxx; vec3 x1 = x0 - i1 + C.xxx; vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y // Permutations i = mod289(i); vec4 p = permute( permute( permute( i.z + vec4(0.0, i1.z, i2.z, 1.0 )) + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); // Gradients: 7x7 points over a square, mapped onto an octahedron. // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) float n_ = 0.142857142857; // 1.0/7.0 vec3 ns = n_ * D.wyz - D.xzx; vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) vec4 x_ = floor(j * ns.z); vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) vec4 x = x_ *ns.x + ns.yyyy; vec4 y = y_ *ns.x + ns.yyyy; vec4 h = 1.0 - abs(x) - abs(y); vec4 b0 = vec4( x.xy, y.xy ); vec4 b1 = vec4( x.zw, y.zw ); //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; vec4 s0 = floor(b0)*2.0 + 1.0; vec4 s1 = floor(b1)*2.0 + 1.0; vec4 sh = -step(h, vec4(0.0)); vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; vec3 p0 = vec3(a0.xy,h.x); vec3 p1 = vec3(a0.zw,h.y); vec3 p2 = vec3(a1.xy,h.z); vec3 p3 = vec3(a1.zw,h.w); //Normalise gradients vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); p0 *= norm.x; p1 *= norm.y; p2 *= norm.z; p3 *= norm.w; // Mix final noise value vec4 m = max(0.5 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); m = m * m; return 105.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) ); } float cro(in vec2 a, in vec2 b ) { return a.x*b.y - a.y*b.x; } /////////////// K.jpg's Re-oriented 8-Point BCC Noise (OpenSimplex2S) //////////////// ////////////////////// Output: vec4(dF/dx, dF/dy, dF/dz, value) ////////////////////// // Gradient set is a normalized expanded rhombic dodecahedron vec3 grad(float hash) { // Random vertex of a cube, +/- 1 each vec3 cube = mod(floor(hash / vec3(1.0, 2.0, 4.0)), 2.0) * 2.0 - 1.0; // Random edge of the three edges connected to that vertex // Also a cuboctahedral vertex // And corresponds to the face of its dual, the rhombic dodecahedron vec3 cuboct = cube; cuboct[int(hash / 16.0)] = 0.0; // In a funky way, pick one of the four points on the rhombic face float type = mod(floor(hash / 8.0), 2.0); vec3 rhomb = (1.0 - type) * cube + type * (cuboct + cross(cube, cuboct)); // Expand it so that the new edges are the same length // as the existing ones vec3 grad = cuboct * 1.22474487139 + rhomb; // To make all gradients the same length, we only need to shorten the // second type of vector. We also put in the whole noise scale constant. // The compiler should reduce it into the existing floats. I think. grad *= (1.0 - 0.042942436724648037 * type) * 3.5946317686139184; return grad; } // BCC lattice split up into 2 cube lattices vec4 openSimplex2SDerivativesPart(vec3 X) { vec3 b = floor(X); vec4 i4 = vec4(X - b, 2.5); // Pick between each pair of oppposite corners in the cube. vec3 v1 = b + floor(dot(i4, vec4(.25))); vec3 v2 = b + vec3(1, 0, 0) + vec3(-1, 1, 1) * floor(dot(i4, vec4(-.25, .25, .25, .35))); vec3 v3 = b + vec3(0, 1, 0) + vec3(1, -1, 1) * floor(dot(i4, vec4(.25, -.25, .25, .35))); vec3 v4 = b + vec3(0, 0, 1) + vec3(1, 1, -1) * floor(dot(i4, vec4(.25, .25, -.25, .35))); // Gradient hashes for the four vertices in this half-lattice. vec4 hashes = permute(mod(vec4(v1.x, v2.x, v3.x, v4.x), 289.0)); hashes = permute(mod(hashes + vec4(v1.y, v2.y, v3.y, v4.y), 289.0)); hashes = mod(permute(mod(hashes + vec4(v1.z, v2.z, v3.z, v4.z), 289.0)), 48.0); // Gradient extrapolations & kernel function vec3 d1 = X - v1; vec3 d2 = X - v2; vec3 d3 = X - v3; vec3 d4 = X - v4; vec4 a = max(0.75 - vec4(dot(d1, d1), dot(d2, d2), dot(d3, d3), dot(d4, d4)), 0.0); vec4 aa = a * a; vec4 aaaa = aa * aa; vec3 g1 = grad(hashes.x); vec3 g2 = grad(hashes.y); vec3 g3 = grad(hashes.z); vec3 g4 = grad(hashes.w); vec4 extrapolations = vec4(dot(d1, g1), dot(d2, g2), dot(d3, g3), dot(d4, g4)); // Derivatives of the noise vec3 derivative = -8.0 * mat4x3(d1, d2, d3, d4) * (aa * a * extrapolations) + mat4x3(g1, g2, g3, g4) * aaaa; // Return it all as a vec4 return vec4(derivative, dot(aaaa, extrapolations)); } // Use this if you don't want Z to look different from X and Y vec4 openSimplex2SDerivatives_Conventional(vec3 X) { X = dot(X, vec3(2.0/3.0)) - X; vec4 result = openSimplex2SDerivativesPart(X) + openSimplex2SDerivativesPart(X + 144.5); return vec4(dot(result.xyz, vec3(2.0/3.0)) - result.xyz, result.w); } // Use this if you want to show X and Y in a plane, then use Z for time, vertical, etc. vec4 openSimplex2SDerivatives_ImproveXY(vec3 X) { // Not a skew transform. mat3 orthonormalMap = mat3( 0.788675134594813, -0.211324865405187, -0.577350269189626, -0.211324865405187, 0.788675134594813, -0.577350269189626, 0.577350269189626, 0.577350269189626, 0.577350269189626); X = orthonormalMap * X; vec4 result = openSimplex2SDerivativesPart(X) + openSimplex2SDerivativesPart(X + 144.5); return vec4(result.xyz * orthonormalMap, result.w); } //////////////////////////////// End noise code //////////////////////////////// // // Description : Inigo Quilez’s Blog on 2D distance functions. // Author : Inigo Quilez. // License : https://iquilezles.org/articles/distfunctions2d/ // float msign(in float x) { return (x<0.0)?-1.0:1.0; } // Ellipse float sdEllipse( vec2 p, in vec2 ab ) { //if( ab.x==ab.y ) return length(p)-ab.x; p = abs( p ); if( p.x>p.y ){ p=p.yx; ab=ab.yx; } float l = ab.y*ab.y - ab.x*ab.x; float m = ab.x*p.x/l; float n = ab.y*p.y/l; float m2 = m*m; float n2 = n*n; float c = (m2+n2-1.0)/3.0; float c3 = c*c*c; float d = c3 + m2*n2; float q = d + m2*n2; float g = m + m *n2; float co; if( d<0.0 ) { float h = acos(q/c3)/3.0; float s = cos(h) + 2.0; float t = sin(h) * sqrt(3.0); float rx = sqrt( m2-c*(s+t) ); float ry = sqrt( m2-c*(s-t) ); co = ry + sign(l)*rx + abs(g)/(rx*ry); } else { float h = 2.0*m*n*sqrt(d); float s = msign(q+h)*pow( abs(q+h), 1.0/3.0 ); float t = msign(q-h)*pow( abs(q-h), 1.0/3.0 ); float rx = -(s+t) - c*4.0 + 2.0*m2; float ry = (s-t)*sqrt(3.0); float rm = sqrt( rx*rx + ry*ry ); co = ry/sqrt(rm-rx) + 2.0*g/rm; } co = (co-m)/2.0; float si = sqrt( max(1.0-co*co,0.0) ); vec2 r = ab * vec2(co,si); return length(r-p) * msign(p.y-r.y); } // Arc float sdArc( in vec2 p, in vec2 sc, in float ra, float rb, bool mirrorX ) { p.x = abs(p.x); if (mirrorX) { // Mirroring point 'p' across the x-axis p.y = -p.y; } return ((sc.y*p.x>sc.x*p.y) ? length(p-sc*ra) : abs(length(p)-ra)) - rb; } // Blobby cross float sdBlobbyCross( in vec2 pos, float he ) { pos = abs(pos); pos = vec2(abs(pos.x-pos.y),1.0-pos.x-pos.y)/sqrt(2.0); float p = (he-pos.y-0.25/he)/(6.0*he); float q = pos.x/(he*he*16.0); float h = q*q - p*p*p; float x; if( h>0.0 ) { float r = sqrt(h); x = pow(q+r,1.0/3.0) - pow(abs(q-r),1.0/3.0)*sign(r-q); } else { float r = sqrt(p); x = 2.0*r*cos(acos(q/(p*r))/3.0); } x = min(x,sqrt(2.0)/2.0); vec2 z = vec2(x,he*(1.0-2.0*x*x)) - pos; return length(z) * sign(z.y); } // Heart float dot2( in vec2 v ) { return dot(v,v); } float sdHeart( in vec2 p ) { p.x = abs(p.x); if( p.y+p.x>1.0 ) return sqrt(dot2(p-vec2(0.25,0.75))) - sqrt(2.0)/4.0; return sqrt(min(dot2(p-vec2(0.00,1.00)), dot2(p-0.5*max(p.x+p.y,0.0)))) * sign(p.x-p.y); } float color(vec2 xy) { return 0.7 * snoise(vec3(xy, 0.3*u_time)); } void main() { // Normalize coordinates to range [0, 1] vec2 uv = (gl_FragCoord.xy / u_resolution.xy); // Center the coordinates uv -= 0.5; // Define the sea slug shape using a signed distance function (SDF) float sdf = sdEllipse(uv, vec2(0.4, 0.18)); // Define the antennae vec2 antenna1Coord = 3.0 * uv; antenna1Coord.x += 1.2; antenna1Coord.y += 0.4; vec2 sc1 = vec2(sin(1.0),cos(1.0)); float antenna1 = sdArc(antenna1Coord, sc1, 0.3, 0.01, false); vec2 antenna2Coord = 3.0*uv; antenna2Coord.x +=1.2; antenna2Coord.y -=0.4; vec2 sc2 = vec2(sin(1.0),cos(1.0)); float antenna2 = sdArc(antenna2Coord, sc2, 0.3, 0.01, true); // Define the tentacles vec2 tentacle1Coord = 8.0 * uv; tentacle1Coord.y -= 1.1; tentacle1Coord = rotate(tentacle1Coord, radians(45.0)); // Apply rotation float tentacle1 = sdBlobbyCross(tentacle1Coord, 0.6) - 0.15; vec2 tentacle2Coord = 8.0 * uv; tentacle2Coord.y += 1.1; tentacle2Coord = rotate(tentacle2Coord, radians(45.0)); // Apply rotation float tentacle2 = sdBlobbyCross( tentacle2Coord, 0.6 ) - 0.15; // Define the eyes vec2 eyesPos = 8.0 * uv; eyesPos.x += 2.2; eyesPos = rotate(eyesPos, radians(90.0)); // Apply rotation float eyes = sdHeart(eyesPos); // Combining shapes float anteannea = min(antenna1, antenna2); float tentacles = min(tentacle1, tentacle2); sdf = min(sdf, min(min(anteannea, tentacles), eyes)); // Add Perlin noise to the sea slug float noiseValue = snoise(vec3(uv * 2.0, u_time * 0.1)); float sdfWithNoise = sdf + 0.1 * noiseValue; // Apply anti-aliasing to the edges of the shape float aa = smoothstep(0.02, 0.01, sdfWithNoise); // // Define the color of the sea slug with a gradient from black to dark blue // // Scale the uv coordinates to create an ellipse uv.y *= 2.5; // Calculate the distance from the center float distance = length(uv); // Calculate the intensity using the exponential function float intensity = exp(-distance); // Define the colors vec4 centerCol = vec4(0.2, 0.2, 1.0, 1.0); vec4 circumferenceCol = vec4(0.0, 0.0, 0.0, 1.0); // Define a pattern for the sea slug body with noise vec2 st = gl_FragCoord.xy / u_resolution.xy; st.x *= u_resolution.x / u_resolution.y; vec3 color = vec3(0.0); vec2 pos = vec2(st * 3.0); float DF = 0.0; // Add a random position float a = 0.0; vec2 vel = vec2(u_time * 0.1); DF += snoise(pos + vel) * 0.25 + 0.25; // Add a random position a = snoise(pos * vec2(cos(u_time * 0.15), sin(u_time * 0.1)) * 0.1) * 3.1415; vel = vec2(cos(a), sin(a)); DF += snoise(pos + vel) * 0.25+.25; color = vec3(1.0, 1.0, 0.0) * smoothstep(0.7, 0.75, fract(DF)); // Set the background color to dark blue vec3 background = mix(centerCol, circumferenceCol, intensity).xyz; color = mix(background, color, color); // // Drawing the ocean background // // Normalized pixel coordinates (from 0 to 1 on largest axis) vec2 uv2 = gl_FragCoord.xy / max(u_resolution.x, u_resolution.y) * 8.0; // Initial input point vec3 X = vec3(uv2, mod(u_time, 578.0) * 0.8660254037844386); // Evaluate noise once vec4 noiseResult = openSimplex2SDerivatives_ImproveXY(X); // Evaluate noise again with the derivative warping the domain // Might be able to approximate this by fitting to a curve instead noiseResult = openSimplex2SDerivatives_ImproveXY(X - noiseResult.xyz / 16.0); float value = noiseResult.w; // Time varying pixel color vec3 col = vec3(.431, 0.8, 1.0) * (0.5 + 0.5 * value); // Set the final fragment color for the background vec3 finalColor = mix(col, color, aa); // Set the final fragment color colour_out = vec4(finalColor, 1.0); }
Felimare Californiensis by hoangxcao
// credit: wh // sea slug: Nembrotha aurea Bernard Picton uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; float sdArc( in vec2 p, in vec2 sc, in float ra, float rb ) { // sc is the sin/cos of the arc's aperture p.x = abs(p.x); return ((sc.y*p.x>sc.x*p.y) ? length(p-sc*ra) : abs(length(p)-ra)) - rb; } float sdf( vec2 p ) { return sdArc(p, vec2(0.940,0.330),0.596,0.228); } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; st-=0.508; st.y+=0.220; st*=2.0; float d = sdf(st.xy); float mask = 0.984; float mask1 = -0.008; mask1 -= sin(u_time*0.8)*0.16; mask *= step( 0.188, distance( st.xy+st.y*1.132, vec2(1.000,0.300) ) ); mask *= step( 0.092, distance( st.xy, vec2(0.510,0.060) ) ); mask *= step( 0.220, distance( st.xy+st.y*3.452+st.x*st.x, vec2(1.950,2.970) ) ); mask *= step( 0.188, distance( st.xy+st.y*1.132, vec2(0.400,1.640) ) ); mask *= step( 0.188, distance( st.xy+st.x*1.132, vec2(-0.630,0.590) ) ); vec3 col = vec3(1.000,0.967,0.894) - sign(d) * vec3(0.700,0.200,0.051); col *= 0.928 - exp(-3.688*abs(d)); col *= 1.160 + 0.200*cos(155.392*d); col = mix( col, vec3(1.000,0.984,0.964), 1.0-smoothstep(0.0,0.018,abs(d)) ); colour_out = vec4(col,1.0); colour_out.x+=1.0-mask; colour_out +=mask1; }
Nembrotha aurea Bernard Picton by
wh
// credit: Ruijie Ren (will show up on website) // sea slug: Fellimara Picta Nudibranch uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; float cro(vec2 a,vec2 b ) { return a.x*b.y - a.y*b.x; } float sdUnevenCapsule(vec2 p,vec2 pa,vec2 pb,float ra,float rb ) { p -= pa; pb -= pa; float h = dot(pb,pb); vec2 q = vec2( dot(p,vec2(pb.y,-pb.x)), dot(p,pb) )/h; //----------- q.x = abs(q.x); float b = ra-rb; vec2 c = vec2(sqrt(h-b*b),b); float k = cro(c,q); float m = dot(c,q); float n = dot(q,q); if( k < 0.0 ) return sqrt(h*(n )) - ra; else if( k > c.x ) return sqrt(h*(n+1.0-2.0*q.y)) - rb; return m - ra; } // b.x = width // b.y = height // r.x = roundness top-right // r.y = roundness boottom-right // r.z = roundness top-left // r.w = roundness bottom-left float sdRoundBox( in vec2 p, in vec2 b, in vec4 r ) { r.xy = (p.x>0.0)?r.xy : r.zw; r.x = (p.y>0.0)?r.x : r.y; vec2 q = abs(p)-b+r.x; return min(max(q.x,q.y),0.0) + length(max(q,0.0)) - r.x; } float get_edge_mask(vec2 p) { vec2 si = vec2(0.5+ 0.01*sin(u_time),0.9+ 0.05*sin(u_time)) ; vec4 ra = 0.4 + 0.2*cos( 1.0*u_time + vec4(3,1,1,2) ); ra = min(ra,min(si.x,si.y)); vec2 b = vec2(0.5,0.9); vec4 r = vec4(0.0,0.0,0.0,0.0); float r1 = 0.45*(1.+0.1*sin(u_time)); float r2 = 0.35*(1.-0.1*sin(u_time)); float d = step( 0.001, sdRoundBox( p, si, ra )); return d; } float get_body_mask(vec2 p) { vec2 v1 = vec2(0.0,-0.40); vec2 v2 = vec2(0.0,0.450); float r1 = 0.45*(1.+0.1*sin(u_time)); float r2 = 0.35*(1.-0.1*sin(u_time)); float d = step( 0.01,sdUnevenCapsule( p, v1, v2, r1, r2 )); return d; } float get_tentacle_left(vec2 p) { vec2 v1 = vec2(-0.5,-0.40); vec2 v2 = vec2(-0.9+0.02*sin(u_time),0.1-0.02*sin(u_time)); float r1 = 0.04; float r2 = 0.02; vec2 p2 = vec2(p.x - 0.2, p.y - 0.8); float d = step( 0.01,sdUnevenCapsule( p2, v1, v2, r1, r2 )); return d; } float get_tentacle_right(vec2 p) { vec2 v1 = ( vec2(0.5,-0.40) + 0.0 ); vec2 v2 = vec2(0.8+0.02*sin(u_time),-0.04*sin(u_time)); float r1 = 0.04; float r2 = 0.02; vec2 p2 = vec2(p.x + 0.2,p.y - 0.8); float d = step( 0.01,sdUnevenCapsule( p2, v1, v2, r1, r2 )); return d; } float get_mask(vec2 st, vec2 p) { float mask = 1.0; mask *= get_body_mask(p); mask *= get_tentacle_left(p); mask *= get_tentacle_right(p); mask *= get_edge_mask(p); return mask; } vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 permute(vec3 x) { return mod289(((x*34.0)+10.0)*x); } float snoise(vec2 v) { const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) -0.577350269189626, // -1.0 + 2.0 * C.x 0.024390243902439); // 1.0 / 41.0 // First corner vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); // Other corners vec2 i1; //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 //i1.y = 1.0 - i1.x; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); // x0 = x0 - 0.0 + 0.0 * C.xx ; // x1 = x0 - i1 + 1.0 * C.xx ; // x2 = x0 - 1.0 + 2.0 * C.xx ; vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; // Permutations i = mod289(i); // Avoid truncation effects in permutation vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; // Gradients: 41 points uniformly over a line, mapped onto a diamond. // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; // Normalise gradients implicitly by scaling m // Approximation of: m *= inversesqrt( a0*a0 + h*h ); m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); // Compute final noise value at P vec3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } float marbleturbulence( vec2 p ) { /* Same as the turbulence before. */ float f = 0.0, scale; for (int i=0; i<4; i++) { scale = pow( pow(2.0, 4.0/3.0), float(i) ); f += abs( snoise( p * scale ) ) / scale; } return f; } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec2 p = st * 2.0 - 1.0; float foreground_mask = get_mask(st,p); vec4 tentacle_c = vec4(0.3176, 0.1608, 0.9412, 1.0); vec4 body_c = vec4(0.1333, 0.0627, 0.6667, 1.0); vec4 strip_c = vec4(0.9804, 0.9686, 0.2235, 1.0); vec4 edge_c = vec4(0.8196, 0.7961, 0.0941, 1.0); float n = marbleturbulence( st ); float strip = 0.2+sin( (st.x * u_resolution.x) / (3.5+0.2*sin(u_time)) + 5. * n ); float dot_mask = snoise(st*35. + .3*sin(u_time) ); float body_mask = 1.0; body_mask *= get_body_mask(p); float tentacle_mask = 1.0; tentacle_mask *= get_tentacle_left(p); tentacle_mask *= get_tentacle_right(p); vec4 strip_mix = mix(body_c, strip_c, vec4(step(1.5, (strip+dot_mask)*(1.0 - body_mask)*tentacle_mask ))); vec4 colour_layer = mix(strip_mix, vec4(1, 1, 1, 1.0), foreground_mask); float edge_mask = 1.0; edge_mask *= get_edge_mask(p); colour_layer = mix(colour_layer, edge_c, (body_mask-edge_mask)); colour_out = mix(tentacle_c, colour_layer, tentacle_mask); }
Fellimara Picta Nudibranch by Ruijie Ren
// credit: Eibaloch // sea slug: Fellimara picta Victor Micallef uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; // GLSL textureless classic 2D noise "cnoise", // with an RSL-style periodic variant "pnoise". // Author: Stefan Gustavson (stefan.gustavson@liu.se) // Version: 2011-08-22 // // Many thanks to Ian McEwan of Ashima Arts for the // ideas for permutation and gradient selection. // // Copyright (c) 2011 Stefan Gustavson. All rights reserved. // Distributed under the MIT license. See LICENSE file. // https://github.com/stegu/webgl-noise float cro(in vec2 a, in vec2 b ) { return a.x*b.y - a.y*b.x; } vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 permute(vec4 x) { return mod289(((x*34.0)+10.0)*x); } vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } vec2 fade(vec2 t) { return t*t*t*(t*(t*6.0-15.0)+10.0); } //Classic Perlin Noise float cnoise(vec2 P) { vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0); vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0); Pi = mod289(Pi); // To avoid truncation effects in permutation vec4 ix = Pi.xzxz; vec4 iy = Pi.yyww; vec4 fx = Pf.xzxz; vec4 fy = Pf.yyww; vec4 i = permute(permute(ix) + iy); vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0 ; vec4 gy = abs(gx) - 0.5 ; vec4 tx = floor(gx + 0.5); gx = gx - tx; vec2 g00 = vec2(gx.x,gy.x); vec2 g10 = vec2(gx.y,gy.y); vec2 g01 = vec2(gx.z,gy.z); vec2 g11 = vec2(gx.w,gy.w); vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); g00 *= norm.x; g01 *= norm.y; g10 *= norm.z; g11 *= norm.w; float n00 = dot(g00, vec2(fx.x, fy.x)); float n10 = dot(g10, vec2(fx.y, fy.y)); float n01 = dot(g01, vec2(fx.z, fy.z)); float n11 = dot(g11, vec2(fx.w, fy.w)); vec2 fade_xy = fade(Pf.xy); vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x); float n_xy = mix(n_x.x, n_x.y, fade_xy.y); return 2.3 * n_xy; } // Copyright © 2018 Inigo Quilez // and https://iquilezles.org/articles/distfunctions2d float sdUnevenCapsule( in vec2 p, in vec2 pa, in vec2 pb, in float ra, in float rb ) { p -= pa; pb -= pa; float h = dot(pb,pb); vec2 q = vec2( dot(p,vec2(pb.y,-pb.x)), dot(p,pb) )/h; //----------- q.x = abs(q.x); float b = ra-rb; vec2 c = vec2(sqrt(h-b*b),b); float k = cro(c,q); float m = dot(c,q); float n = dot(q,q); if( k < 0.0 ) return sqrt(h*(n )) - ra; else if( k > c.x ) return sqrt(h*(n+1.0-2.0*q.y)) - rb; return m - ra; } float sdOrientedVesica( vec2 p, vec2 a, vec2 b, float w ) { float r = 0.5*length(b-a); float d = 0.5*(r*r-w*w)/w; vec2 v = (b-a)/r; vec2 c = (b+a)*0.5; vec2 q = 0.5*abs(mat2(v.y,v.x,-v.x,v.y)*(p-c)); vec3 h = (r*q.x<d*(q.y-r)) ? vec3(0.0,r,0.0) : vec3(-d,0.0,d+w); return length( q-h.xy) - h.z; } float sdCircle( vec2 p, float r ) { return length(p)-r; } float sdUnion( float d1, float d2 ) { return min( d1, d2 ); } float sdDifference( float d1, float d2 ) { return max( -d1, d2 ); /* Remove d1 from d2 */ } float sdIntersection( float d1, float d2 ) { return max( d1, d2 ); } float sdfAntenna_front( vec2 p ) { vec4 v1 = vec4(-3.6,2.00,-3.0,.20) ; float r1 = 0.3+0.1*sin(u_time); float r2 = 0.5+0.1*sin(1.0+2.3); float d = sdUnevenCapsule( p, v1.xy, v1.zw, r1, r2 ); return d; } float sdfAntenna_back( vec2 p ) { vec4 v1 = vec4(-2.,2.00,-2.0,.20) ; float r1 = 0.3+0.1*sin(u_time); float r2 = 0.5+0.1*sin(1.0+2.3); float d = sdUnevenCapsule( p, v1.xy, v1.zw, r1, r2 ); return d; } float sdfbody1( vec2 p ){ //slugPosition p-=vec2(-1.,-2.0); //head float h = sdCircle(p - vec2(-1.6,-0.7),2.5); //Different body parts vec4 v1 = vec4(-.9,.5,5.50,-1.8) ; float r1 = 7.*0.3+0.1*sin(u_time); float r2 = 3.*0.5+0.1*sin(1.0+2.3); float d_1 = sdUnevenCapsule( p, v1.xy, v1.zw, r1, r2 ); vec4 v2 = vec4 (4.,-1.8,-1,-1.50) ; float r2_1 = 5.*0.3+0.1*sin(u_time); float r2_2 = 3.*0.5+0.1*sin(1.0+2.3); float d_2 = sdUnevenCapsule( p, v2.xy, v2.zw, r2_1, r2_2 ); vec4 v3 = vec4 (-1.,-2.8,-1,.50) ; float r3_1 = 2.*0.3+0.1*sin(u_time); float r3_2 = 3.*0.5+0.1*sin(1.0+2.3); float d_3 = sdUnevenCapsule( p, v3.xy, v3.zw, r3_1, r3_2 ); vec4 v4 = vec4 (0.5,-2.99,-1,.50) ; float r4_1 = 2.*0.3+0.1*sin(u_time); float r4_2 = 3.*0.5+0.1*sin(1.0+2.3); float d_4 = sdUnevenCapsule( p, v4.xy, v4.zw, r4_1, r4_2 ); vec4 v5 = vec4 (1.8,-2.8,-1,.50) ; float r5_1 = 2.*0.3+0.1*sin(u_time); float r5_2 = 3.*0.5+0.1*sin(1.0+2.3); float d_5 = sdUnevenCapsule( p, v5.xy, v5.zw, r5_1, r5_2 ); //3rd part float e_1 = sdOrientedVesica(p-vec2(-5.,-3.), .1* vec2(3.,3.00 ),2.1* vec2(3.,2.00 ),7.*0.40*(0.5+0.495*cos(89.))); float e_2 = sdOrientedVesica(p-vec2(3.5,-2.), .1* vec2(4.,3.00 ),2.1*vec2(2.,00 ),4.*0.40*(0.5+0.495*cos(89.))); //Combing shapes float k_1 = sdUnion(d_1,d_2); float k_2 = sdUnion(k_1,h); float k_3 = sdUnion(k_2,e_1); float k_4 = sdUnion(k_3,e_2); float k_5 = sdUnion(k_4,d_3); float k_6 = sdUnion(k_5,d_4); float k_7 = sdUnion(k_6,d_5); return k_7; } float t_1(vec2 uv){ float m = cnoise(vec2(cnoise(uv*2.),cnoise(uv*-1.))); return m; } vec2 random2( vec2 p ) { return fract(sin(vec2(dot(p,vec2(127.1,311.7)),dot(p,vec2(269.5,183.3))))*43758.5453); } void main() { vec2 uv = gl_FragCoord.xy/u_resolution.xy; uv = uv-0.5; uv = uv * u_resolution/36.; vec3 color = vec3(0.34, 0.3, 0.44); vec2 center = vec2(0,0); float mask_1 = sdfAntenna_front(uv); float mask_3 = sdfAntenna_back(uv); float mask_2 = sdfbody1(uv); //Additional texture noise (Book of Shaders code) vec3 bg_color = vec3(0.16, 0.4, 0.59); vec2 st = uv; st *= .9; // Tile the space vec2 i_st = floor(st); vec2 f_st = fract(st); float m_dist = 1.; // minimum distance for (int y= -1; y <= 1; y++) { for (int x= -1; x <= 1; x++) { // Neighbor place in the grid vec2 neighbor = vec2(float(x),float(y)); // Random position from current + neighbor place in the grid vec2 point = random2(i_st + neighbor); // Animate the point point = 0.5 + 0.5*sin(u_time + 6.2831*point); // Vector between the pixel and the point vec2 diff = neighbor + point - f_st; // Distance to the point float dist = length(diff); // Keep the closer distance m_dist = min(m_dist, dist); } } // Draw the min distance (distance field) bg_color += m_dist; // Show isolines bg_color -= step(.7,abs(sin(27.0*m_dist)))*.5; //Colors vec3 yellow = vec3(0.4824, 0.3569, 0.1412); vec3 darkblue = vec3(0.0078, 0.1569, 0.3176)*bg_color; vec3 lightblue = vec3(0.2353, 0.4039, 0.7765); //Color application to masks float t = step(0.05, cnoise(4.0*uv+uv.xy)); float t_1 = t_1(uv); float d_1 = 0.; vec3 Antenna_color_1 = mask_1 > 0.0 ? lightblue*-uv.y/10. : mix(yellow, darkblue,smoothstep( 1.,3.4,length(center - uv.xy)) ); vec3 body_color_2 = max(-mask_1,mask_2) > 0.0 ? vec3(0) : mix(darkblue, yellow-0. ,t+t_1+.9+0.3*sin(u_time)); vec3 Antenna_back_color_3 = max(-mask_2,mask_3) >0.0? vec3(0) : darkblue; //White Border color = mix(vec3(0.9608, 0.9294, 0.9294),Antenna_color_1 + body_color_2 +Antenna_back_color_3, step(0.09, abs(sdDifference(sdDifference(mask_1,mask_2),sdUnion(mask_2,mask_1))))); color += mix(vec3(0.9608, 0.9294, 0.9294),vec3(0), step(0.09, abs(sdDifference(sdUnion(mask_1,mask_2),sdUnion(mask_2,mask_3))))); colour_out = vec4(color,1.0); }
Fellimara picta Victor Micallef by
Eibaloch
// credit: IRIS PAN // sea slug: Nembrotha chamberlaini uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; float random(vec2 co) { const highp float seed = 13.702; highp float a = seed; highp float b = 77.841, c = 43759.409; highp float dt= dot(co.xy, vec2(a,b)); highp float sn= mod(dt,3.14159265358979323846); return fract(sin(sn) * c); } float noise( vec2 st ) { vec2 i = floor(st), f = fract(st); float a = random(i), b = random(i + vec2(1.0, 0.0)), c = random(i + vec2(0.0, 1.0)), d = random(i + vec2(1.0, 1.0)); vec2 uv= smoothstep(0.0, 1.0, f); //uv = f; return mix( a, b, uv.x ) + (c-a)*uv.y * (1.0-uv.x) + (d-b)*uv.x*uv.y; } float turb( vec2 p ) { float f = 0.0, scale; for (int i=0; i<4; i++) { scale = pow( pow(2.0, 4.0/3.0), float(i) ); f += abs( noise( u_time+p * scale) ) / scale; } return f; } float cro(in vec2 a, in vec2 b ){ return a.x*b.y - a.y*b.x; } float sdUnevenCapsule( in vec2 p, in vec2 pa, in vec2 pb, in float ra, in float rb ) { p -= pa; pb -= pa; float h = dot(pb,pb); vec2 q = vec2( dot(p,vec2(pb.y,-pb.x)), dot(p,pb) )/h; //----------- q.x = abs(q.x); float b = ra-rb; vec2 c = vec2(sqrt(h-b*b),b); float k = cro(c,q); float m = dot(c,q); float n = dot(q,q); if( k < 0.0 ) return sqrt(h*(n )) - ra; else if( k > c.x ) return sqrt(h*(n+1.0-2.0*q.y)) - rb; return m - ra; } float sdMoon(vec2 p, float d, float ra, float rb ) { float a = (ra*ra - rb*rb + d*d)/(2.000*d); float b = sqrt(max(ra*ra-a*a,0.0)); if( 1.260+d*(p.x*b-p.y*a) > d*d*max(b-p.y,0.0) ) return length(p-vec2(a,b)); return max( (length(vec2(p.x+0.032,p.y+0.272) )-ra), -(length(vec2(p.x+-0.656,p.y+-0.656)-vec2(d,0))-rb)); } float sdStar( in vec2 p, in float r, in int n, in float m) { // next 4 lines can be precomputed for a given shape float an = 0.934/float(n); float c = cos(u_time); float s = sin(u_time); an *=abs(c); float en = 0.870/m; // m is between 2 and n vec2 acs = 1.064*vec2(cos(an),sin(an)); vec2 ecs = vec2(cos(en),sin(en)); // ecs=vec2(0,1) for regular polygon float bn = mod(atan(p.x+-0.024,p.y+0.020),4.552*an) - an; p = length(p)*vec2(cos(bn),abs(sin(bn))); p -= r*acs; p += ecs*clamp( -dot(p,ecs), 0.032, r*acs.y/ecs.y); return length(p)*sign(p.x); } void main() { vec2 st = (2.360*gl_FragCoord.xy-u_resolution.xy)/u_resolution.y; st.y=st.y+-0.472; vec3 color; vec3 col; //body float bod = -1.080; float ra =0.688; float rb=1.368; float moon = sdMoon(st, bod, ra, rb); //antenna float horna=1.480; vec2 v1a = cos( 0.076 + vec2(0.0,2.00) + 0.008 ); vec2 v2a = cos( -1.092 + vec2(0.0,1.50) + 1.492); float r1a = -0.100+0.148*sin(-0.408+1.660*horna); float r2a = 0.124+-1.876*sin(0.624+1.660*horna); float tr1 = sdUnevenCapsule(vec2(st.x+0.400,st.y+-0.264), v1a,v2a,r1a, r2a); //position of antenna float hornb=1.456; vec2 v1b = cos( 0.660 + -vec2(0.0,2.00) + -0.056 ); vec2 v2b = cos( -1.228 + vec2(-0.020,0.990) + 1.500); float r1b = -0.100+0.148*sin(-0.408+1.660*hornb); float r2b = 0.092+-0.932*sin(0.608+1.684*hornb); float tr2 = sdUnevenCapsule(vec2(st.x+0.160,st.y+0.448), v1b,v2b,r1b, r2b); //position of antenna //head float head=1.456; vec2 v1h = cos( 0.660 + -vec2(0.0,2.00) + -0.056 ); vec2 v2h = cos( -1.380 + vec2(-0.020,0.990) + 1.556); float r1h = -0.100+0.148*sin(-0.408+1.660*head); float r2h = 0.108+-0.932*sin(0.608+1.684*head); float trh = sdUnevenCapsule(vec2(st.x+0.352,st.y+0.616), v1h,v2h,r1h, r2h); //position //tail float tail=1.464; vec2 v1t = cos( 0.684 + -vec2(0.0,2.00) + -0.056 ); vec2 v2t = cos( -1.132 + vec2(-0.020,0.990) + 1.556); float r1t = -0.116+0.148*sin(-0.408+1.660*tail); float r2t = 0.100+-0.932*sin(0.608+1.684*tail); float trt = sdUnevenCapsule(vec2(st.x+1.432,st.y+0.888), v1t,v2t,r1t, r2t); //position //blob on its back float top=1.488; vec2 v1v = cos( 0.708 + -vec2(0.0,2.00) + -0.056 ); vec2 v2v = cos( -0.972 + vec2(-0.020,0.990) + 1.556); float r1v = -0.100+0.148*sin(-0.408+1.660*top); float r2v = 0.116+-0.932*sin(0.608+1.684*top); float trv = sdUnevenCapsule(vec2(st.x+0.744,st.y+0.600), v1v,v2v,r1v,r2v); //position float r=0.140; int n=7; float m=4.272; float blob1 = sdStar( vec2(st.x+-0.136,st.y+0.416), r, n, m); float blob2 = sdStar( vec2(st.x+0.016,st.y+0.472), r, n, m); float blob3 = sdStar( vec2(st.x+-0.032,st.y+0.368), r, n, m); //spots float spots1 = sdUnevenCapsule(vec2(st.x+0.408,st.y+1.072),vec2(0.240,0.250),vec2(0.240,0.230),0.600/10.0,0.680/9.520);//left float spots2 = sdUnevenCapsule(vec2(st.x+0.016,st.y+0.776),vec2(-0.030,-0.010),vec2(-0.050,0.010),0.904/10.0,0.672/10.0); float spots3 = sdUnevenCapsule(vec2(st.x+0.264,st.y+0.800),vec2(0.100,0.020),vec2(0.170,0.030),0.840/10.0,0.984/10.0); float spots4 = sdUnevenCapsule(vec2(st.x+-0.400,st.y+0.600),vec2(0.010,0.000),vec2(-0.090,0.050),0.784/10.0,0.296/10.0); //right float spots5 = sdUnevenCapsule(vec2(st.x+-0.288,st.y+0.464),vec2(0.020,-0.150),vec2(0.120,-0.040),0.912/10.0,0.552/10.0); float spots6 = sdUnevenCapsule(vec2(st.x+-0.432,st.y+0.512),vec2(-0.140,-0.160),vec2(-0.070,-0.070),0.760/10.0,-0.360/10.0); //noise float ni = turb( gl_FragCoord.xy*u_time*10.0 / 50.0 ); float t = 0.632 + sin( gl_FragCoord.x / 78.176 + 11.104 * ni ) / 2.0; float na = turb( gl_FragCoord.xy / 28.696 ); //bg color=mix( col, vec3(1.128,0.924,0.649), 2.352-smoothstep(-0.336,-0.321,abs(tr1)) *1.0);; //left horn if(tr1<=0.0){ color=mix( col,vec3(0.448,-0.408+st.x,-0.548), 2.088-smoothstep(-0.816,-2.905,abs(tr2)) *1.368);; } //headpart if(trh<=0.0){ color = mix( col, vec3(1.808,0.391,st.y+1.041), 2.952-smoothstep(-0.336,-0.321,abs(trh)) *1.0); //color *= vec3(ni*0.416); } //body if(moon<=0.0){ color = mix( col, vec3(1.808,0.391,st.y+1.041), 2.952-smoothstep(-0.336,-0.321,abs(moon)) *1.0); } //right horn if(tr2<=0.0){ color=mix( col, vec3(1.000,-0.528+st.x,-1.084), 2.352-smoothstep(-0.816,-1.265,abs(tr2)) *1.368); } //tail if(trt<=0.0){ color=mix( col, vec3(1.016+st.x,0.281,0.404), 2.952-smoothstep(-0.336,-0.321,abs(trt)) *1.0); } //back thingy if(trv<=0.0){ color=mix( col, vec3(1.000,0.575,0.527), 1.920-smoothstep(-0.664,-0.417,abs(trv)) *1.0); } //blob if(blob1<=0.0){ color=mix( col, vec3(st.x+0.516,st.x*1.396,0.196), 3.792-smoothstep(-0.336,-0.321,abs(blob1)) *1.0); color *= vec3(na*0.620); } if(blob2<=0.0){ color=mix( col, vec3(st.x+0.516,st.x*1.396,0.196), 3.792-smoothstep(-0.336,-0.321,abs(blob2)) *1.0); color *= vec3(na*0.620); } if(blob3<=0.0){ color=mix( col, vec3(st.x+0.516,st.x*1.396,0.196), 3.792-smoothstep(-0.336,-0.321,abs(blob3)) *1.0); color *= vec3(na*0.620); } //leftspots if(spots1<=0.0){ color=mix( col, vec3(1.396,0.208,0.603), 3.792-smoothstep(-0.336,-0.321,abs(spots1)) *1.0); color *= vec3(na*0.232); } if(spots2<=0.0){ color=mix( col, vec3(1.396,0.208,0.603), 3.792-smoothstep(-0.336,-0.321,abs(spots2)) *1.0); color *= vec3(na*0.232); } if(spots3<=0.0){ color=mix( col, vec3(1.396,0.208,0.603), 3.792-smoothstep(-0.336,-0.321,abs(spots3)) *1.0); color *= vec3(na*0.232); } //rightspots if(spots4<=0.0){ color=mix( col, vec3(1.396,0.773,0.460), 3.792-smoothstep(-0.336,-0.321,abs(spots4)) *1.0); color *= vec3(na*0.208); } if(spots5<=0.0){ color=mix( col, vec3(1.396,0.773,0.460), 3.792-smoothstep(-0.336,-0.321,abs(spots5)) *1.0); color *= vec3(na*0.208); } if(spots6<=0.0){ color=mix( col, vec3(1.396,0.773,0.460), 3.792-smoothstep(-0.336,-0.321,abs(spots5)) *1.0); color *= vec3(na*0.208); } colour_out = vec4(color, 1.0); }
Nembrotha chamberlaini by IRIS PAN
More Student Works
The rest of the student works from 2023 are shown below. Note that some are very computationally expensive and may potentially cause issues with your browser. Show Other Student Works
// credit: yukinoguchi // sea slug: sea bunny uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; float sdCircle( vec2 p, float r ) { return length(p) - r; } float sdEllipse( in vec2 p, in vec2 ab ) { p = abs(p); if( p.x > p.y ) {p=p.yx;ab=ab.yx;} float l = ab.y*ab.y - ab.x*ab.x; float m = ab.x*p.x/l; float m2 = m*m; float n = ab.y*p.y/l; float n2 = n*n; float c = (m2+n2-1.0)/3.0; float c3 = c*c*c; float q = c3 + m2*n2*2.0; float d = c3 + m2*n2; float g = m + m*n2; float co; if( d<0.0 ) { float h = acos(q/c3)/3.0; float s = cos(h); float t = sin(h)*sqrt(3.0); float rx = sqrt( -c*(s + t + 2.0) + m2 ); float ry = sqrt( -c*(s - t + 2.0) + m2 ); co = (ry+sign(l)*rx+abs(g)/(rx*ry)- m)/2.0; } else { float h = 2.0*m*n*sqrt( d ); float s = sign(q+h)*pow(abs(q+h), 1.0/3.0); float u = sign(q-h)*pow(abs(q-h), 1.0/3.0); float rx = -s - u - c*4.0 + 2.0*m2; float ry = (s - u)*sqrt(3.0); float rm = sqrt( rx*rx + ry*ry ); co = (ry/sqrt(rm-rx)+2.0*g/rm-m)/2.0; } vec2 r = ab * vec2(co, sqrt(1.0-co*co)); return length(r-p) * sign(p.y-r.y); } vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 permute(vec3 x) { return mod289(((x*34.0)+10.0)*x); } float snoise(vec2 v) { const vec4 C = vec4(0.187, // (3.0-sqrt(3.0))/6.0 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) -0.793, // -1.0 + 2.0 * C.x 0.024390243902439); // 1.0 / 41.0 // First corner vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); // Other corners vec2 i1; //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 //i1.y = 1.0 - i1.x; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); // x0 = x0 - 0.0 + 0.0 * C.xx ; // x1 = x0 - i1 + 1.0 * C.xx ; // x2 = x0 - 1.0 + 2.0 * C.xx ; vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; // Permutations i = mod289(i); // Avoid truncation effects in permutation vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.412 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; // Gradients: 41 points uniformly over a line, mapped onto a diamond. // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) vec3 x = 1.752 * fract(p * C.www) - 1.0; vec3 h = abs(x) - -0.212; vec3 ox = floor(x + 0.308); vec3 a0 = x - ox; // Normalise gradients implicitly by scaling m // Approximation of: m *= inversesqrt( a0*a0 + h*h ); m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); // Compute final noise value at P vec3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } float sdVesica(vec2 p, float r, float d) { p = abs(p); float b = sqrt(r*r-d*d); return ((p.y-b)*d>p.x*b) ? length(p-vec2(0.0,b)) : length(p-vec2(-d,0.0))-r; } float sdf( vec2 p, float x, float y, float a, float b, float m, float n) { float c = a, s = b; float t1 = x; float t2 = y; mat3 H = mat3( c, s, 0, /* Column-major!! */ -s, c, 0, t1, t2, 1 ); p = (inverse(H) * vec3(p,1.0)).xy; /* Note the inverse!! */ return sdVesica(vec2(p.x, p.y), m, n); } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; float n = snoise( gl_FragCoord.xy / 101.080 ); n = n*-1.220 + 1.180; /* Map from [-1,1] to [0,1] */ float mask = 1.0; int texture = 1; mask *= step(0.0, sdEllipse(vec2(st.x-0.476, st.y-0.460), vec2(0.300,0.230))); mask *= step(0.0, sdCircle(vec2(st.x-0.588, st.y-0.396), 0.224)); mask *= step(0.0, sdEllipse(vec2(st.x-0.492, st.y-0.420), vec2(0.300,0.230))); //mask *= step(0.0, sdVesica(vec2(st.x-0.492, st.y-0.420), 0.068, 0.03)); //mask *= step(0.0, sdf(st, 0.47, 0.5, 0.6, 1.0)); //mask *= step( 0.3, distance( st.xy, vec2(0.5, 0.4) ) ); //mask *= step( 0.25, distance( st.xy, vec2(0.630,0.590) ) ); //mask *= step( 0.25, distance( st.xy, vec2(0.4, 0.7) ) ); //colour_out = vec4( st.x, st.y, abs(sin(3.0*u_time)), 1.0 ); //if(texture == 1){ // colour_out = vec4( st.x, st.y, abs(sin(3.0*u_time)), 1.0 ); //} colour_out = vec4( vec3(n), 1.008 ); colour_out *= 1.0-mask; if(mask == 1.0){ colour_out = vec4(0.74, 0.717, 0.67, 1.0); } if(sdf(st, 0.47, 0.5, 1.020, 1.0, 0.068, 0.035)<0.0){ colour_out = vec4(0.0); } if(sdf(st, 0.82, 0.5, -0.784, 1.056, 0.090, 0.06)<0.0){ colour_out = vec4(0.0); } }
sea bunny by yukinoguchi
//credit: Kojun //sea slug: Hypselodoris bullocki vec3 mod289(vec3 x) {return x - floor(x * (1.0 / 289.0)) * 289.0;} vec2 mod289(vec2 x) {return x - floor(x * (1.0 / 289.0)) * 289.0;} vec4 mod289(vec4 x) {return x - floor(x * (1.0 / 289.0)) * 289.0;} vec3 mod7(vec3 x) { return x - floor(x * (1.0 / 7.0)) * 7.0; } vec4 permute(vec4 x) {return mod289(((x*34.0)+10.0)*x);} vec3 permute(vec3 x) {return mod289(((x*34.0)+10.0)*x);} vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;} float snoise(vec3 v){ const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); vec3 i = floor(v + dot(v, C.yyy) );vec3 x0 = v - i + dot(i, C.xxx) ;vec3 g = step(x0.yzx, x0.xyz); vec3 l = 1.0 - g;vec3 i1 = min( g.xyz, l.zxy );vec3 i2 = max( g.xyz, l.zxy ); vec3 x1 = x0 - i1 + C.xxx;vec3 x2 = x0 - i2 + C.yyy; vec3 x3 = x0 - D.yyy; i = mod289(i); vec4 p = permute( permute( permute( i.z + vec4(0.0, i1.z, i2.z, 1.0 )) + i.y + vec4(0.0, i1.y, i2.y, 1.0 ))+ i.x + vec4(0.0, i1.x, i2.x, 1.0 )); float n_ = 0.142857142857; vec3 ns = n_ * D.wyz - D.xzx;vec4 j = p - 49.0 * floor(p * ns.z * ns.z); vec4 x_ = floor(j * ns.z);vec4 y_ = floor(j - 7.0 * x_ );vec4 x = x_ *ns.x + ns.yyyy; vec4 y = y_ *ns.x + ns.yyyy;vec4 h = 1.0 - abs(x) - abs(y);vec4 b0 = vec4( x.xy, y.xy ); vec4 b1 = vec4( x.zw, y.zw );vec4 s0 = floor(b0)*2.0 + 1.0;vec4 s1 = floor(b1)*2.0 + 1.0; vec4 sh = -step(h, vec4(0.0));vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;vec3 p0 = vec3(a0.xy,h.x); vec3 p1 = vec3(a0.zw,h.y);vec3 p2 = vec3(a1.xy,h.z);vec3 p3 = vec3(a1.zw,h.w); vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); p0 *= norm.x;p1 *= norm.y;p2 *= norm.z;p3 *= norm.w; vec4 m = max(0.5 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); m = m * m;return 105.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),dot(p2,x2), dot(p3,x3) ) );} float snoise(vec2 v){const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439);vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx);vec2 i1;i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); vec4 x12 = x0.xyxy + C.xxzz;x12.xy -= i1;i = mod289(i); // Avoid truncation effects in permutation vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))+ i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ;m = m*m ; vec3 x = 2.0 * fract(p * C.www) - 1.0;vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5);vec3 a0 = x - ox;m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); vec3 g;g.x = a0.x * x0.x + h.x * x0.y;g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g);} float cro(in vec2 a, in vec2 b ) { return a.x*b.y - a.y*b.x; } float sdUnevenCapsule( in vec2 p, in vec2 pa, in vec2 pb, in float ra, in float rb ){ p -= pa; pb -= pa; float h = dot(pb,pb);vec2 q = vec2( dot(p,vec2(pb.y,-pb.x)), dot(p,pb) )/h; q.x = abs(q.x);float b = ra-rb;vec2 c = vec2(sqrt(h-b*b),b);float k = cro(c,q); float m = dot(c,q);float n = dot(q,q);if( k < 0.0 ) return sqrt(h*(n )) - ra; else if( k > c.x ) return sqrt(h*(n+1.0-2.0*q.y)) - rb; return m - ra;} float sdSegment( in vec2 p, in vec2 a, in vec2 b ){ vec2 pa = p-a, ba = b-a;float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); return length( pa - ba*h );} float turb_fract( vec3 p ) {float f = -0.2, scale;for (int i=0; i<4; i++) { scale = pow( pow(3.0, 1.75), float(i) );f += abs(snoise( p * scale )) / scale;} return f;} float turb_fract( vec2 p ) {float f = -0.2, scale;for (int i=0; i<4; i++) { scale = pow( pow(5.0, 1.75), float(i) );f += abs(snoise( p * scale )) / scale;} return f;} vec2 random2( vec2 p ) { return fract(sin(vec2(dot(p,vec2(127.1,311.7)),dot(p,vec2(269.5,183.3))))*43758.5453); } //////////////////////// #ifdef GL_ES precision mediump float; #endif uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec2 mt = u_mouse.xy/u_resolution.xy; vec3 uv = vec3( .5 * st - 0.5, 0.1*u_time ); float noise = 0.6*turb_fract( uv )+0.2; colour_out = vec4( vec3(0.076,0.174,0.230), noise ); //体 vec3 co_dark = vec3(0.026,0.060,0.150);//体色 vec3 co_pat = vec3(0.706,0.048,0.089);//斑点色 float mask = 1.0; float n = turb_fract( st / 0.25 + 0.1 * mt.x);//斑点 mask *= step( 0.03, sdUnevenCapsule(st - vec2(0.570,0.580), vec2(-0.350,-0.220), vec2(0.200,-0.090), 0.1, .2));//体1 mask *= step( 0.023, sdUnevenCapsule(st - vec2(0.240,0.430), vec2(0.280,0.040), vec2(-0.010,-0.020), 0.1, .2));//体2 vec3 co = mix(co_dark, co_pat, vec3(step(0.7, n * 0.5+ 0.5)));//see slug //背景 vec3 color = vec3(0.071,0.778,1.000); vec2 i_st = floor(st*4.); vec2 f_st = fract(st*4.); float m_dist = 1.; // minimum distance for (int y= -1; y <= 1; y++) { for (int x= -1; x <= 1; x++) { // Neighbor place in the grid vec2 neighbor = vec2(float(x),float(y)); // Random position from current + neighbor place in the grid vec2 point = random2(i_st + neighbor); // Animate the point point = -0.060 + 0.5*sin(u_time + 6.2831*point); // Vector between the pixel and the point vec2 diff = neighbor + point - f_st; // Distance to the point float dist = length(diff); // Keep the closer distance m_dist = min(m_dist, dist);}} // Draw the min distance (distance field) color += m_dist; // Draw cell center color += 1.-step(.02, m_dist); colour_out += mix(vec4(co, 1.0), vec4(color,1.0), mask);//背景 //影 mask = 1.0; mask *= smoothstep( .0, .20, sdUnevenCapsule(st - vec2(0.870,0.330), vec2(-0.640,-0.090), vec2(0.0), 0.01, 0.03) ); colour_out *= mix(vec4(0.7), vec4(1.0), mask); //触覚 mask = 1.0; co = mix(vec3(0.00), vec3(7.000,0.528,0.127), vec3(step(0.4, n * 0.5 + 0.5))); mask *= step( 0.03, sdSegment(st, vec2(0.160,0.730), vec2(0.100,0.540)) ); mask *= step( 0.03, sdSegment(st, vec2(0.320,0.720), vec2(0.220,0.520)) ); colour_out *= mix(vec4(co, 1.0), vec4(1.0, 1.0, 1.0, 1.0), mask); //しっぽ mask = 1.0; //1 mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.655,0.77))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.660,0.76))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.666,0.74))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.670, 0.74))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.676,0.73))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.690,0.72))); mask *= step(0.03, distance(st - 0.01 * (mt - vec2(.3, .7)), vec2(0.700,0.71))); //2 mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.710, 0.81))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.717,0.81))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.710,0.80))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.710,0.77))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.720, 0.76))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.720,0.73))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.730,0.72))); mask *= step(0.03, distance(st - 0.01 * (mt - vec2(.3, .7)), vec2(0.730,0.71))); //3 mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.755,0.810))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.755,0.78))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.755,0.77))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.750,0.76))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.740, 0.75))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.740,0.74))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.740,0.73))); mask *= step(0.03, distance(st - 0.01 * (mt - vec2(.3, .7)), vec2(0.73,0.70))); //4 mask *= step(0.018, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.790, 0.79))); mask *= step(0.018, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.787,0.78))); mask *= step(0.018, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.780,0.77))); mask *= step(0.018, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.780,0.76))); mask *= step(0.018, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.770, 0.75))); mask *= step(0.018, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.760,0.74))); mask *= step(0.018, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.760,0.73))); mask *= step(0.028, distance(st - 0.01 * (mt - vec2(.3, .7)), vec2(0.760,0.70))); //5 mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.825,0.77))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.820,0.76))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.820,0.74))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.8120, 0.74))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.816,0.73))); mask *= step(0.02, distance(st - 0.03 * (mt - vec2(.3, .7)), vec2(0.810,0.72))); mask *= step(0.03, distance(st - 0.01 * (mt - vec2(.3, .7)), vec2(0.800,0.71))); colour_out += mix(vec4(0.975,0.450,0.055,1.000), vec4(.0), mask); }
Hypselodoris bullocki by Kojun
// credit: zhu // sea slug uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; // // Description : Array and textureless GLSL 2D simplex noise function. // Author : Ian McEwan, Ashima Arts. // Maintainer : stegu // Lastmod : 20110822 (ijm) // License : Copyright (C) 2011 Ashima Arts. All rights reserved. // Distributed under the MIT License. See LICENSE file. // https://github.com/ashima/webgl-noise // https://github.com/stegu/webgl-noise // vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 permute(vec3 x) { return mod289(((x*34.0)+10.0)*x); } float snoise(vec2 v) { const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) -0.577350269189626, // -1.0 + 2.0 * C.x 0.024390243902439); // 1.0 / 41.0 // First corner vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); // Other corners vec2 i1; //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 //i1.y = 1.0 - i1.x; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); // x0 = x0 - 0.0 + 0.0 * C.xx ; // x1 = x0 - i1 + 1.0 * C.xx ; // x2 = x0 - 1.0 + 2.0 * C.xx ; vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; // Permutations i = mod289(i); // Avoid truncation effects in permutation vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; // Gradients: 41 points uniformly over a line, mapped onto a diamond. // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; // Normalise gradients implicitly by scaling m // Approximation of: m *= inversesqrt( a0*a0 + h*h ); m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); // Compute final noise value at P vec3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } float sdEllipse( in vec2 p, in vec2 ab ) { p = abs(p); if( p.x > p.y ) {p=p.yx;ab=ab.yx;} float l = ab.y*ab.y - ab.x*ab.x; float m = ab.x*p.x/l; float m2 = m*m; float n = ab.y*p.y/l; float n2 = n*n; float c = (m2+n2-1.0)/3.0; float c3 = c*c*c; float q = c3 + m2*n2*2.0; float d = c3 + m2*n2; float g = m + m*n2; float co; if( d<0.0 ) { float h = acos(q/c3)/3.0; float s = cos(h); float t = sin(h)*sqrt(3.0); float rx = sqrt( -c*(s + t + 2.0) + m2 ); float ry = sqrt( -c*(s - t + 2.0) + m2 ); co = (ry+sign(l)*rx+abs(g)/(rx*ry)- m)/2.0; } else { float h = 2.0*m*n*sqrt( d ); float s = sign(q+h)*pow(abs(q+h), 1.0/3.0); float u = sign(q-h)*pow(abs(q-h), 1.0/3.0); float rx = -s - u - c*4.0 + 2.0*m2; float ry = (s - u)*sqrt(3.0); float rm = sqrt( rx*rx + ry*ry ); co = (ry/sqrt(rm-rx)+2.0*g/rm-m)/2.0; } vec2 r = ab * vec2(co, sqrt(1.0-co*co)); return length(r-p) * sign(p.y-r.y); } float sdOrientedBox( in vec2 p, in vec2 a, in vec2 b, float th ) { float l = length(b-a); vec2 d = (b-a)/l; vec2 q = (p-(a+b)*0.5); q = mat2(d.x,-d.y,d.y,d.x)*q; q = abs(q)-vec2(l,th)*0.5; return length(max(q,0.0)) + min(max(q.x,q.y),0.0); } vec2 rotate( vec2 v, float a ) { float s = sin(a); float c = cos(a); mat2 m = mat2(c,-s,s,c); return m*v; } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec2 posparams[10] = vec2[10]( vec2(0.5, 0.4), vec2(0.6, 0.7), vec2(0.4, 0.7), vec2(0.3, 0.3), vec2(0.7, 0.3), vec2(0.3, 0.6), vec2(0.7, 0.6), vec2(0.5, 0.2), vec2(0.5, 0.8), vec2(0.5, 0.5) ); float PI = 3.1415; float rotparams[10] = float[10]( 0.2233461037801064, 2.001346354336402, 1.4679388529120532, 1.3685408012576143, 0.9926512279720201, 2.873918692889804, 0.4254639299635069, 2.3032786037019606, 1.3584553728153652, 0.6613299790099506 ); float sizeparams[10] = float[10]( 0.9026858071489114, 0.3999867953106939, 0.7895833118750084, 0.24781006431329144, 0.4816870884046909, 0.6680503885050741, 0.5083456681447074, 0.3944068654633692, 0.64749891730475, 0.6158968781845998 ); // background green material // grass? float noise_bg = snoise(st * 30.0); for (int i = 0; i < 10; i++) { vec2 pos = rotate(st - posparams[i], rotparams[i]); float d = sdEllipse(pos, vec2(sizeparams[i] * 0.1, sizeparams[i] * 0.3)); if (d < 0.0) { colour_out = vec4(noise_bg, (1.0 + d * 7.0), 0.0, 0.8); } } for (int i = 0; i < 10; i++) { vec2 pos = rotate(st - vec2(posparams[i].x, 1.0 - posparams[i].y), rotparams[i] + PI / 2.0); float d = sdEllipse(pos, vec2(sizeparams[i] * 0.1, sizeparams[i] * 0.3)); if (d < 0.0) { colour_out = vec4(noise_bg, (1.0 + d * 7.0), 0.0, 0.8); } } // sea slug body vec2 pos1 = rotate(st - vec2(0.5, 0.4), -0.4); float d1 = sdEllipse(pos1, vec2(0.1, 0.15)); vec2 pos2 = rotate(st - vec2(0.6, 0.7), -0.2); float d2 = sdEllipse(pos2, vec2(0.05, 0.2)); float bodynoise = 1.0 - snoise(st * 50. + u_time * 0.15); if (d1 < 0.0 || d2 < 0.0) { colour_out = vec4(bodynoise, bodynoise, 0.1, 1.0); } else if (d1 < 0.01 || d2 < 0.01) { colour_out = vec4(1.0); } // sea slug eyes float timenoise = snoise(vec2(u_time * 0.5, 0.0)); float eyecl = 1.0 - snoise(st * 30.); vec2 mov = vec2(timenoise * 0.1 - 0.05, timenoise * 0.06 - 0.03); float eye1 = sdOrientedBox(st, vec2(0.4, 0.3), vec2(0.3, 0.26) + mov, 0.03); float eye2 = sdOrientedBox(st, vec2(0.52, 0.29), vec2(0.5, 0.1) + mov, 0.03); if (eye1 < 0.0 || eye2 < 0.0) { colour_out = vec4(eyecl, eyecl, 1.0, 1.0); } }
sea slug by zhu
// credit: w20v0(will show up on website) uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; float mask = 1.0; mask *= step( 0.9 , distance( st.xy, vec2(0.5, 0.5) ) ); if(abs(st.x-st.y)<0.3 && (st.x+st.y)<1.6 && (st.x+st.y)>0.4) colour_out = vec4(1.0,1.0,1.0,1.0); if(abs(st.x-st.y)<0.2&& (st.x+st.y)<1.5 && (st.x+st.y)>0.5) colour_out = vec4(exp(-abs(st.x-st.y))-0.2,abs(sin(3.0*u_time))/3.0+exp(-1.0-st.y),0.6+exp(abs(st.x-st.y)),1.000); if(step( 0.4 , distance( st.xy, vec2(0.49, 0.49) ) )>0.0) colour_out = vec4(0.0,0.0,0.0,0.0); if(step( 0.04 , distance( vec2(st.x-st.y, st.x+0.05), vec2(0.0, 0.9) ) )==0.0) colour_out = vec4(0.609,1.000,0.913,1.000-abs(sin(3.0*u_time))/3.0); if(step( 0.04 , distance( vec2(st.x-st.y+0.1, st.x+0.13), vec2(0.0, 0.9) ) )==0.0) colour_out = vec4(0.439,0.971,1.000,1.000-abs(sin(3.0*u_time))/3.0); if(step( 0.05 , distance( vec2(st.x-st.y-st.y+0.65, st.x+0.03), vec2(0.0, 0.9) ) )==0.0) colour_out = vec4(0.506,1.000,0.943,1.000-abs(sin(3.0*u_time))/3.0); if(step( 0.09 , distance( st.xy, vec2(0.75, 0.75) ) )==0.0) colour_out = vec4(0.045+st.y,0.2605+abs(sin(3.0*u_time))/3.0,1.000,1.000); if(step( 0.05 , distance( vec2(st.x-st.y-st.y+0.65, st.x+0.03), vec2(0.21, 0.26) ) )==0.0) colour_out = vec4(1.000,0.046,0.200,1.000); if(step( 0.04 , distance( vec2(3.0*st.x-st.y*2.7+0.3, st.x+0.1), vec2(0.5, 0.4) ) )==0.0) colour_out = vec4(1.000,0.046,0.200,1.000); if(step( 0.04 , distance( vec2(3.0*st.x-st.y*2.7+0.27, st.x+0.1), vec2(0.5, 0.4) ) )==0.0) colour_out = vec4(1.000,0.046,0.200,1.000); if(step( 0.04 , distance( vec2(3.0*st.x-st.y*2.7+0.24, st.x+0.1), vec2(0.5, 0.4) ) )==0.0) colour_out = vec4(1.000,0.046,0.200,1.000); }
unknown by w20v0
// credit: Chen Bixuan (will show up on website) // sea slug: Jorunna Parva #ifdef GL_ES precision mediump float; #endif #ifdef GL_OES_standard_derivatives #extension GL_OES_standard_derivatives : enable #endif uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 permute(vec3 x) { return mod289(((x*34.0)+10.0)*x); } float snoise(vec2 v) { const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) -0.577350269189626, // -1.0 + 2.0 * C.x 0.024390243902439); // 1.0 / 41.0 // First corner vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); // Other corners vec2 i1; //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 //i1.y = 1.0 - i1.x; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); // x0 = x0 - 0.0 + 0.0 * C.xx ; // x1 = x0 - i1 + 1.0 * C.xx ; // x2 = x0 - 1.0 + 2.0 * C.xx ; vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; // Permutations i = mod289(i); // Avoid truncation effects in permutation vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; // Gradients: 41 points uniformly over a line, mapped onto a diamond. // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; // Normalise gradients implicitly by scaling m // Approximation of: m *= inversesqrt( a0*a0 + h*h ); m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); // Compute final noise value at P vec3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } vec3 mod7(vec3 x) { return x - floor(x * (1.0 / 7.0)) * 7.0; } vec2 cellular(vec2 P) { #define K 0.142857142857 // 1/7 #define Ko 0.428571428571 // 3/7 #define jitter 1.0 // Less gives more regular pattern vec2 Pi = mod289(floor(P)); vec2 Pf = fract(P); vec3 oi = vec3(-1.0, 0.0, 1.0); vec3 of = vec3(-0.5, 0.5, 1.5); vec3 px = permute(Pi.x + oi); vec3 p = permute(px.x + Pi.y + oi); // p11, p12, p13 vec3 ox = fract(p*K) - Ko; vec3 oy = mod7(floor(p*K))*K - Ko; vec3 dx = Pf.x + 0.5 + jitter*ox; vec3 dy = Pf.y - of + jitter*oy; vec3 d1 = dx * dx + dy * dy; // d11, d12 and d13, squared p = permute(px.y + Pi.y + oi); // p21, p22, p23 ox = fract(p*K) - Ko; oy = mod7(floor(p*K))*K - Ko; dx = Pf.x - 0.5 + jitter*ox; dy = Pf.y - of + jitter*oy; vec3 d2 = dx * dx + dy * dy; // d21, d22 and d23, squared p = permute(px.z + Pi.y + oi); // p31, p32, p33 ox = fract(p*K) - Ko; oy = mod7(floor(p*K))*K - Ko; dx = Pf.x - 1.5 + jitter*ox; dy = Pf.y - of + jitter*oy; vec3 d3 = dx * dx + dy * dy; // d31, d32 and d33, squared // Sort out the two smallest distances (F1, F2) vec3 d1a = min(d1, d2); d2 = max(d1, d2); // Swap to keep candidates for F2 d2 = min(d2, d3); // neither F1 nor F2 are now in d3 d1 = min(d1a, d2); // F1 is now in d1 d2 = max(d1a, d2); // Swap to keep candidates for F2 d1.xy = (d1.x < d1.y) ? d1.xy : d1.yx; // Swap if smaller d1.xz = (d1.x < d1.z) ? d1.xz : d1.zx; // F1 is in d1.x d1.yz = min(d1.yz, d2.yz); // F2 is now not in d2.yz d1.y = min(d1.y, d1.z); // nor in d1.z d1.y = min(d1.y, d2.x); // F2 is in d1.y, we're done. return sqrt(d1.xy); } float psrdnoise(vec2 x, vec2 period, float alpha, out vec2 gradient) { vec2 uv = vec2(x.x+x.y*0.5, x.y); vec2 i0 = floor(uv), f0 = fract(uv); float cmp = step(f0.y, f0.x); vec2 o1 = vec2(cmp, 1.0-cmp); vec2 i1 = i0 + o1, i2 = i0 + 1.0; vec2 v0 = vec2(i0.x - i0.y*0.5, i0.y); vec2 v1 = vec2(v0.x + o1.x - o1.y*0.5, v0.y + o1.y); vec2 v2 = vec2(v0.x + 0.5, v0.y + 1.0); vec2 x0 = x - v0, x1 = x - v1, x2 = x - v2; vec3 iu, iv, xw, yw; if(any(greaterThan(period, vec2(0.0)))) { xw = vec3(v0.x, v1.x, v2.x); yw = vec3(v0.y, v1.y, v2.y); if(period.x > 0.0) xw = mod(vec3(v0.x, v1.x, v2.x), period.x); if(period.y > 0.0) yw = mod(vec3(v0.y, v1.y, v2.y), period.y); iu = floor(xw + 0.5*yw + 0.5); iv = floor(yw + 0.5); } else { iu = vec3(i0.x, i1.x, i2.x); iv = vec3(i0.y, i1.y, i2.y); } vec3 hash = mod(iu, 289.0); hash = mod((hash*51.0 + 2.0)*hash + iv, 289.0); hash = mod((hash*34.0 + 10.0)*hash, 289.0); vec3 psi = hash*0.07482 + alpha; vec3 gx = cos(psi); vec3 gy = sin(psi); vec2 g0 = vec2(gx.x, gy.x); vec2 g1 = vec2(gx.y, gy.y); vec2 g2 = vec2(gx.z, gy.z); vec3 w = 0.8 - vec3(dot(x0, x0), dot(x1, x1), dot(x2, x2)); w = max(w, 0.0); vec3 w2 = w*w; vec3 w4 = w2*w2; vec3 gdotx = vec3(dot(g0, x0), dot(g1, x1), dot(g2, x2)); float n = dot(w4, gdotx); vec3 w3 = w2*w; vec3 dw = -8.0*w3*gdotx; vec2 dn0 = w4.x*g0 + dw.x*x0; vec2 dn1 = w4.y*g1 + dw.y*x1; vec2 dn2 = w4.z*g2 + dw.z*x2; gradient = 10.9*(dn0 + dn1 + dn2); return 10.9*n; } float aastep(float threshold, float value) { float afwidth = 0.7 * length(vec2(dFdx(value), dFdy(value))); // float afwidth = fwidth(value); // fwidth(v) is |dFdx(v)| + |dFdy(v)| return smoothstep(threshold-afwidth, threshold+afwidth, value); } float color_1(vec2 xy) { return snoise(xy); }//Simplex and Perlin Noise (sea slug main body) float color_2(vec2 xy) { return cellular(xy).y * 2.0 - 1.0; }//Worly Noise (background) void main() { const float PI = 3.14159; float a = .2; // ellipse parameters float b = 0.1; float a_1 = .029; float b_1 = .015; float a_2 = .030; float b_2 = .017; float a_3 = .05; float b_3 = .02; float a_4 = .05; float b_4 = .02; float a_5 = .05; float b_5 = .02; float h = .07;float k = .12; // ellipse positions (main body) float h_1 = .07; float k_1 = .16;// ellipse positions (2 horns) float h_2 = -.15; float k_2 = .14; float h_3 = .07; float k_3 = -.05;// ellipse positions (tail) float h_4 = .055; float k_4 = -.05; float h_5 = .04; float k_5 = -.04; float theta = PI* 2.15 / 3.0; //thetas for ellipses (body, horns) float theta_1 = PI* 2.2 / 3.0; float theta_2 = PI* 2.9 / 3.0; float theta_3 = PI* 2.3 / 3.0; //thetas for ellipses (tail) float theta_4 = PI* 2.3 / 3.0; float theta_5 = PI* 2.3 / 3.0; float theta_thorn_1 = PI* -1.2 / 3.0; //thorn rotations float theta_thorn_2 = PI* 2.6 / 3.0; float theta_thorn_3 = PI* .33 / 3.0; float theta_thorn_4 = PI* .3 / 3.0; float theta_thorn_5 = PI* 1.5/ 3.0; float theta_thorn_6 = PI* -.1 / 3.0; float theta_thorn_7 = PI* -.7 / 3.0; float theta_thorn_8 = PI* .6 / 3.0; vec2 uv_1 = gl_FragCoord.xy/u_resolution.xy - .5; //normalization for the thorns vec2 uv_2 = gl_FragCoord.xy/u_resolution.xy - .5; vec2 uv_3 = gl_FragCoord.xy/u_resolution.xy - .5; vec2 uv_4 = gl_FragCoord.xy/u_resolution.xy - .5; vec2 uv_5 = gl_FragCoord.xy/u_resolution.xy - .5; vec2 uv_6 = gl_FragCoord.xy/u_resolution.xy - .5; vec2 uv_7 = gl_FragCoord.xy/u_resolution.xy - .5; vec2 uv_8 = gl_FragCoord.xy/u_resolution.xy - .5; //Zooming and rotation for the thorns mat2 zoomMatrix_thorn_1 = mat2( 260.0, 0, 0.0, 50.0); mat2 zoomMatrix_thorn_2 = mat2( 150.0, 0, 0.0, 50.0); mat2 zoomMatrix_thorn_3 = mat2( 150.0, 0, 0.0, 50.0); mat2 zoomMatrix_thorn_4 = mat2( 150.0, 0, 0.0, 50.0); mat2 zoomMatrix_thorn_5 = mat2( 130.0, 0, 0.0, 50.0); mat2 zoomMatrix_thorn_6 = mat2( 160.0, 0, 0.0, 50.0); mat2 zoomMatrix_thorn_7 = mat2( 150.0, 0, 0.0, 50.0); mat2 zoomMatrix_thorn_8 = mat2( 95.0, 0, 0.0, 60.0); mat2 rotationMatrix_thorn_1 = mat2( cos(theta_thorn_1),-sin(theta_thorn_1), sin(theta_thorn_1), cos(theta_thorn_1)); mat2 rotationMatrix_thorn_2 = mat2( cos(theta_thorn_2),-sin(theta_thorn_2), sin(theta_thorn_2),cos(theta_thorn_2)); mat2 rotationMatrix_thorn_3 = mat2( cos(theta_thorn_3),-sin(theta_thorn_3), sin(theta_thorn_3),cos(theta_thorn_3)); mat2 rotationMatrix_thorn_4 = mat2( cos(theta_thorn_4),-sin(theta_thorn_4), sin(theta_thorn_4),cos(theta_thorn_4)); mat2 rotationMatrix_thorn_5 = mat2( cos(theta_thorn_5),-sin(theta_thorn_5), sin(theta_thorn_5),cos(theta_thorn_5)); mat2 rotationMatrix_thorn_6 = mat2( cos(theta_thorn_6),-sin(theta_thorn_6), sin(theta_thorn_6),cos(theta_thorn_6)); mat2 rotationMatrix_thorn_7 = mat2( cos(theta_thorn_7),-sin(theta_thorn_7), sin(theta_thorn_7),cos(theta_thorn_7)); mat2 rotationMatrix_thorn_8 = mat2( cos(theta_thorn_8),-sin(theta_thorn_8), sin(theta_thorn_8),cos(theta_thorn_8)); uv_1.x += 0.015 * sin(u_time) * sin(20.0*uv_1.y);//sway the thorns (to attach the body) uv_2.x += 0.015 * sin(u_time) * sin(20.0*uv_2.y); uv_3.x += 0.015 * sin(u_time) * sin(20.0*uv_3.y); uv_4.x += 0.015 * sin(u_time) * sin(20.0*uv_4.y); uv_5.x += 0.015 * sin(u_time) * sin(20.0*uv_5.y); uv_6.x += 0.015 * sin(u_time) * sin(20.0*uv_6.y); uv_7.x += 0.015 * sin(u_time) * sin(20.0*uv_7.y); uv_8.x += 0.015 * sin(u_time) * sin(20.0*uv_8.y); uv_1 += vec2(-.21,.22);/////////////// position (thorn_1) uv_1 *= rotationMatrix_thorn_1; uv_1 *= zoomMatrix_thorn_1; uv_2 += vec2(-.05,0.04);/////////////// thorn_2 uv_2 *= rotationMatrix_thorn_2; uv_2 *= zoomMatrix_thorn_2; uv_3 += vec2(0,0.2);/////////////// thorn_3 uv_3 *= rotationMatrix_thorn_3; uv_3 *= zoomMatrix_thorn_3; uv_4 += vec2(.06,.18);/////////////// thorn_4 uv_4 *= rotationMatrix_thorn_4; uv_4 *= zoomMatrix_thorn_4; uv_5 += vec2(.04,.07);/////////////// thorn_5 uv_5 *= rotationMatrix_thorn_5; uv_5 *= zoomMatrix_thorn_5; uv_6 += vec2(-.09,.25);/////////////// thorn_6 uv_6 *= rotationMatrix_thorn_6; uv_6 *= zoomMatrix_thorn_6; uv_7 += vec2(-.16,.27);/////////////// thorn_6 uv_7 *= rotationMatrix_thorn_7; uv_7 *= zoomMatrix_thorn_7; uv_8 += vec2(.03,.12);/////////////// thorn_6 uv_8 *= rotationMatrix_thorn_8; uv_8 *= zoomMatrix_thorn_8; //triangles parameter (thorns) vec2 A = vec2(-.7, .1);vec2 B = vec2( 1., 1.1);vec2 C = vec2( -0.3, 1.1); float alpha_1 = (B.y*C.x - B.x*C.y + uv_1.x*(C.y - B.y) + uv_1.y*(B.x - C.x)) / (B.y*C.x - B.x*C.y + A.x*(C.y - B.y) + A.y*(B.x - C.x)); float beta_1 = (B.y*A.x - B.x*A.y + uv_1.x*(A.y - B.y) + uv_1.y*(B.x - A.x)) / (B.y*C.x - B.x*C.y + A.x*(C.y - B.y) + A.y*(B.x - C.x)); float gamma_1 = 1.0 - alpha_1 - beta_1; float alpha_2 = (B.y*C.x - B.x*C.y + uv_2.x*(C.y - B.y) + uv_2.y*(B.x - C.x)) / (B.y*C.x - B.x*C.y + A.x*(C.y - B.y) + A.y*(B.x - C.x)); float beta_2 = (B.y*A.x - B.x*A.y + uv_2.x*(A.y - B.y) + uv_2.y*(B.x - A.x)) / (B.y*C.x - B.x*C.y + A.x*(C.y - B.y) + A.y*(B.x - C.x)); float gamma_2 = 1.0 - alpha_2 - beta_2; float alpha_3 = (B.y*C.x - B.x*C.y + uv_3.x*(C.y - B.y) + uv_3.y*(B.x - C.x)) / (B.y*C.x - B.x*C.y + A.x*(C.y - B.y) + A.y*(B.x - C.x)); float beta_3 = (B.y*A.x - B.x*A.y + uv_3.x*(A.y - B.y) + uv_3.y*(B.x - A.x)) / (B.y*C.x - B.x*C.y + A.x*(C.y - B.y) + A.y*(B.x - C.x)); float gamma_3 = 1.0 - alpha_3 - beta_3; float alpha_4 = (B.y*C.x - B.x*C.y + uv_4.x*(C.y - B.y) + uv_4.y*(B.x - C.x)) / (B.y*C.x - B.x*C.y + A.x*(C.y - B.y) + A.y*(B.x - C.x)); float beta_4 = (B.y*A.x - B.x*A.y + uv_4.x*(A.y - B.y) + uv_4.y*(B.x - A.x)) / (B.y*C.x - B.x*C.y + A.x*(C.y - B.y) + A.y*(B.x - C.x)); float gamma_4 = 1.0 - alpha_4 - beta_4; float alpha_5 = (B.y*C.x - B.x*C.y + uv_5.x*(C.y - B.y) + uv_5.y*(B.x - C.x)) / (B.y*C.x - B.x*C.y + A.x*(C.y - B.y) + A.y*(B.x - C.x)); float beta_5 = (B.y*A.x - B.x*A.y + uv_5.x*(A.y - B.y) + uv_5.y*(B.x - A.x)) / (B.y*C.x - B.x*C.y + A.x*(C.y - B.y) + A.y*(B.x - C.x)); float gamma_5 = 1.0 - alpha_5 - beta_5; float alpha_6 = (B.y*C.x - B.x*C.y + uv_6.x*(C.y - B.y) + uv_6.y*(B.x - C.x)) / (B.y*C.x - B.x*C.y + A.x*(C.y - B.y) + A.y*(B.x - C.x)); float beta_6 = (B.y*A.x - B.x*A.y + uv_6.x*(A.y - B.y) + uv_6.y*(B.x - A.x)) / (B.y*C.x - B.x*C.y + A.x*(C.y - B.y) + A.y*(B.x - C.x)); float gamma_6 = 1.0 - alpha_6 - beta_6; float alpha_7 = (B.y*C.x - B.x*C.y + uv_7.x*(C.y - B.y) + uv_7.y*(B.x - C.x)) / (B.y*C.x - B.x*C.y + A.x*(C.y - B.y) + A.y*(B.x - C.x)); float beta_7 = (B.y*A.x - B.x*A.y + uv_7.x*(A.y - B.y) + uv_7.y*(B.x - A.x)) / (B.y*C.x - B.x*C.y + A.x*(C.y - B.y) + A.y*(B.x - C.x)); float gamma_7 = 1.0 - alpha_7 - beta_7; float alpha_8 = (B.y*C.x - B.x*C.y + uv_8.x*(C.y - B.y) + uv_8.y*(B.x - C.x)) / (B.y*C.x - B.x*C.y + A.x*(C.y - B.y) + A.y*(B.x - C.x)); float beta_8 = (B.y*A.x - B.x*A.y + uv_8.x*(A.y - B.y) + uv_8.y*(B.x - A.x)) / (B.y*C.x - B.x*C.y + A.x*(C.y - B.y) + A.y*(B.x - C.x)); float gamma_8 = 1.0 - alpha_8 - beta_8; vec2 st = gl_FragCoord.xy/u_resolution.xy - .5;//Calibration for ellipses vec2 st_1 = gl_FragCoord.xy/u_resolution.xy - .5; vec2 st_2 = gl_FragCoord.xy/u_resolution.xy - .5; vec2 st_3 = gl_FragCoord.xy/u_resolution.xy - .5; vec2 st_4 = gl_FragCoord.xy/u_resolution.xy - .5; vec2 st_5 = gl_FragCoord.xy/u_resolution.xy - .5; mat2 rotationMatrix = mat2( cos(theta),-sin(theta),//Rotation for ellipses (main body) sin(theta),cos(theta)); mat2 rotationMatrix_1 = mat2( cos(theta_1),-sin(theta_1),//Rotation for ellipses (2 horns) sin(theta_1),cos(theta_1)); mat2 rotationMatrix_2 = mat2( cos(theta_2),-sin(theta_2), sin(theta_2),cos(theta_2)); mat2 rotationMatrix_3 = mat2( cos(theta_3),-sin(theta_3),//Rotation for ellipses (tail) sin(theta_3),cos(theta_3)); mat2 rotationMatrix_4 = mat2( cos(theta_4),-sin(theta_4), sin(theta_4),cos(theta_4)); mat2 rotationMatrix_5 = mat2( cos(theta_5),-sin(theta_5), sin(theta_5),cos(theta_5)); st.xy *= rotationMatrix; //Rotation for the main body and 2 horns st_1.xy *= rotationMatrix_1; st_2.xy *= rotationMatrix_2; st_3.xy *= rotationMatrix_3; st_4.xy *= rotationMatrix_4; st_5.xy *= rotationMatrix_5; st.x += 0.009 * sin(u_time) * sin(20.0*st.y);//Deformation for the ellipse parts st_1.x += 0.015 * sin(u_time*u_mouse.x*.01) * sin(20.0*st_1.y); st_2.x += 0.015 * sin(u_time*u_mouse.x*.01) * sin(20.0*st_2.y); st_3.x += 0.015 * sin(u_time) * sin(20.0*st_3.y); st_4.x += 0.015 * sin(u_time) * sin(20.0*st_4.y); st_5.x += 0.015 * sin(u_time) * sin(20.0*st_5.y); // Ellipse computation for the main body float ellipse = (st.x - h) * (st.x - h) / (b * b) + (st.y - k) * (st.y - k) / (a * a); // Ellipse computation for the 2 horns float ellipse_1 = (st_1.x - h_1) * (st_1.x - h_1) / (b_1 * b_1) + (st_1.y - k_1) * (st_1.y - k_1) / (a_1 * a_1); float ellipse_2 = (st_2.x - h_2) * (st_2.x - h_2) / (b_2 * b_2) + (st_2.y - k_2) * (st_2.y - k_2) / (a_2 * a_2); //Ellipse computation for the tail float ellipse_3 = (st_3.x - h_3) * (st_3.x - h_3) / (b_3 * b_3) + (st_3.y - k_3) * (st_3.y - k_3) / (a_3 * a_3); float ellipse_4 = (st_4.x - h_4) * (st_4.x - h_4) / (b_4 * b_4) + (st_4.y - k_4) * (st_4.y - k_4) / (a_4 * a_4); float ellipse_5 = (st_5.x - h_5) * (st_5.x - h_5) / (b_5 * b_5) + (st_5.y - k_5) * (st_5.y - k_5) / (a_5 * a_5); vec2 p_1 = (gl_FragCoord.xy/u_resolution.y) * 3.0 - 1.0;//normalization for noises (able to control the pattern scale) vec2 p_2 = (gl_FragCoord.xy/u_resolution.y) * 2.0 - 1.0; colour_out = vec4( 1.0, 1.0, 1.0, 1.0 ); //RGB is not shown but necessary to offer Alpha channel vec4 color_AllObjects; //all obejects except for the water float n_1 = color_1(p_1 * 4.0); float n_2 = color_2(p_2 * 4.0); if((ellipse_1<=1.0)||(ellipse_2<=1.0)){ float stripeCount = 200.0; // Strips computation float stripes = 0.5 * sin(st_1.y * stripeCount * 3.14159); vec3 color_stripe = vec3(.85*stripes,.6*stripes,.0*stripes); color_AllObjects = vec4(color_stripe, 1.0); } else if((alpha_1 >= 0.0 && beta_1 >= 0.0 && gamma_1 >= 0.0) //draw thorns ||(alpha_2 >= 0.0 && beta_2 >= 0.0 && gamma_2 >= 0.0) ||(alpha_3 >= 0.0 && beta_3 >= 0.0 && gamma_3 >= 0.0) ||(alpha_4 >= 0.0 && beta_4 >= 0.0 && gamma_4 >= 0.0) ||(alpha_5 >= 0.0 && beta_5 >= 0.0 && gamma_5 >= 0.0) ||(alpha_6>= 0.0 && beta_6 >= 0.0 && gamma_6 >= 0.0) ||(alpha_7>= 0.0 && beta_7 >= 0.0 && gamma_7 >= 0.0) ||(alpha_8>= 0.0 && beta_8 >= 0.0 && gamma_8 >= 0.0) ){ color_AllObjects = vec4(0.25, 0.14, 0.14, 1.0); } else if((ellipse <= 1.0)){ //draw the main body color_AllObjects = vec4(0.9+ 0.3 * vec3(n_1, n_1, n_1),1.0); } else if((ellipse > 1.0)&&((ellipse_3<=1.0)||(ellipse_4<=1.0)||(ellipse_5<=1.0))){ //draw the tail color_AllObjects = vec4(0.32, 0.08, 0.04, 1.0); } else color_AllObjects = vec4(0.5 + 0.7 * vec3(1.*n_2, .3*n_2, .1*n_2),.0); //draw the background vec2 st_watermask = gl_FragCoord.xy/u_resolution.xy - .5; const vec2 nscale = 4.0*vec2(1.0,6.0); // wave parameters vec2 v = nscale*(st_watermask-0.5)+vec2(u_time*0.2,u_time);//wave speed (vertical/horizontal) const vec2 P = vec2(0.0, 0.0); float alpha = 4.0*u_time;//wave speed vec2 g; float n = psrdnoise(v, P, alpha, g); float w = clamp(0.6-st_watermask.t + 0.01*n, 0.0, 1.0);//water line w += -0.2*smoothstep(0.0, 0.1, w); float mask = aastep(.1,w); // mask "this is water" vec4 watercol = vec4(.1, .0, .4, 0.26); vec3 mixcol = mix(color_AllObjects.rgb, watercol.rgb, mask*watercol.a); colour_out = vec4(mixcol, 1.0); }
Jorunna Parva by Chen Bixuan
// // Name you want to appear with your shader (can be real name or pseudonym): hoangxcao // 【optional】Scientific name of the sea slug: Felimare Californiensis // precision mediump float; uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; vec2 rotate(vec2 point, float angle) { mat2 rotationMatrix = mat2(cos(angle), -sin(angle), sin(angle), cos(angle)); return rotationMatrix * point; } // // Description : Array and textureless GLSL 2D simplex noise function. // Author : Ian McEwan, Ashima Arts. // Maintainer : stegu // Lastmod : 20110822 (ijm) // License : Copyright (C) 2011 Ashima Arts. All rights reserved. // Distributed under the MIT License. See LICENSE file. // https://github.com/ashima/webgl-noise // https://github.com/stegu/webgl-noise // vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 permute(vec3 x) { return mod289(((x*34.0)+10.0)*x); } float snoise(vec2 v) { const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) -0.577350269189626, // -1.0 + 2.0 * C.x 0.024390243902439); // 1.0 / 41.0 // First corner vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); // Other corners vec2 i1; //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 //i1.y = 1.0 - i1.x; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); // x0 = x0 - 0.0 + 0.0 * C.xx ; // x1 = x0 - i1 + 1.0 * C.xx ; // x2 = x0 - 1.0 + 2.0 * C.xx ; vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; // Permutations i = mod289(i); // Avoid truncation effects in permutation vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; // Gradients: 41 points uniformly over a line, mapped onto a diamond. // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; // Normalise gradients implicitly by scaling m // Approximation of: m *= inversesqrt( a0*a0 + h*h ); m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); // Compute final noise value at P vec3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } // // Description : Array and textureless GLSL 2D/3D/4D simplex // noise functions. // Author : Ian McEwan, Ashima Arts. // Maintainer : stegu // Lastmod : 20201014 (stegu) // License : Copyright (C) 2011 Ashima Arts. All rights reserved. // Distributed under the MIT License. See LICENSE file. // https://github.com/ashima/webgl-noise // https://github.com/stegu/webgl-noise // vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 permute(vec4 x) { return mod289(((x*34.0)+10.0)*x); } vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } float snoise(vec3 v) { const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); // First corner vec3 i = floor(v + dot(v, C.yyy) ); vec3 x0 = v - i + dot(i, C.xxx) ; // Other corners vec3 g = step(x0.yzx, x0.xyz); vec3 l = 1.0 - g; vec3 i1 = min( g.xyz, l.zxy ); vec3 i2 = max( g.xyz, l.zxy ); // x0 = x0 - 0.0 + 0.0 * C.xxx; // x1 = x0 - i1 + 1.0 * C.xxx; // x2 = x0 - i2 + 2.0 * C.xxx; // x3 = x0 - 1.0 + 3.0 * C.xxx; vec3 x1 = x0 - i1 + C.xxx; vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y // Permutations i = mod289(i); vec4 p = permute( permute( permute( i.z + vec4(0.0, i1.z, i2.z, 1.0 )) + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); // Gradients: 7x7 points over a square, mapped onto an octahedron. // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) float n_ = 0.142857142857; // 1.0/7.0 vec3 ns = n_ * D.wyz - D.xzx; vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) vec4 x_ = floor(j * ns.z); vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) vec4 x = x_ *ns.x + ns.yyyy; vec4 y = y_ *ns.x + ns.yyyy; vec4 h = 1.0 - abs(x) - abs(y); vec4 b0 = vec4( x.xy, y.xy ); vec4 b1 = vec4( x.zw, y.zw ); //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; vec4 s0 = floor(b0)*2.0 + 1.0; vec4 s1 = floor(b1)*2.0 + 1.0; vec4 sh = -step(h, vec4(0.0)); vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; vec3 p0 = vec3(a0.xy,h.x); vec3 p1 = vec3(a0.zw,h.y); vec3 p2 = vec3(a1.xy,h.z); vec3 p3 = vec3(a1.zw,h.w); //Normalise gradients vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); p0 *= norm.x; p1 *= norm.y; p2 *= norm.z; p3 *= norm.w; // Mix final noise value vec4 m = max(0.5 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); m = m * m; return 105.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) ); } float cro(in vec2 a, in vec2 b ) { return a.x*b.y - a.y*b.x; } /////////////// K.jpg's Re-oriented 8-Point BCC Noise (OpenSimplex2S) //////////////// ////////////////////// Output: vec4(dF/dx, dF/dy, dF/dz, value) ////////////////////// // Gradient set is a normalized expanded rhombic dodecahedron vec3 grad(float hash) { // Random vertex of a cube, +/- 1 each vec3 cube = mod(floor(hash / vec3(1.0, 2.0, 4.0)), 2.0) * 2.0 - 1.0; // Random edge of the three edges connected to that vertex // Also a cuboctahedral vertex // And corresponds to the face of its dual, the rhombic dodecahedron vec3 cuboct = cube; cuboct[int(hash / 16.0)] = 0.0; // In a funky way, pick one of the four points on the rhombic face float type = mod(floor(hash / 8.0), 2.0); vec3 rhomb = (1.0 - type) * cube + type * (cuboct + cross(cube, cuboct)); // Expand it so that the new edges are the same length // as the existing ones vec3 grad = cuboct * 1.22474487139 + rhomb; // To make all gradients the same length, we only need to shorten the // second type of vector. We also put in the whole noise scale constant. // The compiler should reduce it into the existing floats. I think. grad *= (1.0 - 0.042942436724648037 * type) * 3.5946317686139184; return grad; } // BCC lattice split up into 2 cube lattices vec4 openSimplex2SDerivativesPart(vec3 X) { vec3 b = floor(X); vec4 i4 = vec4(X - b, 2.5); // Pick between each pair of oppposite corners in the cube. vec3 v1 = b + floor(dot(i4, vec4(.25))); vec3 v2 = b + vec3(1, 0, 0) + vec3(-1, 1, 1) * floor(dot(i4, vec4(-.25, .25, .25, .35))); vec3 v3 = b + vec3(0, 1, 0) + vec3(1, -1, 1) * floor(dot(i4, vec4(.25, -.25, .25, .35))); vec3 v4 = b + vec3(0, 0, 1) + vec3(1, 1, -1) * floor(dot(i4, vec4(.25, .25, -.25, .35))); // Gradient hashes for the four vertices in this half-lattice. vec4 hashes = permute(mod(vec4(v1.x, v2.x, v3.x, v4.x), 289.0)); hashes = permute(mod(hashes + vec4(v1.y, v2.y, v3.y, v4.y), 289.0)); hashes = mod(permute(mod(hashes + vec4(v1.z, v2.z, v3.z, v4.z), 289.0)), 48.0); // Gradient extrapolations & kernel function vec3 d1 = X - v1; vec3 d2 = X - v2; vec3 d3 = X - v3; vec3 d4 = X - v4; vec4 a = max(0.75 - vec4(dot(d1, d1), dot(d2, d2), dot(d3, d3), dot(d4, d4)), 0.0); vec4 aa = a * a; vec4 aaaa = aa * aa; vec3 g1 = grad(hashes.x); vec3 g2 = grad(hashes.y); vec3 g3 = grad(hashes.z); vec3 g4 = grad(hashes.w); vec4 extrapolations = vec4(dot(d1, g1), dot(d2, g2), dot(d3, g3), dot(d4, g4)); // Derivatives of the noise vec3 derivative = -8.0 * mat4x3(d1, d2, d3, d4) * (aa * a * extrapolations) + mat4x3(g1, g2, g3, g4) * aaaa; // Return it all as a vec4 return vec4(derivative, dot(aaaa, extrapolations)); } // Use this if you don't want Z to look different from X and Y vec4 openSimplex2SDerivatives_Conventional(vec3 X) { X = dot(X, vec3(2.0/3.0)) - X; vec4 result = openSimplex2SDerivativesPart(X) + openSimplex2SDerivativesPart(X + 144.5); return vec4(dot(result.xyz, vec3(2.0/3.0)) - result.xyz, result.w); } // Use this if you want to show X and Y in a plane, then use Z for time, vertical, etc. vec4 openSimplex2SDerivatives_ImproveXY(vec3 X) { // Not a skew transform. mat3 orthonormalMap = mat3( 0.788675134594813, -0.211324865405187, -0.577350269189626, -0.211324865405187, 0.788675134594813, -0.577350269189626, 0.577350269189626, 0.577350269189626, 0.577350269189626); X = orthonormalMap * X; vec4 result = openSimplex2SDerivativesPart(X) + openSimplex2SDerivativesPart(X + 144.5); return vec4(result.xyz * orthonormalMap, result.w); } //////////////////////////////// End noise code //////////////////////////////// // // Description : Inigo Quilez’s Blog on 2D distance functions. // Author : Inigo Quilez. // License : https://iquilezles.org/articles/distfunctions2d/ // float msign(in float x) { return (x<0.0)?-1.0:1.0; } // Ellipse float sdEllipse( vec2 p, in vec2 ab ) { //if( ab.x==ab.y ) return length(p)-ab.x; p = abs( p ); if( p.x>p.y ){ p=p.yx; ab=ab.yx; } float l = ab.y*ab.y - ab.x*ab.x; float m = ab.x*p.x/l; float n = ab.y*p.y/l; float m2 = m*m; float n2 = n*n; float c = (m2+n2-1.0)/3.0; float c3 = c*c*c; float d = c3 + m2*n2; float q = d + m2*n2; float g = m + m *n2; float co; if( d<0.0 ) { float h = acos(q/c3)/3.0; float s = cos(h) + 2.0; float t = sin(h) * sqrt(3.0); float rx = sqrt( m2-c*(s+t) ); float ry = sqrt( m2-c*(s-t) ); co = ry + sign(l)*rx + abs(g)/(rx*ry); } else { float h = 2.0*m*n*sqrt(d); float s = msign(q+h)*pow( abs(q+h), 1.0/3.0 ); float t = msign(q-h)*pow( abs(q-h), 1.0/3.0 ); float rx = -(s+t) - c*4.0 + 2.0*m2; float ry = (s-t)*sqrt(3.0); float rm = sqrt( rx*rx + ry*ry ); co = ry/sqrt(rm-rx) + 2.0*g/rm; } co = (co-m)/2.0; float si = sqrt( max(1.0-co*co,0.0) ); vec2 r = ab * vec2(co,si); return length(r-p) * msign(p.y-r.y); } // Arc float sdArc( in vec2 p, in vec2 sc, in float ra, float rb, bool mirrorX ) { p.x = abs(p.x); if (mirrorX) { // Mirroring point 'p' across the x-axis p.y = -p.y; } return ((sc.y*p.x>sc.x*p.y) ? length(p-sc*ra) : abs(length(p)-ra)) - rb; } // Blobby cross float sdBlobbyCross( in vec2 pos, float he ) { pos = abs(pos); pos = vec2(abs(pos.x-pos.y),1.0-pos.x-pos.y)/sqrt(2.0); float p = (he-pos.y-0.25/he)/(6.0*he); float q = pos.x/(he*he*16.0); float h = q*q - p*p*p; float x; if( h>0.0 ) { float r = sqrt(h); x = pow(q+r,1.0/3.0) - pow(abs(q-r),1.0/3.0)*sign(r-q); } else { float r = sqrt(p); x = 2.0*r*cos(acos(q/(p*r))/3.0); } x = min(x,sqrt(2.0)/2.0); vec2 z = vec2(x,he*(1.0-2.0*x*x)) - pos; return length(z) * sign(z.y); } // Heart float dot2( in vec2 v ) { return dot(v,v); } float sdHeart( in vec2 p ) { p.x = abs(p.x); if( p.y+p.x>1.0 ) return sqrt(dot2(p-vec2(0.25,0.75))) - sqrt(2.0)/4.0; return sqrt(min(dot2(p-vec2(0.00,1.00)), dot2(p-0.5*max(p.x+p.y,0.0)))) * sign(p.x-p.y); } float color(vec2 xy) { return 0.7 * snoise(vec3(xy, 0.3*u_time)); } void main() { // Normalize coordinates to range [0, 1] vec2 uv = (gl_FragCoord.xy / u_resolution.xy); // Center the coordinates uv -= 0.5; // Define the sea slug shape using a signed distance function (SDF) float sdf = sdEllipse(uv, vec2(0.4, 0.18)); // Define the antennae vec2 antenna1Coord = 3.0 * uv; antenna1Coord.x += 1.2; antenna1Coord.y += 0.4; vec2 sc1 = vec2(sin(1.0),cos(1.0)); float antenna1 = sdArc(antenna1Coord, sc1, 0.3, 0.01, false); vec2 antenna2Coord = 3.0*uv; antenna2Coord.x +=1.2; antenna2Coord.y -=0.4; vec2 sc2 = vec2(sin(1.0),cos(1.0)); float antenna2 = sdArc(antenna2Coord, sc2, 0.3, 0.01, true); // Define the tentacles vec2 tentacle1Coord = 8.0 * uv; tentacle1Coord.y -= 1.1; tentacle1Coord = rotate(tentacle1Coord, radians(45.0)); // Apply rotation float tentacle1 = sdBlobbyCross(tentacle1Coord, 0.6) - 0.15; vec2 tentacle2Coord = 8.0 * uv; tentacle2Coord.y += 1.1; tentacle2Coord = rotate(tentacle2Coord, radians(45.0)); // Apply rotation float tentacle2 = sdBlobbyCross( tentacle2Coord, 0.6 ) - 0.15; // Define the eyes vec2 eyesPos = 8.0 * uv; eyesPos.x += 2.2; eyesPos = rotate(eyesPos, radians(90.0)); // Apply rotation float eyes = sdHeart(eyesPos); // Combining shapes float anteannea = min(antenna1, antenna2); float tentacles = min(tentacle1, tentacle2); sdf = min(sdf, min(min(anteannea, tentacles), eyes)); // Add Perlin noise to the sea slug float noiseValue = snoise(vec3(uv * 2.0, u_time * 0.1)); float sdfWithNoise = sdf + 0.1 * noiseValue; // Apply anti-aliasing to the edges of the shape float aa = smoothstep(0.02, 0.01, sdfWithNoise); // // Define the color of the sea slug with a gradient from black to dark blue // // Scale the uv coordinates to create an ellipse uv.y *= 2.5; // Calculate the distance from the center float distance = length(uv); // Calculate the intensity using the exponential function float intensity = exp(-distance); // Define the colors vec4 centerCol = vec4(0.2, 0.2, 1.0, 1.0); vec4 circumferenceCol = vec4(0.0, 0.0, 0.0, 1.0); // Define a pattern for the sea slug body with noise vec2 st = gl_FragCoord.xy / u_resolution.xy; st.x *= u_resolution.x / u_resolution.y; vec3 color = vec3(0.0); vec2 pos = vec2(st * 3.0); float DF = 0.0; // Add a random position float a = 0.0; vec2 vel = vec2(u_time * 0.1); DF += snoise(pos + vel) * 0.25 + 0.25; // Add a random position a = snoise(pos * vec2(cos(u_time * 0.15), sin(u_time * 0.1)) * 0.1) * 3.1415; vel = vec2(cos(a), sin(a)); DF += snoise(pos + vel) * 0.25+.25; color = vec3(1.0, 1.0, 0.0) * smoothstep(0.7, 0.75, fract(DF)); // Set the background color to dark blue vec3 background = mix(centerCol, circumferenceCol, intensity).xyz; color = mix(background, color, color); // // Drawing the ocean background // // Normalized pixel coordinates (from 0 to 1 on largest axis) vec2 uv2 = gl_FragCoord.xy / max(u_resolution.x, u_resolution.y) * 8.0; // Initial input point vec3 X = vec3(uv2, mod(u_time, 578.0) * 0.8660254037844386); // Evaluate noise once vec4 noiseResult = openSimplex2SDerivatives_ImproveXY(X); // Evaluate noise again with the derivative warping the domain // Might be able to approximate this by fitting to a curve instead noiseResult = openSimplex2SDerivatives_ImproveXY(X - noiseResult.xyz / 16.0); float value = noiseResult.w; // Time varying pixel color vec3 col = vec3(.431, 0.8, 1.0) * (0.5 + 0.5 * value); // Set the final fragment color for the background vec3 finalColor = mix(col, color, aa); // Set the final fragment color colour_out = vec4(finalColor, 1.0); }
Felimare Californiensis by hoangxcao
// credit: wh // sea slug: Nembrotha aurea Bernard Picton uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; float sdArc( in vec2 p, in vec2 sc, in float ra, float rb ) { // sc is the sin/cos of the arc's aperture p.x = abs(p.x); return ((sc.y*p.x>sc.x*p.y) ? length(p-sc*ra) : abs(length(p)-ra)) - rb; } float sdf( vec2 p ) { return sdArc(p, vec2(0.940,0.330),0.596,0.228); } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; st-=0.508; st.y+=0.220; st*=2.0; float d = sdf(st.xy); float mask = 0.984; float mask1 = -0.008; mask1 -= sin(u_time*0.8)*0.16; mask *= step( 0.188, distance( st.xy+st.y*1.132, vec2(1.000,0.300) ) ); mask *= step( 0.092, distance( st.xy, vec2(0.510,0.060) ) ); mask *= step( 0.220, distance( st.xy+st.y*3.452+st.x*st.x, vec2(1.950,2.970) ) ); mask *= step( 0.188, distance( st.xy+st.y*1.132, vec2(0.400,1.640) ) ); mask *= step( 0.188, distance( st.xy+st.x*1.132, vec2(-0.630,0.590) ) ); vec3 col = vec3(1.000,0.967,0.894) - sign(d) * vec3(0.700,0.200,0.051); col *= 0.928 - exp(-3.688*abs(d)); col *= 1.160 + 0.200*cos(155.392*d); col = mix( col, vec3(1.000,0.984,0.964), 1.0-smoothstep(0.0,0.018,abs(d)) ); colour_out = vec4(col,1.0); colour_out.x+=1.0-mask; colour_out +=mask1; }
Nembrotha aurea Bernard Picton by
wh
// credit: jikihakase (will show up on website) // sea slug: Costasiella kuroshimae uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; float mask = 1.0; mask *= step( 0.03, distance( st.xy, vec2(0.150,0.680) ) ); mask *= step( 0.04, distance( st.xy, vec2(0.180,0.680) ) ); mask *= step( 0.05, distance( st.xy, vec2(0.220,0.680) ) ); mask *= step( 0.05, distance( st.xy, vec2(0.260,0.680) ) ); mask *= step( 0.05, distance( st.xy, vec2(0.290,0.680) ) ); mask *= step( 0.05, distance( st.xy, vec2(0.320,0.680) ) ); mask *= step( 0.05, distance( st.xy, vec2(0.350,0.680) ) ); mask *= step( 0.05, distance( st.xy, vec2(0.380,0.660) ) ); mask *= step( 0.06, distance( st.xy, vec2(0.410,0.660) ) ); mask *= step( 0.06, distance( st.xy, vec2(0.440,0.630) ) ); mask *= step( 0.06, distance( st.xy, vec2(0.440,0.570) ) ); mask *= step( 0.06, distance( st.xy, vec2(0.460,0.510) ) ); mask *= step( 0.06, distance( st.xy, vec2(0.510,0.400) ) ); mask *= step( 0.06, distance( st.xy, vec2(0.470,0.450) ) ); mask *= step( 0.06, distance( st.xy, vec2(0.570,0.340) ) ); mask *= step( 0.06, distance( st.xy, vec2(0.570,0.370) ) ); mask *= step( 0.06, distance( st.xy, vec2(0.700,0.330) ) ); mask *= step( 0.06, distance( st.xy, vec2(0.640,0.340) ) ); //Add Triangle float tri1 = atan(st.x-0.736, 0.488 - st.y); float tri2 = atan(st.x-0.720, 0.472 - st.y); float tri3 = atan(st.x-0.704, st.y - 0.260); float tri4 = distance(st.x-0.800, -0.366 + st.y); //mask *= step(0.1, length(vec2(tri1, tri2)) + -0.064); mask *= step(0.1, length(vec2(tri3, tri1)) - 0.118); mask *= step(0.1, length(vec2(tri4, tri2)) + 0.054); //noise(colour_out); colour_out = vec4( st.x, st.y, abs(sin(3.0*u_time)), 1.0 ); colour_out *= 1.0-mask; }
Costasiella kuroshimae by anonymous
// credit: Ruijie Ren (will show up on website) // sea slug: Fellimara Picta Nudibranch uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; float cro(vec2 a,vec2 b ) { return a.x*b.y - a.y*b.x; } float sdUnevenCapsule(vec2 p,vec2 pa,vec2 pb,float ra,float rb ) { p -= pa; pb -= pa; float h = dot(pb,pb); vec2 q = vec2( dot(p,vec2(pb.y,-pb.x)), dot(p,pb) )/h; //----------- q.x = abs(q.x); float b = ra-rb; vec2 c = vec2(sqrt(h-b*b),b); float k = cro(c,q); float m = dot(c,q); float n = dot(q,q); if( k < 0.0 ) return sqrt(h*(n )) - ra; else if( k > c.x ) return sqrt(h*(n+1.0-2.0*q.y)) - rb; return m - ra; } // b.x = width // b.y = height // r.x = roundness top-right // r.y = roundness boottom-right // r.z = roundness top-left // r.w = roundness bottom-left float sdRoundBox( in vec2 p, in vec2 b, in vec4 r ) { r.xy = (p.x>0.0)?r.xy : r.zw; r.x = (p.y>0.0)?r.x : r.y; vec2 q = abs(p)-b+r.x; return min(max(q.x,q.y),0.0) + length(max(q,0.0)) - r.x; } float get_edge_mask(vec2 p) { vec2 si = vec2(0.5+ 0.01*sin(u_time),0.9+ 0.05*sin(u_time)) ; vec4 ra = 0.4 + 0.2*cos( 1.0*u_time + vec4(3,1,1,2) ); ra = min(ra,min(si.x,si.y)); vec2 b = vec2(0.5,0.9); vec4 r = vec4(0.0,0.0,0.0,0.0); float r1 = 0.45*(1.+0.1*sin(u_time)); float r2 = 0.35*(1.-0.1*sin(u_time)); float d = step( 0.001, sdRoundBox( p, si, ra )); return d; } float get_body_mask(vec2 p) { vec2 v1 = vec2(0.0,-0.40); vec2 v2 = vec2(0.0,0.450); float r1 = 0.45*(1.+0.1*sin(u_time)); float r2 = 0.35*(1.-0.1*sin(u_time)); float d = step( 0.01,sdUnevenCapsule( p, v1, v2, r1, r2 )); return d; } float get_tentacle_left(vec2 p) { vec2 v1 = vec2(-0.5,-0.40); vec2 v2 = vec2(-0.9+0.02*sin(u_time),0.1-0.02*sin(u_time)); float r1 = 0.04; float r2 = 0.02; vec2 p2 = vec2(p.x - 0.2, p.y - 0.8); float d = step( 0.01,sdUnevenCapsule( p2, v1, v2, r1, r2 )); return d; } float get_tentacle_right(vec2 p) { vec2 v1 = ( vec2(0.5,-0.40) + 0.0 ); vec2 v2 = vec2(0.8+0.02*sin(u_time),-0.04*sin(u_time)); float r1 = 0.04; float r2 = 0.02; vec2 p2 = vec2(p.x + 0.2,p.y - 0.8); float d = step( 0.01,sdUnevenCapsule( p2, v1, v2, r1, r2 )); return d; } float get_mask(vec2 st, vec2 p) { float mask = 1.0; mask *= get_body_mask(p); mask *= get_tentacle_left(p); mask *= get_tentacle_right(p); mask *= get_edge_mask(p); return mask; } vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 permute(vec3 x) { return mod289(((x*34.0)+10.0)*x); } float snoise(vec2 v) { const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) -0.577350269189626, // -1.0 + 2.0 * C.x 0.024390243902439); // 1.0 / 41.0 // First corner vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); // Other corners vec2 i1; //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 //i1.y = 1.0 - i1.x; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); // x0 = x0 - 0.0 + 0.0 * C.xx ; // x1 = x0 - i1 + 1.0 * C.xx ; // x2 = x0 - 1.0 + 2.0 * C.xx ; vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; // Permutations i = mod289(i); // Avoid truncation effects in permutation vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; // Gradients: 41 points uniformly over a line, mapped onto a diamond. // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; // Normalise gradients implicitly by scaling m // Approximation of: m *= inversesqrt( a0*a0 + h*h ); m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); // Compute final noise value at P vec3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } float marbleturbulence( vec2 p ) { /* Same as the turbulence before. */ float f = 0.0, scale; for (int i=0; i<4; i++) { scale = pow( pow(2.0, 4.0/3.0), float(i) ); f += abs( snoise( p * scale ) ) / scale; } return f; } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec2 p = st * 2.0 - 1.0; float foreground_mask = get_mask(st,p); vec4 tentacle_c = vec4(0.3176, 0.1608, 0.9412, 1.0); vec4 body_c = vec4(0.1333, 0.0627, 0.6667, 1.0); vec4 strip_c = vec4(0.9804, 0.9686, 0.2235, 1.0); vec4 edge_c = vec4(0.8196, 0.7961, 0.0941, 1.0); float n = marbleturbulence( st ); float strip = 0.2+sin( (st.x * u_resolution.x) / (3.5+0.2*sin(u_time)) + 5. * n ); float dot_mask = snoise(st*35. + .3*sin(u_time) ); float body_mask = 1.0; body_mask *= get_body_mask(p); float tentacle_mask = 1.0; tentacle_mask *= get_tentacle_left(p); tentacle_mask *= get_tentacle_right(p); vec4 strip_mix = mix(body_c, strip_c, vec4(step(1.5, (strip+dot_mask)*(1.0 - body_mask)*tentacle_mask ))); vec4 colour_layer = mix(strip_mix, vec4(1, 1, 1, 1.0), foreground_mask); float edge_mask = 1.0; edge_mask *= get_edge_mask(p); colour_layer = mix(colour_layer, edge_c, (body_mask-edge_mask)); colour_out = mix(tentacle_c, colour_layer, tentacle_mask); }
Fellimara Picta Nudibranch by Ruijie Ren
// credit: Ninomiya Asuka // sea slug: Fellimara Picta Nudibranch uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; float sdRoundedBox(in vec2 p, in vec2 b, in vec4 r) { r.xy = (p.x > 0.0) ? r.xy : r.zw; r.x = (p.y > 0.0) ? r.x : r.y; vec2 q = abs(p) - b + r.x; return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r.x; } float sdTriangle(in vec2 p, in vec2 p0, in vec2 p1, in vec2 p2) { vec2 e0 = p1 - p0, e1 = p2 - p1, e2 = p0 - p2; vec2 v0 = p - p0, v1 = p - p1, v2 = p - p2; vec2 pq0 = v0 - e0 * clamp(dot(v0, e0) / dot(e0, e0), 0.0, 1.0); vec2 pq1 = v1 - e1 * clamp(dot(v1, e1) / dot(e1, e1), 0.0, 1.0); vec2 pq2 = v2 - e2 * clamp(dot(v2, e2) / dot(e2, e2), 0.0, 1.0); float s = sign(e0.x * e2.y - e0.y * e2.x); vec2 d = min(min(vec2(dot(pq0, pq0), s * (v0.x * e0.y - v0.y * e0.x)), vec2(dot(pq1, pq1), s * (v1.x * e1.y - v1.y * e1.x))), vec2(dot(pq2, pq2), s * (v2.x * e2.y - v2.y * e2.x))); return -sqrt(d.x) * sign(d.y); } float sdUnevenCapsule(vec2 p, float r1, float r2, float h) { p.x = abs(p.x); float b = (r1 - r2) / h; float a = sqrt(1.0 - b * b); float k = dot(p, vec2(-b, a)); if (k < 0.0) return length(p) - r1; if (k > a * h) return length(p - vec2(0.0, h)) - r2; return dot(p, vec2(a, b)) - r1; } float pointToLineDistance(vec2 point, vec2 lineStart, vec2 lineEnd) { vec2 lineDirection = normalize(lineEnd - lineStart); vec2 pointToLineStart = point - lineStart; float projection = dot(pointToLineStart, lineDirection); if (projection <= 0.0) { return length(pointToLineStart); } else if (projection >= length(lineEnd - lineStart)) { return length(point - lineEnd); } else { vec2 pointOnLine = lineStart + projection * lineDirection; return length(point - pointOnLine); } } vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.)) * 289.; } vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.)) * 289.; } vec4 permute(vec4 x) { return mod289((34.0 * x + 10.0) * x); } vec4 mod7(vec4 x) { return x - floor(x * (1.0 / 7.0)) * 7.; } vec2 cellular2x2(vec2 P) { #define K 0.142857142857 // 1/7 #define K2 0.0714285714285 // K/2 #define jitter 0.8 // jitter 1.0 makes F1 wrong more often vec2 Pi = mod289(floor(P)); vec2 Pf = fract(P); vec4 Pfx = Pf.x + vec4(-0.5, -1.5, -0.5, -1.5); vec4 Pfy = Pf.y + vec4(-0.5, -0.5, -1.5, -1.5); vec4 p = permute(Pi.x + vec4(0.0, 1.0, 0.0, 1.0)); p = permute(p + Pi.y + vec4(0.0, 0.0, 1.0, 1.0)); vec4 ox = mod7(p) * K + K2; vec4 oy = mod7(floor(p * K)) * K + K2; vec4 dx = Pfx + jitter * ox; vec4 dy = Pfy + jitter * oy; vec4 d = dx * dx + dy * dy; // d11, d12, d21 and d22, squared // Sort out the two smallest distances #if 0 // Cheat and pick only F1 d.xy = min(d.xy, d.zw); d.x = min(d.x, d.y); return vec2(sqrt(d.x)); // F1 duplicated, F2 not computed #else // Do it right and find both F1 and F2 d.xy = (d.x < d.y) ? d.xy : d.yx; // Swap if smaller d.xz = (d.x < d.z) ? d.xz : d.zx; d.xw = (d.x < d.w) ? d.xw : d.wx; d.y = min(d.y, d.z); d.y = min(d.y, d.w); return sqrt(d.xy); #endif } void main() { vec2 st = gl_FragCoord.xy / u_resolution.xy; float mask = 1.0; float isInnerBody = step(0.0, sdUnevenCapsule(st.xy - vec2(0.5, 0.5), 0.2, 0.15, 0.3)); float isOuterBody = step(0.0, sdUnevenCapsule(st.xy - vec2(0.5, 0.5), 0.23, 0.18, 0.3)); float isAntenna1 = step(0.0, sdTriangle(st.xy, vec2(0.4, 0.8), vec2(0.45, 0.85), vec2(0.25, 0.95))); float isAntenna2 = step(0.0, sdTriangle(st.xy, vec2(0.6, 0.8), vec2(0.55, 0.85), vec2(0.75, 0.95))); mask *= isInnerBody * isAntenna1 * isAntenna2; if (isAntenna1 == 0.0) { float dis = pointToLineDistance(st.xy, vec2(0.35, 0.7), vec2(0.45, 0.8)); vec3 color1 = vec3(0.0, 0.0, 1.0); vec3 color2 = vec3(0.0, 0.0, 0.0); float interval = 0.01; float position = mod(dis, interval); colour_out = vec4(mix(color1, color2, step(0.5 * interval, position)), 1.0); colour_out *= 1.0 - mask; } else if (isAntenna2 == 0.0) { float dis = pointToLineDistance(st.xy, vec2(0.65, 0.7), vec2(0.55, 0.8)); vec3 color1 = vec3(0.0, 0.0, 1.0); vec3 color2 = vec3(0.0, 0.0, 0.0); float interval = 0.01; float position = mod(dis, interval); colour_out = vec4(mix(color1, color2, step(0.5 * interval, position)), 1.0); colour_out *= 1.0 - mask; } else if (isInnerBody == 0.0) { colour_out = vec4(1.0, 1.0, 1.0, 1.0); vec2 F = cellular2x2(st * 20.952); float n = 1.0 - step(abs(sin(3.494 * 30.284)), F.x * 2.488); colour_out = vec4(n, n, 0.0, 1.0); colour_out *= 1.0 - mask; } else if (isOuterBody == 0.0) { colour_out = vec4(1.0, 1.0, 0.0, 1.0); } else { colour_out = vec4(1.0); } }
Fellimara Picta Nudibranch by Ninomiya Asuka
// credit: Eibaloch // sea slug: Fellimara picta Victor Micallef uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; // GLSL textureless classic 2D noise "cnoise", // with an RSL-style periodic variant "pnoise". // Author: Stefan Gustavson (stefan.gustavson@liu.se) // Version: 2011-08-22 // // Many thanks to Ian McEwan of Ashima Arts for the // ideas for permutation and gradient selection. // // Copyright (c) 2011 Stefan Gustavson. All rights reserved. // Distributed under the MIT license. See LICENSE file. // https://github.com/stegu/webgl-noise float cro(in vec2 a, in vec2 b ) { return a.x*b.y - a.y*b.x; } vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 permute(vec4 x) { return mod289(((x*34.0)+10.0)*x); } vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } vec2 fade(vec2 t) { return t*t*t*(t*(t*6.0-15.0)+10.0); } //Classic Perlin Noise float cnoise(vec2 P) { vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0); vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0); Pi = mod289(Pi); // To avoid truncation effects in permutation vec4 ix = Pi.xzxz; vec4 iy = Pi.yyww; vec4 fx = Pf.xzxz; vec4 fy = Pf.yyww; vec4 i = permute(permute(ix) + iy); vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0 ; vec4 gy = abs(gx) - 0.5 ; vec4 tx = floor(gx + 0.5); gx = gx - tx; vec2 g00 = vec2(gx.x,gy.x); vec2 g10 = vec2(gx.y,gy.y); vec2 g01 = vec2(gx.z,gy.z); vec2 g11 = vec2(gx.w,gy.w); vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); g00 *= norm.x; g01 *= norm.y; g10 *= norm.z; g11 *= norm.w; float n00 = dot(g00, vec2(fx.x, fy.x)); float n10 = dot(g10, vec2(fx.y, fy.y)); float n01 = dot(g01, vec2(fx.z, fy.z)); float n11 = dot(g11, vec2(fx.w, fy.w)); vec2 fade_xy = fade(Pf.xy); vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x); float n_xy = mix(n_x.x, n_x.y, fade_xy.y); return 2.3 * n_xy; } // Copyright © 2018 Inigo Quilez // and https://iquilezles.org/articles/distfunctions2d float sdUnevenCapsule( in vec2 p, in vec2 pa, in vec2 pb, in float ra, in float rb ) { p -= pa; pb -= pa; float h = dot(pb,pb); vec2 q = vec2( dot(p,vec2(pb.y,-pb.x)), dot(p,pb) )/h; //----------- q.x = abs(q.x); float b = ra-rb; vec2 c = vec2(sqrt(h-b*b),b); float k = cro(c,q); float m = dot(c,q); float n = dot(q,q); if( k < 0.0 ) return sqrt(h*(n )) - ra; else if( k > c.x ) return sqrt(h*(n+1.0-2.0*q.y)) - rb; return m - ra; } float sdOrientedVesica( vec2 p, vec2 a, vec2 b, float w ) { float r = 0.5*length(b-a); float d = 0.5*(r*r-w*w)/w; vec2 v = (b-a)/r; vec2 c = (b+a)*0.5; vec2 q = 0.5*abs(mat2(v.y,v.x,-v.x,v.y)*(p-c)); vec3 h = (r*q.x<d*(q.y-r)) ? vec3(0.0,r,0.0) : vec3(-d,0.0,d+w); return length( q-h.xy) - h.z; } float sdCircle( vec2 p, float r ) { return length(p)-r; } float sdUnion( float d1, float d2 ) { return min( d1, d2 ); } float sdDifference( float d1, float d2 ) { return max( -d1, d2 ); /* Remove d1 from d2 */ } float sdIntersection( float d1, float d2 ) { return max( d1, d2 ); } float sdfAntenna_front( vec2 p ) { vec4 v1 = vec4(-3.6,2.00,-3.0,.20) ; float r1 = 0.3+0.1*sin(u_time); float r2 = 0.5+0.1*sin(1.0+2.3); float d = sdUnevenCapsule( p, v1.xy, v1.zw, r1, r2 ); return d; } float sdfAntenna_back( vec2 p ) { vec4 v1 = vec4(-2.,2.00,-2.0,.20) ; float r1 = 0.3+0.1*sin(u_time); float r2 = 0.5+0.1*sin(1.0+2.3); float d = sdUnevenCapsule( p, v1.xy, v1.zw, r1, r2 ); return d; } float sdfbody1( vec2 p ){ //slugPosition p-=vec2(-1.,-2.0); //head float h = sdCircle(p - vec2(-1.6,-0.7),2.5); //Different body parts vec4 v1 = vec4(-.9,.5,5.50,-1.8) ; float r1 = 7.*0.3+0.1*sin(u_time); float r2 = 3.*0.5+0.1*sin(1.0+2.3); float d_1 = sdUnevenCapsule( p, v1.xy, v1.zw, r1, r2 ); vec4 v2 = vec4 (4.,-1.8,-1,-1.50) ; float r2_1 = 5.*0.3+0.1*sin(u_time); float r2_2 = 3.*0.5+0.1*sin(1.0+2.3); float d_2 = sdUnevenCapsule( p, v2.xy, v2.zw, r2_1, r2_2 ); vec4 v3 = vec4 (-1.,-2.8,-1,.50) ; float r3_1 = 2.*0.3+0.1*sin(u_time); float r3_2 = 3.*0.5+0.1*sin(1.0+2.3); float d_3 = sdUnevenCapsule( p, v3.xy, v3.zw, r3_1, r3_2 ); vec4 v4 = vec4 (0.5,-2.99,-1,.50) ; float r4_1 = 2.*0.3+0.1*sin(u_time); float r4_2 = 3.*0.5+0.1*sin(1.0+2.3); float d_4 = sdUnevenCapsule( p, v4.xy, v4.zw, r4_1, r4_2 ); vec4 v5 = vec4 (1.8,-2.8,-1,.50) ; float r5_1 = 2.*0.3+0.1*sin(u_time); float r5_2 = 3.*0.5+0.1*sin(1.0+2.3); float d_5 = sdUnevenCapsule( p, v5.xy, v5.zw, r5_1, r5_2 ); //3rd part float e_1 = sdOrientedVesica(p-vec2(-5.,-3.), .1* vec2(3.,3.00 ),2.1* vec2(3.,2.00 ),7.*0.40*(0.5+0.495*cos(89.))); float e_2 = sdOrientedVesica(p-vec2(3.5,-2.), .1* vec2(4.,3.00 ),2.1*vec2(2.,00 ),4.*0.40*(0.5+0.495*cos(89.))); //Combing shapes float k_1 = sdUnion(d_1,d_2); float k_2 = sdUnion(k_1,h); float k_3 = sdUnion(k_2,e_1); float k_4 = sdUnion(k_3,e_2); float k_5 = sdUnion(k_4,d_3); float k_6 = sdUnion(k_5,d_4); float k_7 = sdUnion(k_6,d_5); return k_7; } float t_1(vec2 uv){ float m = cnoise(vec2(cnoise(uv*2.),cnoise(uv*-1.))); return m; } vec2 random2( vec2 p ) { return fract(sin(vec2(dot(p,vec2(127.1,311.7)),dot(p,vec2(269.5,183.3))))*43758.5453); } void main() { vec2 uv = gl_FragCoord.xy/u_resolution.xy; uv = uv-0.5; uv = uv * u_resolution/36.; vec3 color = vec3(0.34, 0.3, 0.44); vec2 center = vec2(0,0); float mask_1 = sdfAntenna_front(uv); float mask_3 = sdfAntenna_back(uv); float mask_2 = sdfbody1(uv); //Additional texture noise (Book of Shaders code) vec3 bg_color = vec3(0.16, 0.4, 0.59); vec2 st = uv; st *= .9; // Tile the space vec2 i_st = floor(st); vec2 f_st = fract(st); float m_dist = 1.; // minimum distance for (int y= -1; y <= 1; y++) { for (int x= -1; x <= 1; x++) { // Neighbor place in the grid vec2 neighbor = vec2(float(x),float(y)); // Random position from current + neighbor place in the grid vec2 point = random2(i_st + neighbor); // Animate the point point = 0.5 + 0.5*sin(u_time + 6.2831*point); // Vector between the pixel and the point vec2 diff = neighbor + point - f_st; // Distance to the point float dist = length(diff); // Keep the closer distance m_dist = min(m_dist, dist); } } // Draw the min distance (distance field) bg_color += m_dist; // Show isolines bg_color -= step(.7,abs(sin(27.0*m_dist)))*.5; //Colors vec3 yellow = vec3(0.4824, 0.3569, 0.1412); vec3 darkblue = vec3(0.0078, 0.1569, 0.3176)*bg_color; vec3 lightblue = vec3(0.2353, 0.4039, 0.7765); //Color application to masks float t = step(0.05, cnoise(4.0*uv+uv.xy)); float t_1 = t_1(uv); float d_1 = 0.; vec3 Antenna_color_1 = mask_1 > 0.0 ? lightblue*-uv.y/10. : mix(yellow, darkblue,smoothstep( 1.,3.4,length(center - uv.xy)) ); vec3 body_color_2 = max(-mask_1,mask_2) > 0.0 ? vec3(0) : mix(darkblue, yellow-0. ,t+t_1+.9+0.3*sin(u_time)); vec3 Antenna_back_color_3 = max(-mask_2,mask_3) >0.0? vec3(0) : darkblue; //White Border color = mix(vec3(0.9608, 0.9294, 0.9294),Antenna_color_1 + body_color_2 +Antenna_back_color_3, step(0.09, abs(sdDifference(sdDifference(mask_1,mask_2),sdUnion(mask_2,mask_1))))); color += mix(vec3(0.9608, 0.9294, 0.9294),vec3(0), step(0.09, abs(sdDifference(sdUnion(mask_1,mask_2),sdUnion(mask_2,mask_3))))); colour_out = vec4(color,1.0); }
Fellimara picta Victor Micallef by
Eibaloch