Selected Student Works
This is a small selection of student works from the 2024 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.
uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; float sdWings(in vec2 p, in float he, in float ra, in float rb, in float angle) { mat2 rotation_matrix = mat2(cos(angle), -sin(angle), sin(angle), cos(angle)); p = rotation_matrix * p; float ce = 0.5 * (he * he - (ra - rb) * (ra - rb)) / (ra - rb); p.x = abs(p.x); if (p.y < 0.0) return length(p) - ra; if (p.y * ce - p.x * he > he * ce) return length(vec2(p.x, p.y - he)) - rb; return length(vec2(p.x + ce, p.y)) - (ce + ra); } float sdCircle(vec2 p, float r){ return length(p) - r; } float smin( float a, float b, float k ) { float h = max( k-abs(a-b), 0.0 )/k; return min( a, b ) - h*h*k*(1.0/4.0); } float sdLine(vec2 p, vec2 a, vec2 b, float thickness) { vec2 pa = p - a; vec2 ba = b - a; float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0); return length(pa - ba * h) - thickness; } float random(vec2 co) { const highp float seed = 12.9898; highp float a = seed; highp float b = 78.233, c = 43758.5453; float dt = dot(co.xy, vec2(a, b)); float sn = mod(dt, 3.14159265358979323846); return fract(sin(sn) * c); } vec3 permute(vec3 x) { return mod(((x * 34.0) + 1.0) * x, 289.0); } float snoise(vec2 v) { const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439); // First corner vec2 i = floor(v + dot(v, C.yy)); vec2 x0 = v - i + dot(i, C.xx); // Other corners vec2 i1; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); vec2 x1 = x0 - i1 + C.xx; vec2 x2 = x0 - 1.0 + C.yy; // Permutations i = mod(i, 289.0); 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(x1, x1), dot(x2, x2)), 0.0); m = m * m; m = m * m; // Gradients: 41 points uniformly over a unit circle, mapped onto [-1,1] 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 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.y = a0.y * x1.x + h.y * x1.y; g.z = a0.z * x2.x + h.z * x2.y; return 130.0 * dot(m, g); } float fbm_example( 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 += snoise( p * scale ) / scale; } return f; } void main() { vec2 st = gl_FragCoord.xy / u_resolution.xy; vec3 baseBgColor = vec3(0.08,0.68,0.12); float n = fbm_example( gl_FragCoord.xy / 400.0 + u_time*0.02); vec3 noiseColor = vec3(n); vec4 bgColor = vec4(mix(baseBgColor, noiseColor, 0.2), 0.7); vec2 center = vec2(0.5, 0.6); float distToCenter = length(st - center); float gradient = smoothstep(0.0, 0.6, distToCenter); // Wings' color float noise = random(st) * 4.0; vec3 wingColor = mix(vec3(0.02,0.21,0.53), vec3(0.40,0.74,0.93), gradient); wingColor += vec3(noise) * 0.1; // Wings float wing1 = sdWings(st.xy + vec2(-0.78, -0.57), 0.27, 0.15, 0.03, 1.65); float wing1_adjust = sdCircle(st.xy+vec2(-0.855, -0.635), 0.08); wing1 = smin(wing1, wing1_adjust, 0.05); float wing2 = sdWings(st.xy + vec2(-0.22, -0.57), 0.27, 0.15, 0.03, -1.65); float wing2_adjust = sdCircle(st.xy+vec2(-0.145, -0.635), 0.08); wing2 = smin(wing2, wing2_adjust, 0.05); float wing3 = sdWings(st.xy + vec2(-0.65, -0.3), 0.2, 0.12, 0.02, 0.5); float wing4 = sdWings(st.xy + vec2(-0.35, -0.3), 0.2, 0.12, 0.02, -0.5); float wingMask = step(0.0, wing1) * step(0.0, wing2) * step(0.0, wing3) * step(0.0, wing4); // Body float body = sdWings(st.xy + vec2(-0.5, -0.6), 0.35, 0.05, 0.015, 3.14); float bodyMask = step(0.0, -body); // Body's color float distToCenterBody = length(st - center); float gradientBody = smoothstep(0.0, 0.5, distToCenterBody); float bodyNoise = random(st) * 0.4; vec3 bodyBaseColor = mix(vec3(0.192, 0.526, 0.715),vec3(1.0), gradientBody); vec3 bodyColor = bodyBaseColor - bodyNoise; // Antennas float antenna1 = sdLine(st, vec2(0.5 - 0.015, 0.65), vec2(0.5 - 0.17, 0.77), .0); float antenna2 = sdLine(st, vec2(0.5 + 0.015, 0.65), vec2(0.5 + 0.17, 0.77), .0); float antennaMask = smoothstep(0.01, 0.0, antenna1) + smoothstep(0.01, 0.0, antenna2); // Antennas' color float tex = step( sin( gl_FragCoord.x), sin( gl_FragCoord.y) ); vec3 antennaColor = vec3(tex); // Wings' edge (White) float edgeThickness = distance(center + vec2(0.0, 0.1), st) * 0.08; float edgeMask = 1.0 - smoothstep(-edgeThickness, 0.0, min(wing1, min(wing2, min(wing3, wing4)))); vec3 edgeColor = vec3(0.90,1.000,1.000); // Wings' edge (Black) float edgeThicknessBlack = distance(center + vec2(0.0, 0.1), st) * 0.04; float edgeMaskBlack = 1.0 - smoothstep(-edgeThicknessBlack, 0.000, min(wing1, min(wing2, min(wing3, wing4)))); vec3 edgeColorBlack = vec3(0.0); // Synthesize colors vec3 color = mix(edgeColor, edgeColorBlack, edgeMaskBlack); color = mix(color, wingColor, edgeMask); color = mix(color, bgColor.rgb, wingMask); color = mix(color, bodyColor, bodyMask); color = mix(color, antennaColor, antennaMask); colour_out = vec4(color, 1.0); }
Adonis Blue by Masy
uniform vec2 u_resolution; uniform float u_time; // Simplex 3D Noise // by Ian McEwan, Ashima Arts vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);} 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 * C vec3 x1 = x0 - i1 + 1.0 * C.xxx; vec3 x2 = x0 - i2 + 2.0 * C.xxx; vec3 x3 = x0 - 1. + 3.0 * C.xxx; // Permutations i = mod(i, 289.0 ); 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 // ( N*N points uniformly over a square, mapped onto an octahedron.) float n_ = 1.0/7.0; // N=7 vec3 ns = n_ * D.wyz - D.xzx; vec4 j = p - 49.0 * floor(p * ns.z *ns.z); // mod(p,N*N) 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.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); m = m * m; return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) ); } float random(vec2 st) { return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453123); } float butterflyShape(vec2 st) { float shape = 1.0; shape *= step(0.210, distance(st, vec2(0.280, 0.670))); // Upper left wing shape *= step(0.154, distance(st, vec2(0.170, 0.490))); // Lower left wing shape *= step(0.210, distance(st, vec2(0.710, 0.440))); // Upper right wing shape *= step(0.154, distance(st, vec2(0.550, 0.280))); // Lower right wing return 1.0 - shape; // Invert so 1 is inside the butterfly } float sdSegment(vec2 p, vec2 a, 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); } bool isBlackPart(vec2 st) { return distance(st, vec2(0.610, 0.720)) < 0.084 || // Head distance(st, vec2(0.560, 0.610)) < 0.106 || // Neck distance(st, vec2(0.480, 0.490)) < 0.138 || // Second neck distance(st, vec2(0.330, 0.330)) < 0.186; // Under body } float leafShape(vec2 st, vec2 center, float size, float angle) { st -= center; st = mat2(cos(angle), -sin(angle), sin(angle), cos(angle)) * st; st /= size; float d = length(max(abs(st) - vec2(0.3, 0.8), 0.0)) - 0.1; return smoothstep(0.01, 0.0, d); } void main() { vec2 st = gl_FragCoord.xy / u_resolution.xy; vec4 bgColor = vec4(0.2, 0.6, 0.1, 1.0); // Green background vec4 wingColor = vec4(1.0, 0.5, 0.0, 1.0); vec4 edgeColor = vec4(0.0, 0.0, 0.0, 1.0); vec4 whiteSpotColor = vec4(1.0); vec4 leafColor = vec4(0.1, 0.4, 0.05, 0.7); // Start with the green background colour_out = bgColor; // Add animated leaves for (int i = 0; i < 5; i++) { float t = u_time * 0.2 + float(i) * 1.5; vec2 leafPos = vec2( mod(sin(t * 0.7) * 0.5 + t * 0.1, 1.5) - 0.25, mod(cos(t * 0.6) * 0.5 + t * 0.15, 1.2) - 0.1 ); float leafAngle = sin(t * 2.0) * 0.5; float leaf = leafShape(st, leafPos, 0.15, leafAngle); // Add simple lighting effect to leaves float light = max(0.5, sin(u_time + leafPos.x * 10.0) * 0.5 + 0.5); vec4 litLeafColor = leafColor * light; colour_out = mix(colour_out, litLeafColor, leaf * 0.7); } float shape = butterflyShape(st); // Add noise to the wing color float noiseValue = snoise(vec3(st * 10.0, u_time * 0.1)); vec4 noisyWingColor = mix(wingColor, vec4(1.0, 0.7, 0.2, 1.0), noiseValue * 0.5); // Butterfly color with noise colour_out = mix(colour_out, noisyWingColor, shape); // Add black edges with noise if (shape > 0.0 && shape < 0.1) { float edgeNoise = snoise(vec3(st * 20.0, u_time * 0.2)); colour_out = mix(edgeColor, noisyWingColor, edgeNoise * 0.3); } // Make head, neck, second neck, and under body black if (isBlackPart(st)) { colour_out = edgeColor; } // Add fixed lines crossing the butterfly if (shape > 0.0) { for (int i = 0; i < 10; i++) { float angle = random(vec2(float(i), 0.0)) * 6.28318530718; vec2 direction = vec2(cos(angle), sin(angle)); vec2 lineStart = vec2(random(vec2(float(i), 1.0)), random(vec2(float(i), 2.0))); vec2 lineEnd = lineStart + direction * 2.0; float lineDistance = sdSegment(st, lineStart, lineEnd); if (lineDistance < 0.012) { colour_out = mix(colour_out, edgeColor, 0.8); } } } // Add white dots separately if (shape > 0.0) { for (int i = 0; i < 90; i++) { vec2 dotPosition = vec2( random(vec2(float(i), 3.0)), random(vec2(float(i), 4.0)) ); if (butterflyShape(dotPosition) > 0.0 && distance(st, dotPosition) < 0.015 && !isBlackPart(dotPosition)) { colour_out = mix(colour_out, whiteSpotColor, 0.7); } } } // Add white spots along the edges with noise if (shape > 0.0 && shape < 0.1) { float edgeSpot = step(0.99, sin(st.x * 50.0) * sin(st.y * 50.0)); float spotNoise = snoise(vec3(st * 60.0, u_time * 0.5)); colour_out = mix(colour_out, whiteSpotColor, edgeSpot * (1.0 - spotNoise * 0.4)); } }
Monarch Butterfly by バタフリー
uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; // Cellular noise ("Worley noise") in 2D in GLSL. // Copyright (c) Stefan Gustavson 2011-04-19. All rights reserved. // This code is released under the conditions of the MIT license. // See LICENSE file for details. // https://github.com/stegu/webgl-noise // Modulo 289 without a division (only multiplications) 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; } // Modulo 7 without a division vec3 mod7(vec3 x) { return x - floor(x * (1.0 / 7.0)) * 7.0; } // Permutation polynomial: (34x^2 + 10x) mod 289 vec3 permute(vec3 x) { return mod289((34.0 * x + 10.0) * x); } // Cellular noise, returning F1 and F2 in a vec2. // Standard 3x3 search window for good F1 and F2 values 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); } // Generate Pattern float generatePattern(vec2 uv, float mouse) { // Adjust the scale to change the pattern density vec2 scaled_st = uv * 4.0; // Slightly move the pattern based on the mouse position scaled_st += mouse * 0.01; // Apply cellular noise vec2 f = cellular(scaled_st); float n = f.x; n = f.y - f.x; // Make the pattern more distinct n = smoothstep(0.0, 0.5, n); return n; } float smoothUnion(float d1, float d2, float k) { float h = clamp(0.5 + 0.5 * (d2 - d1) / k, 0.0, 1.0); return mix(d2, d1, h) - k * h * (1.0 - h); } float dot2(vec2 v) { return dot(v, v); } float sdTriangle(in vec2 p, in vec2 p0, in vec2 p1, in vec2 p2, in float r) { 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) - r; } float sdCircle( vec2 p, float r ) { return length(p) - r; } 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 ); } vec4 sdButterFlyWing(vec2 p) { // Adjust scale and position (right-aligned) p = p * 3.188 - vec2(0.700,0.000); // Scale down by 1.5 and shift 0.3 to the right // Rotate the wing float angle = sin(u_time * 1.0) * 0.15; // Angle of rotation mat2 rotation = mat2( cos(angle), -sin(angle), sin(angle), cos(angle)); p = rotation * p; // Shift position to the left before scaling p -= vec2(-0.5, 0.0); // Adjust this value as needed // Scale the wing horizontally float scale = sin(u_time * 1.0) * 0.2 + 1.2; p.x *= scale; // Shift position back after scaling p += vec2(-0.5, 0.0); // Adjust this value as needed // Upper wing part (rounded triangle) float upperWing = sdTriangle( p, vec2(-0.620,0.020), vec2(0.570,0.190), vec2(0.310,0.730), 0.25 ); // Lower wing part (rounded triangle) float lowerWing = sdTriangle( p, vec2(-0.620,0.020), vec2(0.280,-0.220), vec2(0.060,-0.710), 0.25 ); vec3 wingColor = vec3(0.125,0.125,0.075); // Dark yellow color vec3 patternColor = vec3(1.0, 1.0, 0.8); // Light yellow color // Visibility check and color calculation for each wing vec3 col = vec3(0.0); float alpha = 0.0; if (upperWing < 0.0) { col = mix(wingColor, patternColor, generatePattern(p, length(u_mouse)) * 0.8); alpha = 1.0; } if (lowerWing < 0.0) { // Ensure the lower wing is below the upper wing if (upperWing > 0.0) { col = mix(wingColor, patternColor, generatePattern(p, length(u_mouse)) * 0.8); alpha = 1.0; } } return vec4(col, alpha); } vec4 sdButterFlyBody(vec2 p) { // Body part (circle) float body = sdSegment(p, vec2(0.0, -0.2), vec2(0.0, 0.1)) - 0.05; float eyes = min(sdCircle(p - vec2(0.05,0.1), 0.03), sdCircle(p - vec2(-0.05,0.1), 0.03)); vec3 bodyColor = vec3(0.480,0.480,0.480); // Gray color vec3 eyeColor = vec3(0.0, 0.0, 0.0); // Black color vec3 col = vec3(0.0); float alpha = 0.0; if (body < 0.0) { col = bodyColor; alpha = 1.0; } if (eyes < 0.0) { col = eyeColor; alpha = 1.0; } return vec4(col, alpha); } void main() { vec2 uv = (gl_FragCoord.xy - 0.5 * u_resolution.xy) / min(u_resolution.x, u_resolution.y); // Draw the right wing vec4 rightWing = sdButterFlyWing(uv); // Draw the left wing (invert x-coordinate) vec4 leftWing = sdButterFlyWing(vec2(-uv.x, uv.y)); // Draw the body vec4 body = sdButterFlyBody(uv); // Background color (soft green) vec3 topColor = vec3(0.629,0.850,0.424); vec3 bottomColor = vec3(0.400,0.545,0.245); vec3 backgroundColor = mix(bottomColor, topColor, uv.y); // Combine both wings vec3 color = mix(backgroundColor, rightWing.rgb, rightWing.a); color = mix(color, leftWing.rgb, leftWing.a); color = mix(color, body.rgb, body.a); colour_out = vec4(color, 1.0); }
Papilio machaon by cherr0406
uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; #define PI 3.1415926 // Cellular Noise:from https://thebookofshaders.com/edit.php#12/cell.frag // Permutation function for cellular noise vec4 permute(vec4 x) { return mod((33.944 * x + 1.0) * x, 289.0); } // Cellular noise function vec2 cellular2x2(vec2 P) { #define K 0.142857142857 // 1/7 #define K2 0.0714285714285 // K/2 #define jitter 0.8 // Adjust jitter for noise pattern vec2 Pi = mod(floor(P), 289.0); 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 = mod(p, 7.0) * K + K2; vec4 oy = mod(floor(p * K), 7.0) * K + K2; vec4 dx = Pfx + jitter * ox; vec4 dy = Pfy + jitter * oy; vec4 d = dx * dx + dy * dy; // Find F1 and F2 distances d.xy = (d.x < d.y) ? d.xy : d.yx; 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); } // Generate cellular noise pattern float cellularNoise(vec2 st) { if (u_resolution.y > u_resolution.x) { st.y *= u_resolution.y / u_resolution.x; st.y -= (u_resolution.y * 0.5 - u_resolution.x * 0.5) / u_resolution.x; } else { st.x *= u_resolution.x / u_resolution.y; st.x -= (u_resolution.x * 0.5 - u_resolution.y * 0.5) / u_resolution.y; } st -= 0.484; st *= 0.788; vec2 F = cellular2x2(st * 30.144 * (-0.228 + 1.488 - dot(st, st) * 6.784)); float facets = -0.460 + (F.y - F.x); float dots = smoothstep(-2.502, 0.468, F.x); float n = facets * dots; n = step(-0.160, facets) * dots; return n; } // Wing color: // Calculate gradient color vec3 gradientColor(float d, float r, vec3 colorStart, vec3 colorEnd, float scale, float weight) { float adjustedD = pow(abs(r), weight); float gradientFactor = smoothstep(0.216, 0.392, 0.412 - 0.5 * abs(d) / adjustedD) * scale; return mix(colorStart, colorEnd, gradientFactor); } // Weight adjustment for cellular noise float cellularNoiseAlpha(float r) { float alpha = 1.75 - smoothstep(0.0, 0.5, r); return alpha; } // Wing shape: // Distance function for vesica piscis segment float sdVesicaSegment(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; } // Distance function for hyperbola float sdHyberbola(in vec2 p, in float k, in float he) { p = abs(p); p = vec2(p.x - p.y, p.x + p.y) / sqrt(2.0); float x2 = p.x * p.x / 16.0; float y2 = p.y * p.y / 16.0; float r = k * (4.0 * k - p.x * p.y) / 12.0; float q = (x2 - y2) * k * k; float h = q * q + r * r * r; float u; if (h < 0.0) { float m = sqrt(-r); u = m * cos(acos(q / (r * m)) / 3.0); } else { float m = pow(sqrt(h) - q, 1.0 / 3.0); u = (m - r / m) / 2.0; } float w = sqrt(u + x2); float b = k * p.y - x2 * p.x * 2.0; float t = p.x / 4.0 - w + sqrt(2.0 * x2 - u + b / w / 4.0); t = max(t, sqrt(he * he * 0.5 + k) - he / sqrt(2.0)); float d = length(p - vec2(t, k / t)); return p.x * p.y < k ? d : -d; } // Body: // Distance function for curved line float curvedLine(vec2 uv, vec2 start, vec2 end, float angle, float curvature, float thickness) { float t = uv.y - start.y; float x = start.x + t * tan(angle) + curvature * t * t; float dist = abs(uv.x - x); if (uv.y < start.y || uv.y > end.y) { return 0.0; } return smoothstep(thickness, 0.0, dist); } void main() { // Normalize screen coordinates vec2 st = gl_FragCoord.xy / u_resolution.xy; vec2 p = st * 2.0 - 1.0; // Map to range [-1, 1] float r = length(p); // Distance from center float ar = u_resolution.y / u_resolution.x; // Aspect ratio vec3 c = vec3(1.0); // Default color (white) // Noise generation float n = cellularNoise(st); float alpha = cellularNoiseAlpha(r); n = 0.388*n+0.7*alpha; // Gradient colors for up wings vec3 colorStart = vec3( st.x * 0.1 + 0.8 * abs(sin(1.0 * u_time)), // Red channel st.y * 0.1 + 0.8 * abs(cos(1.0 * u_time)), // Green channel 0.8 + 1.5 * abs(sin(1.0 * u_time)) // Blue channel: more value ); vec3 colorEnd = vec3(0.025, 0.025, 0.023); // Dark // Vesica segment parameters for wings vec2 v1[4] = vec2[]( vec2(-0.890, 0.580), vec2(0.890, 0.580), vec2(-0.7, -0.7), vec2(0.7, -0.7)); vec2 v2[4] = vec2[]( vec2(-0.1, -0.1), vec2(0.1, -0.1), vec2(0, -0.1), vec2(0, -0.1)); float th[4] = float[](0.312, 0.312, 0.28, 0.28); float ra[4] = float[](0.0795, 0.0795, 0.075, 0.075); // Down wings float dd = 1e10; float di; for (int i = 2; i < 4; i++) { di = sdVesicaSegment(p, v1[i], v2[i], th[i]) - ra[i]; dd = min(dd, di); } // Down wings edge noise float a = atan(p.x, p.y); float adjD = -0.072 + -0.012 * sin(43.448 * a); float e = -30.664 * abs(abs(a) - ((4.176 * PI) + 5.464 * r) / 6.760); float tailhook = 0.252 * exp(e); adjD += tailhook; vec3 colorD = gradientColor(dd, r, colorStart, colorEnd, 1.2, 0.5) * n; c = step(-adjD, -dd) == 0.0 ? c : colorD; // Up wings float du = 1e10; for (int i = 0; i < 2; i++) { di = sdVesicaSegment(p, v1[i], v2[i], th[i]) - ra[i]; du = min(du, di); } // Up wings edge noise float adju = 0.000 + -0.010 * sin(25.288 * a); vec3 colorU = gradientColor(du, r, colorStart, colorEnd, 1.000, 0.944) * n; c = step(adju, -du) == 0.0 ? c : colorU; // Body vec2 bV1 = vec2(0.005, -0.500); vec2 bV2 = vec2(0.005, 0.450); float bTh = 0.072; float bRa = -0.004; float d = sdVesicaSegment(p, bV1, bV2, bTh) - bRa; vec3 colorB = vec3(0.0); c = step(0.0, -d) == 0.0 ? c : colorB; // Head if (distance(p.xy, vec2(0.005, 0.360)) < 0.082) { c = vec3(0.0); } // Tentacles: two curved line vec2 start = vec2(0.005, 0.35); // Starting point float angle = 0.124; // Initial angle in radians float curvature = 1.900; // Curvature float thickness = 0.015; // Thickness vec2 endr = vec2(0.410, 0.780); float rightline = curvedLine(p, start, endr, angle, curvature, thickness); vec2 endl = vec2(-0.410, 0.780); float leftCurve = curvedLine(p, start, endl, -angle, -curvature, thickness); // Symmetrical curve c = step(0.0, -rightline) == 0.0 ? vec3(0.0) : c; c = step(0.0, -leftCurve) == 0.0 ? vec3(0.0) : c; // Final color output colour_out = vec4(c, 1.0); }
Ulysses butterfly by fangluxie
uniform vec2 u_resolution; uniform float u_time; //---- SDFS ------- // The MIT License // Copyright © 2023 Inigo Quilez // Permission is hereby granted, free of charge, to any person obtaining a copy of this float sdTriangle( in vec2 p, in vec2 p0, in vec2 p1, in vec2 p2 ) // Wings { 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 sdOrientedVesica( vec2 p, vec2 a, vec2 b, float w ) //Butt thingy { 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 dot2( vec2 v ) { return dot(v,v); } float sdBezier( in vec2 pos, in vec2 A, in vec2 B, in vec2 C ) { vec2 a = B - A; vec2 b = A - 2.0*B + C; vec2 c = a * 2.0; vec2 d = A - pos; float kk = 1.0/dot(b,b); float kx = kk * dot(a,b); float ky = kk * (2.0*dot(a,a)+dot(d,b)) / 3.0; float kz = kk * dot(d,a); float res = 0.0; float p = ky - kx*kx; float p3 = p*p*p; float q = kx*(2.0*kx*kx-3.0*ky) + kz; float h = q*q + 4.0*p3; if( h >= 0.0) { h = sqrt(h); vec2 x = (vec2(h,-h)-q)/2.0; vec2 uv = sign(x)*pow(abs(x), vec2(1.0/3.0)); float t = clamp( uv.x+uv.y-kx, 0.0, 1.0 ); res = dot2(d + (c + b*t)*t); } else { float z = sqrt(-p); float v = acos( q/(p*z*2.0) ) / 3.0; float m = cos(v); float n = sin(v)*1.732050808; vec3 t = clamp(vec3(m+m,-n-m,n-m)*z-kx,0.0,1.0); res = min( dot2(d+(c+b*t.x)*t.x), dot2(d+(c+b*t.y)*t.y) ); // the third root cannot be the closest // res = min(res,dot2(d+(c+b*t.z)*t.z)); } return sqrt( res ); } //---- NOISE ------ // Cellular noise ("Worley noise") in 2D in GLSL. // Copyright (c) Stefan Gustavson 2011-04-19. All rights reserved. // This code is released under the conditions of the MIT license. // See LICENSE file for details. // https://github.com/stegu/webgl-noise // Modulo 289 without a division (only multiplications) 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; } // Modulo 7 without a division vec3 mod7(vec3 x) { return x - floor(x * (1.0 / 7.0)) * 7.0; } // Permutation polynomial: (34x^2 + 6x) mod 289 vec3 permute(vec3 x) { return mod289((34.0 * x + 10.0) * x); } // Cellular noise, returning F1 and F2 in a vec2. // Standard 3x3 search window for good F1 and F2 values 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); } // // 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 // 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); } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec2 p = (st - 0.5) * 2.0; //Wing geometry float tri1= sdTriangle(p, vec2(-0.3, 0.0), vec2(0.7,0.6), vec2(0.6,0.0)); float tri2= sdTriangle(p, vec2(-0.3, 0.0), vec2(0.5,-0.3), vec2(0.4, -0.2)); float tri3= sdTriangle(p, vec2(-0.3, 0.1), vec2(0.2, 0.5), vec2(0.4, 0.6)); float tri4 = sdOrientedVesica(p, vec2(-0.3,0.1), vec2(0.3, -0.3) ,0.000001 ); float d = min(min(min(tri1, tri2), tri3), tri4) - 0.25; //Body geometry float body = sdOrientedVesica(p, vec2(-0.55,-0.2), vec2(-0.65, 0.1) ,0.1 ) - 0.08; float head = sdOrientedVesica(p, vec2(-0.8,0.05), vec2(-0.8,0.3) ,0.1 ); float butt= sdOrientedVesica(p, vec2(-0.45,-0.2), vec2(-0.2, -0.7) ,0.1 )- 0.04; float b = min(min(body, butt),head); float outline = min(b, d) - 0.01; //Details float eye = sdOrientedVesica(p, vec2(-0.8,0.15), vec2(-0.8, 0.25) , 0.05); float mouth = sdBezier(p, vec2(-0.9,0.1), vec2(-0.98,0.14) , vec2(-0.9,0.2)) - 0.01; float antenna1 = sdBezier(p, vec2(-0.73,0.25), vec2(-0.35, 0.8) , vec2(-0.2,0.6)) - 0.01; float antenna2 = sdBezier(p, vec2(-0.73,0.25), vec2(-0.45, 0.9) , vec2(-0.25,0.7)) - 0.01; float wingDeets1 = sdBezier(p, vec2(0.55,0.81), vec2(0.3,0.85) , vec2(-0.55, 0.15)); float wingDeets2= sdBezier(p, vec2(0.4,-0.54), vec2(0.0,0.0) , vec2(-0.55, 0.15)); float wingDeets3= sdBezier(p, vec2(0.75,-0.2), vec2(0.2,0.3) , vec2(-0.55, 0.15)); float wingDeets4= sdBezier(p, vec2(0.9,0.3), vec2(0.2,0.6) , vec2(-0.55, 0.15)); float wingDeets5 = sdOrientedVesica(p, vec2(0.8,0.65), vec2(0.45, 0.55) , 0.1); float wingDeets6 = sdOrientedVesica(p, vec2(0.8,0.1), vec2(0.45, 0.23) , 0.1); float wingDeets7 = sdOrientedVesica(p, vec2(0.6, -0.4), vec2(0.36, -0.12) , 0.1); float deets567 = min(min(wingDeets5,wingDeets6), wingDeets7); float black1 = sdOrientedVesica(p, vec2(0.8,0.65), vec2(0.5, 0.55) , 0.1) - 0.05; float black2 = sdOrientedVesica(p, vec2(0.8,0.1), vec2(0.5, 0.2) , 0.1) - 0.05; float black3 = sdOrientedVesica(p, vec2(0.6, -0.4), vec2(0.4, -0.15) , 0.1) - 0.05; float blacks = min(min(black1, black2), black3); float black4 = sdOrientedVesica(p, vec2(0.65, 0.6), vec2(0.5, 0.55) , 0.05); float black5 = sdOrientedVesica(p, vec2(0.65, 0.15), vec2(0.5, 0.2) , 0.05)- 0.005; float black6 = sdOrientedVesica(p, vec2(0.5, -0.28), vec2(0.4, -0.18) , 0.05); float pupils = min(min(black4, black5), black6); float wingLines = min(min(min(wingDeets1, wingDeets2),wingDeets3),wingDeets4) -0.007; float wingShapes = min(deets567, blacks); float details = min(min(min(min(min( antenna1, mouth), antenna2), eye), wingLines), wingShapes); //Colours vec2 origin = vec2(0.3, 0.5); vec3 color1 = vec3(0.05, 0.0, 0.0); vec2 wingNoise = cellular(vec2(st.x * 15.0 + u_time * 0.7,st.y* 15.0)); vec3 wingColor = vec3(wingNoise.x*0.9, wingNoise.x*0.8275, wingNoise.x*0.604); vec2 bodyNoise = cellular(st*11.0); vec3 bodyColor = vec3(bodyNoise.x*0.9, bodyNoise.x*0.8275, bodyNoise.x*0.604); vec2 Noise = cellular(vec2(st.x * 5.0 + u_time* -0.7, st.y*5.0)); float simplexNoise = 1.0 - snoise(st * 100.0 + u_time * 0.9); //invert colours bc i want more blue vec3 simplexColor = vec3(simplexNoise*0.27, simplexNoise*0.4, simplexNoise*0.5); vec3 simplexColor2 = vec3(simplexNoise*0.5, simplexNoise*0.3, simplexNoise*0.0); if (details < 0.0) { if(pupils < 0.0) { colour_out = vec4(simplexColor2*0.6,0.5); } else if(deets567 < 0.0) { colour_out = vec4(simplexColor, 1.0); } else if(wingLines < 0.0) { colour_out = vec4(0.1,0.1,0.1,1.0); } else { colour_out = vec4(wingColor * 0.25,1.0); } } else if (b < 0.0) { colour_out = vec4(bodyColor,1.0); } else if (d < 0.0){ float distanceFromCenter = length(st - origin) * 3.0; float factor = exp(-distanceFromCenter); colour_out = vec4(mix(wingColor, color1, factor), 1.0); //Make wing fade from dark to worley noise } else if(outline < 0.0) { colour_out = vec4(wingColor * 0.6,1.0); } else { colour_out = vec4(vec3(Noise.y * 0.2, Noise.y * 0.6, Noise.y*0.2), 0.9); } }
Lime Butterfly by Gayathri Naranath
uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; // Helper functions // Triangle function float triangle(vec2 st, vec2 p0, vec2 p1, vec2 p2) { vec2 v0 = p1 - p0; vec2 v1 = p2 - p0; vec2 v2 = st - p0; float d00 = dot(v0, v0); float d01 = dot(v0, v1); float d11 = dot(v1, v1); float d20 = dot(v2, v0); float d21 = dot(v2, v1); float denom = d00 * d11 - d01 * d01; float v = (d11 * d20 - d01 * d21) / denom; float w = (d00 * d21 - d01 * d20) / denom; float u = 1.0 - v - w; return step(0.0, min(min(u, v), w)); } // line with shader effect vec4 drawLineWithShader(vec2 st, vec2 p0, vec2 p1, float thickness) { float dist = abs(cross(vec3(p1 - p0, 0.0), vec3(st - p0, 0.0)).z) / length(p1 - p0); float segment = step(0.0, dot(st - p0, p1 - p0)) * step(0.0, dot(st - p1, p0 - p1)); //shader effect //normalize float t = length(st - p0) / length(p1 - p0); float wave = 0.5 + 0.5 * sin(u_time + t * 10.0); vec3 gradientColor = mix(vec3(0.006,0.013,0.020), vec3(1.000,0.996,0.986), wave); return (dist < thickness && segment > 0.0) ? vec4(gradientColor, 1.0) : vec4(0.0, 0.0, 0.0, 0.0); } // Noise functions for the wings float rand(vec2 n) { return fract(sin(dot(n, vec2(12.9898, 4.1414))) * 43758.5453); } float noise(vec2 p) { vec2 ip = floor(p); vec2 u = fract(p); u = u * u * (3.0 - 2.0 * u); float res = mix( mix(rand(ip), rand(ip + vec2(1.0, 0.0)), u.x), mix(rand(ip + vec2(0.0, 1.0)), rand(ip + vec2(1.0, 1.0)), u.x), u.y); return res * res; } const mat2 mtx = mat2(0.80, 0.60, -0.60, 0.80); float fbm(vec2 p) { float f = 0.0; f += 0.500000 * noise(p + u_time); p = mtx * p * 2.02; f += 0.250000 * noise(p); p = mtx * p * 2.03; f += 0.125000 * noise(p); p = mtx * p * 2.01; f += 0.062500 * noise(p); return f / 0.9375; } float pattern(vec2 p) { return fbm(p + fbm(p + fbm(p))); } // Wing shader 1 vec4 wingShader1(vec2 st) { float shade = pattern(st * 15.0); vec3 color = mix(vec3(0.1, 0.2, 0.8), vec3(1.0,1.0,1.0), shade); // Gradient between two blue shades return vec4(color, 1.0); } // Wing shader 2 (slightly varied) vec4 wingShader2(vec2 st) { float shade = pattern(st * 10.0 + vec2(sin(u_time), cos(u_time))); vec3 color = mix(vec3(0.0, 0.3, 0.7), vec3(1.0, 1.0, 1.0), shade); // Different blue gradient return vec4(color, 1.0); } // Main void main() { vec2 st = gl_FragCoord.xy / u_resolution.xy; float mask1 = 1.0; float mask2 = 1.0; float mask3 = 1.0; float mask4 = 1.0; // Drawing the body mask3 *= 1.0 - triangle(st, vec2(0.5, 0.65), vec2(0.45, 0.5), vec2(0.55, 0.5)); mask3 *= 1.0 - triangle(st, vec2(0.5, 0.2), vec2(0.45, 0.5), vec2(0.55, 0.5)); //Antennas mask4 *= 1.0 - triangle(st, vec2(0.45, 0.85), vec2(0.4, 0.9), vec2(0.45, 0.7)); mask4 *= 1.0 - triangle(st, vec2(0.55, 0.85), vec2(0.6, 0.9), vec2(0.55, 0.7)); //wings left upper mask1 *= 1.0 - triangle(st, vec2(0.5, 0.6), vec2(0.2, 0.5), vec2(0.5, 0.5)); mask2 *= 1.0 - triangle(st, vec2(0.3, 0.8), vec2(0.2, 0.5), vec2(0.5, 0.6)); mask1 *= 1.0 - triangle(st, vec2(0.3, 0.8), vec2(0.1, 0.6), vec2(0.2, 0.5)); mask2 *= 1.0 - triangle(st, vec2(0.3, 0.8), vec2(0.1, 0.7), vec2(0.1, 0.6)); mask1 *= 1.0 - triangle(st, vec2(0.3, 0.8), vec2(0.05, 0.8), vec2(0.1, 0.7)); //wings left lower mask2 *= 1.0 - triangle(st, vec2(0.5, 0.5), vec2(0.3, 0.5), vec2(0.5, 0.3)); mask1 *= 1.0 - triangle(st, vec2(0.3, 0.5), vec2(0.2, 0.4), vec2(0.5, 0.3)); mask2 *= 1.0 - triangle(st, vec2(0.2, 0.4), vec2(0.25, 0.1), vec2(0.5, 0.3)); mask1 *= 1.0 - triangle(st, vec2(0.5, 0.3), vec2(0.25, 0.1), vec2(0.4, 0.1)); // Wings right upper mask1 *= 1.0 - triangle(st, vec2(0.5, 0.6), vec2(0.8, 0.5), vec2(0.5, 0.5)); mask2 *= 1.0 - triangle(st, vec2(0.7, 0.8), vec2(0.8, 0.5), vec2(0.5, 0.6)); mask1 *= 1.0 - triangle(st, vec2(0.7, 0.8), vec2(0.9, 0.6), vec2(0.8, 0.5)); mask2 *= 1.0 - triangle(st, vec2(0.7, 0.8), vec2(0.9, 0.7), vec2(0.9, 0.6)); mask1 *= 1.0 - triangle(st, vec2(0.7, 0.8), vec2(0.95, 0.8), vec2(0.9, 0.7)); // Wings right lower mask2 *= 1.0 - triangle(st, vec2(0.5, 0.5), vec2(0.7, 0.5), vec2(0.5, 0.3)); mask1 *= 1.0 - triangle(st, vec2(0.7, 0.5), vec2(0.8, 0.4), vec2(0.5, 0.3)); mask2 *= 1.0 - triangle(st, vec2(0.8, 0.4), vec2(0.75, 0.1), vec2(0.5, 0.3)); mask1 *= 1.0 - triangle(st, vec2(0.5, 0.3), vec2(0.75, 0.1), vec2(0.6, 0.1)); // White lines with shader effect left side vec4 line1 = drawLineWithShader(st, vec2(0.05, 0.8), vec2(0.1, 0.7), 0.01); vec4 line2 = drawLineWithShader(st, vec2(0.1, 0.7), vec2(0.1, 0.6), 0.01); vec4 line3 = drawLineWithShader(st, vec2(0.1, 0.6), vec2(0.2, 0.5), 0.01); vec4 line4 = drawLineWithShader(st, vec2(0.2, 0.5), vec2(0.3, 0.5), 0.01); vec4 line5 = drawLineWithShader(st, vec2(0.3, 0.5), vec2(0.2, 0.4), 0.01); vec4 line6 = drawLineWithShader(st, vec2(0.2, 0.4), vec2(0.25, 0.1), 0.01); vec4 line7 = drawLineWithShader(st, vec2(0.25, 0.1), vec2(0.4, 0.1), 0.01); vec4 line8 = drawLineWithShader(st, vec2(0.4, 0.1), vec2(0.48, 0.26), 0.01); vec4 line9 = drawLineWithShader(st, vec2(0.05, 0.8), vec2(0.3, 0.8), 0.01); vec4 line10 = drawLineWithShader(st, vec2(0.3, 0.8), vec2(0.45, 0.63), 0.01); //lines right side vec4 mirrorLine1 = drawLineWithShader(st, vec2(1.0 - 0.05, 0.8), vec2(1.0 - 0.1, 0.7), 0.01); vec4 mirrorLine2 = drawLineWithShader(st, vec2(1.0 - 0.1, 0.7), vec2(1.0 - 0.1, 0.6), 0.01); vec4 mirrorLine3 = drawLineWithShader(st, vec2(1.0 - 0.1, 0.6), vec2(1.0 - 0.2, 0.5), 0.01); vec4 mirrorLine4 = drawLineWithShader(st, vec2(1.0 - 0.2, 0.5), vec2(1.0 - 0.3, 0.5), 0.01); vec4 mirrorLine5 = drawLineWithShader(st, vec2(1.0 - 0.3, 0.5), vec2(1.0 - 0.2, 0.4), 0.01); vec4 mirrorLine6 = drawLineWithShader(st, vec2(1.0 - 0.2, 0.4), vec2(1.0 - 0.25, 0.1), 0.01); vec4 mirrorLine7 = drawLineWithShader(st, vec2(1.0 - 0.25, 0.1), vec2(1.0 - 0.4, 0.1), 0.01); vec4 mirrorLine8 = drawLineWithShader(st, vec2(1.0 - 0.4, 0.1), vec2(1.0 - 0.48, 0.26), 0.01); vec4 mirrorLine9 = drawLineWithShader(st, vec2(1.0 - 0.05, 0.8), vec2(1.0 - 0.3, 0.8), 0.01); vec4 mirrorLine10 = drawLineWithShader(st, vec2(1.0 - 0.3, 0.8), vec2(1.0 - 0.45, 0.63), 0.01); //add all lines together vec4 leftLines = line1 + line2 + line3 + line4 + line5 + line6 + line7 + line8 + line9 + line10; vec4 rightLines = mirrorLine1 + mirrorLine2 + mirrorLine3 + mirrorLine4 + mirrorLine5 + mirrorLine6 + mirrorLine7 + mirrorLine8 + mirrorLine9 + mirrorLine10; // Colors vec4 wingColor1 = wingShader1(st) * (1.0 - mask1); vec4 wingColor2 = wingShader2(st) * (1.0 - mask2); vec4 bodyColor = vec4(0.2, 0.4, 1.0, 1.0); vec4 antennaColor = vec4(1.0, 1.0, 1.0, 1.0) * step(0.5, fract(st.y * 30.0 + u_time)) * (1.0 - mask4); //Output colour_out = (bodyColor * (1.0 - mask3)) + wingColor1 + wingColor2 + antennaColor + leftLines + rightLines; }
Polyommatus Bellargus by Jannik
//No scientific name, but is it okay to name it "Follow the Butterfly"? uniform float u_time; const float PI = 3.14159265359; // Function for generating 2D noise (simple gradient noise) float noise(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453); } // Smooth noise function float smoothNoise(vec2 p) { vec2 i = floor(p); vec2 f = fract(p); float a = noise(i); float b = noise(i + vec2(1.0, 0.0)); float c = noise(i + vec2(0.0, 1.0)); float d = noise(i + vec2(1.0, 1.0)); vec2 u = f * f * (3.0 - 2.0 * f); return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y; } // Smoke effect using noise float smoke(vec2 uv, float time) { float n = 0.0; vec2 p = uv; for (int i = 0; i < 5; i++) { n += smoothNoise(p + time * 0.1) / float(i + 1); p *= 1.6; } return n; } // Signed distance function for a rounded wing shape float sdWing(vec2 p, vec2 size) { p /= size; return length(p) - 1.0; } // Function to create smoother, rounded wing curves float wingShape(vec2 p, float angle) { // Rotate point to create a tilted wing float cosA = cos(angle); float sinA = sin(angle); p = vec2(p.x * cosA - p.y * sinA, p.x * sinA + p.y * cosA); // Control wing curve and size vec2 scale = vec2(0.25, 0.35); // Adjust width and height for realistic look p /= scale; return length(p) - 1.0; } void main() { // Normalize coordinates from -1 to 1 vec2 uv = (gl_FragCoord.xy / 400.0) * 2.0 - 1.25; // Time-based wing flap angle float flapAngle = sin(u_time * 3.0) * 0.3 - 0.5; // Colors change gradually vec3 wingColor = vec3( 0.5 + 0.5 * sin(u_time * 2.0), 0.5 + 0.5 * sin(u_time * 2.5 + PI/3.0), 0.5 + 0.5 * sin(u_time * 3.0 + 2.0*PI/3.0) ); // Draw left wing with a smooth curve and tilt float leftWingDist = wingShape(uv + vec2(0.25, 0.0), flapAngle); // Draw right wing with mirrored curve float rightWingDist = wingShape(uv - vec2(0.25, 0.0), -flapAngle); // Draw butterfly body (small vertical rectangle) float bodyDist = sdWing(uv * vec2(1.0, 2.0), vec2(0.05, 0.2)); // Merge wings and body float d = min(min(leftWingDist, rightWingDist), bodyDist); // Set color based on wing distance vec3 color = mix(vec3(0.3, 0.2, 0.1), wingColor, smoothstep(-0.5, 0.5, -d)); // Smoke effect float smokeAlpha = smoke(uv * 3.0, u_time * 3.0) * 0.5; vec3 smokeColor = vec3(0.2, 0.4, 1.0); // Smooth edge around butterfly shape float alpha = smoothstep(0.02, 0.03, -d) + smokeAlpha; vec3 finalColor = mix(color, smokeColor, smokeAlpha); colour_out = vec4(finalColor, alpha); }
Follow the Butterfly by Rui
// The name I wanna appear of my work is "Fantasy Butterfly" // Introduction: // The inspiration derived from a blue-style butterfly appearing in a novel // with so many supernatural settings. That blue butterfly once became the // horrible nightmare and mysterious symbol for the protagonist, and it // impressed me the reader strongly. So though it is only not realistic, I // think it interesting to replicate and produce a better visual effect. // The concept image is also submitted in this zipped file. However, although // what I desire deviates the image itself, I tried to preserve most features // of this buttefly, including its clear body borderline, flickering on the wings // and color vibrancy. Moreover, I hold a preference to dynamic design so I // enable two wings to wave periodically. I got the equation from mathematicians // and focus on the application of noise pattern and material design. Anyway, // it is not a perfect work, but I wanna you will get surprised at the first glance. // Xiao Tianyu // The name I wanna appear of my work is "Fantasy Butterfly" uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; const float PI = 3.1415926; vec3 createButterFly(vec2 frag); void main() { // Normalized pixel coordinates (from 0 to 1) vec2 uv = gl_FragCoord.xy/u_resolution.xy; // Output to screen colour_out = 0.5+vec4(createButterFly(uv)/1.50,1.0); } // Design: Butterfly with edge-glints // Animation: Butterfly wings fluttering, when fluttering, the colors of the wings orderly change // the edge-glints should flicker, and the colors should change orderly // Perlin noise copied from webgl-noise vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } 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 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; } vec2 fade(vec2 t) { return t*t*t*(t*(t*6.0-15.0)+10.0); } 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))); float n00 = norm.x * dot(g00, vec2(fx.x, fy.x)); float n10 = norm.y * dot(g10, vec2(fx.y, fy.y)); float n01 = norm.z * dot(g01, vec2(fx.z, fy.z)); float n11 = norm.w * 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; } 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); } // SDF float sdWings(vec2 p) { float r = length(p); float t = atan(p.y, p.x); // Originally discovered by Temple H.Fay in 1989, and some changes for a special species float butterfly = 9. - 2.5*sin( 1.*t) + 1.5*sin( 3.*t) + 1.3*sin( 5.*t) - .2*sin( 7.*t) + 2.0*cos( 2.*t) + .2*cos(4.*t) +1.3*cos(6.*t) - 2.0*cos( 8.*t) - 0.4*cos(26.*t) - r; return butterfly; } float uTimeApart(float uTime) { float t = mod(uTime, 2.* PI); if(t >= 0.+0.001 && t <= PI - 0.001) { return uTime; } else { return 0.0; } } vec3 createButterFly(vec2 uv) { uv-= 0.5; uv*= 2.2; // only move left/right(x coord) uv.x *= 1.0 - sin(u_time*2.)*.2; vec2 p =uv*15.0; // transform the butterfly float angle = 20. * PI / 180.; mat3 transform; transform[0] = vec3(cos(angle), sin(angle), 0.); transform[1] = vec3(-sin(angle), cos(angle), 0.); transform[2] = vec3(0., 0., 1.0); vec3 p_transform = transform * vec3(p, 0.); p = vec2(p_transform.x, p_transform.y); float butterfly = sdWings(p); // add noise pattern into the butterfly itself float pnoi = 0.3*cnoise(abs(p)) + 0.7*snoise(abs(p)); vec3 noiseMat = vec3(0.120,0.079,0.071); noiseMat.g += .3*smoothstep(-4.1, .3, butterfly-3.*pnoi); noiseMat.r += .6*smoothstep(-7.1, 0., butterfly); noiseMat.b += .4*smoothstep(-3.1, 0., butterfly/pnoi); noiseMat.r += .5*smoothstep(-3.1, 0., butterfly+1.28*pnoi); noiseMat.g += .2*smoothstep(-2.2, 0., butterfly*pnoi); vec3 brightness = smoothstep(.5, .01, butterfly)-noiseMat; vec3 darkness = smoothstep(.5, .01, butterfly)/noiseMat; vec3 c = mix(brightness, darkness, abs(sin(u_time))); c = mix(c, vec3(0.), -butterfly*8.); // add glints edge to the butterfly float edge = length(vec2( dFdx(butterfly), dFdy(butterfly))); float glint = 0.1 * smoothstep(.01, .5, edge) * abs(sin(u_time * 5.0 + length(p) * 10.0)); vec2 glint_time = vec2(sin(u_time + 0.1) + p.x, cos(u_time + 0.2) + p.y); vec3 whiteBGC = vec3(0.566,0.894,1.000); vec3 glintColor = (abs(butterfly)<1.0)?.5*vec3(1.):vec3(0.); vec3 flickeringColor = vec3( vec2(0.5 + 0.5 * cos(2.0 * PI * sdWings(glint_time))), 0.0); // vec3 color = min(baseColor, glintColor); return c + 0.7*glintColor + flickeringColor * 1.2*sin(u_time) + whiteBGC * 0.24; }
Fantasy Butterly by Xiao Tianyu
// Uniforms uniform vec2 u_resolution; uniform float u_time; // Constants and macros #define shear(g) mat2(1.0, 0.0, g, 1.0) const float PI = 3.1415926; const float scale = 22.8; // Function declarations float function(float r, float t); float solve(vec2 p); float value(vec2 p, float size); float voronoi_noise2(vec2 p); vec2 hash2_2(vec2 p); vec2 domain(vec2 uv, float s); vec3 butterfly_mat(vec2 p, float snd); // Output fragment color void main() { vec2 fragCoord = gl_FragCoord.xy; vec2 uv = domain(fragCoord, 0.7); float snd = 0.5; uv.x *= 1.0 - sin(u_time * 2.0) * 0.2; if (uv.x > 0.0) { uv *= shear((0.3 + sin(snd * 0.2)) * sin(1.2 * u_time)); } else { uv *= shear(-(0.3 + sin(snd * 0.2)) * sin(1.2 * u_time)); } float butterfly = value(uv * scale, 0.005 * scale); vec3 c = vec3(0.0); vec3 bfmat = butterfly_mat(uv * 33.0, snd); vec3 solar = smoothstep(0.05, 0.01, butterfly) + bfmat; vec3 frozen = smoothstep(0.05, 0.01, butterfly) / bfmat; c = mix(solar, frozen, abs(sin(u_time))); c = mix(c, vec3(0.0), -butterfly * 8.0); colour_out = vec4(c, 1.0); } // Domain transformation vec2 domain(vec2 uv, float s) { return (uv / u_resolution * 2.0 - 1.0) * s; } // Butterfly color generation vec3 butterfly_mat(vec2 p, float snd) { float r = length(p); float t = atan(p.y, p.x); float butterfly = 7.0 - 0.5 * sin(t) + 2.5 * sin(3.0 * t) + 2.0 * sin(5.0 * t) - 1.7 * sin(7.0 * t) + 3.0 * cos(2.0 * t) - 2.0 * cos(4.0 * t) - 0.4 * cos(16.0 * t) - r; float vor = voronoi_noise2(abs(p)); vec3 c = vec3(0.0 + snd * 0.5); c.g += 0.8 * smoothstep(-5.1, 0.3, butterfly); c.r += 0.4 * smoothstep(-6.1, 0.3, butterfly / vor); c.r += 0.2 * smoothstep(0.1, 0.0, butterfly); c.g += 0.1 * smoothstep(-0.2, 0.0, butterfly * vor); return c; } // Butterfly mathematical function float function(float r, float t) { return 4.2 - 0.5 * sin(t) + 2.5 * sin(3.0 * t) + 2.0 * sin(5.0 * t) - 1.7 * sin(7.0 * t) + 3.0 * cos(2.0 * t) - 2.0 * cos(4.0 * t) - 0.4 * cos(16.0 * t) - r; } // Solve butterfly structure float solve(vec2 p) { float r = length(p); float t = atan(p.y, p.x); float v = 1000.0; for (int i = 0; i < 32; i++) { v = min(v, abs(function(r, t))); t += PI * 2.0; } return v; } // Value calculation float value(vec2 p, float size) { float error = size; return 1.0 / max(solve(p) / error, 1.0); } // Hashing function for noise vec2 hash2_2(vec2 p) { p = vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3))); return -1.0 + 2.0 * fract(sin(p) * 43758.5453123); } // Voronoi noise function float voronoi_noise2(vec2 p) { vec2 g = floor(p), o; p -= g; vec3 d = vec3(1.0); for (int y = -2; y <= 2; y++) { for (int x = -2; x <= 2; x++) { o = vec2(x, y); o += hash2_2(g + o) - p; d.z = max(dot(o, o), d.z); d.y = max(d.x, min(d.y, d.z)); d.x = min(d.x, d.z); } } return max(d.y / 1.2 - d.x * 1.0, 0.0) / 1.2; }
Unknown by Anonymous
//Name with shader: chen meize //Scientific name of the butterfly:Blue Morpho uniform vec2 u_resolution; float pitime = 50.0; 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)+1.0)*x); } ///////////////////////////////////////////////////////////////// float noisedot(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 = vec2(0.0); i1 = (x0.x > x0.y)? vec2(1.0, 0.0):vec2(0.0, 1.0); vec2 x1 = x0.xy + C.xx - i1; vec2 x2 = x0.xy + C.zz; i = mod289(i); 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(x1,x1), dot(x2,x2) ), 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 = vec3(0.0); g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * vec2(x1.x,x2.x) + h.yz * vec2(x1.y,x2.y); return 130.0 * dot(m, g); } ////////////////////////////////////////////////////////////////// float random (in vec2 st) { return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.5453123); } float bodynoise(vec2 st) { vec2 i = floor(st); vec2 f = fract(st); vec2 u = f*f*(3.0-2.0*f); return mix( mix( random( i + vec2(0.0,0.0) ), random( i + vec2(1.0,0.0) ), u.x), mix( random( i + vec2(0.0,1.0) ), random( i + vec2(1.0,1.0) ), u.x), u.y); } mat2 rotate2d(float angle){ return mat2(cos(angle),-sin(angle), sin(angle),cos(angle)); } float lines(in vec2 pos, float b){ float scale = 10.0; pos *= scale; return smoothstep(0.0, .5+b*.5, abs((sin(pos.x*3.1415)+b*2.0))*.5); } ///////////////////////////////////////////////////////////////// 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); 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); } ////////////////////////////////////////////////////////////// bool isInsideEllipse(vec2 uv, float a, float b, float curvature, vec2 translation, float rotation) { vec2 pos = uv - translation; float cosTheta = cos(rotation); float sinTheta = sin(rotation); vec2 rotatedPos; rotatedPos.x = pos.x * cosTheta - pos.y * sinTheta; rotatedPos.y = pos.x * sinTheta + pos.y * cosTheta; float equation = pow(abs(rotatedPos.x) / a, curvature) + pow(abs(rotatedPos.y) / b, curvature); return equation <= 1.0; } /////////////////////////////////////////////////////////////// void main(void) { vec2 uv = (gl_FragCoord.xy / u_resolution) * 2.0 - 1.0; uv.x *= u_resolution.x / u_resolution.y; vec3 finalColor = vec3(0.611*sin(u_time*2.)*uv.x,0.728,0.530*sin(u_time)*uv.y); float DF = 0.0; float a = -0.640; vec2 vel = vec2(u_time*0.044); vec2 pos = vec2(uv*5.992); DF += snoise(vel)*0.290+3.378; a = snoise(uv.x*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.442+-0.390; vec2 bodypos = uv.yx*vec2(10.,3.); float bodypattern = bodypos.x; bodypos = rotate2d( bodynoise(bodypos) ) * bodypos; bodypattern = lines(bodypos,.5); float casize = 0.045; float wsize = 1.06 - casize + casize * sin(u_time); float moves = 0.01 * sin(u_time); float amoves = 5. * sin(u_time); vec2 uvdot = uv * 10.; float a1 = 0.452*wsize; float b1 = 0.352*wsize; float curvature1 = 1.608; vec2 translation1 = vec2(-0.420,0.270); float rotation1 = radians(0.688*pitime); vec3 color1 = vec3(0.122,0.457,1.000); float a2 = 0.452*wsize; float b2 = 0.352*wsize; float curvature2 = 1.608; vec2 translation2 = vec2(0.420, 0.270); float rotation2 = radians(-0.6880*pitime); vec3 color2 = vec3(0.122,0.457,1.000); float a3 = 0.490*wsize; float b3 = 0.274*wsize; float curvature3 = 1.580; vec2 translation3 = vec2(-0.270,-0.250); float rotation3 = radians(-30.848*pitime); vec3 color3 = vec3(0.122,0.457,1.000); float a4 = 0.490*wsize; float b4 = 0.274*wsize; float curvature4 = 1.580; vec2 translation4 = vec2(0.270,-0.270); float rotation4 = radians(30.848*pitime); vec3 color4 = vec3(0.483,0.646,1.000); float a5 = 0.482; float b5 = 0.100; float curvature5 = 2.060; vec2 translation5 = vec2(-0.0,0.05); float rotation5 = radians(30.600*pitime); vec3 color5 = vec3(0.6, 0.3, 0.1); float a6 = 0.482*wsize; float b6 = 0.274*wsize; float curvature6 = 2.484; vec2 translation6 = vec2(-0.520,0.150); float rotation6 = radians(29.720*pitime); vec3 color6 = vec3(0.155,0.080,0.036); float a7 = 0.482*wsize; float b7 = 0.274*wsize; float curvature7 = 2.484; vec2 translation7 = vec2(0.520,0.150); float rotation7 = radians(-29.720*pitime); float a8 = 0.482*wsize; float b8 = 0.274*wsize; float curvature8 = 1.916; vec2 translation8 = vec2(-0.300,-0.350); float rotation8 = radians(30.224*pitime); vec2 translation9 = vec2(0.300,-0.350); float rotation9 = radians(-30.224*pitime); float a10 = 0.12; float b10 = 0.12; float curvature10 = 2.; vec2 translation10 = vec2(-0.0,0.550); float rotation10 = radians(29.720*pitime); vec3 color10 = vec3(0.155,0.080,0.036); float a11 = 0.032; float b11 = 0.040; float curvature11 = 1.984; vec2 translation11 = vec2(-0.080,0.620); float rotation11 = radians(29.720*pitime); vec3 color11 = vec3(0.0,0.0,0.0); vec2 translation12 = vec2(0.080,0.620); float rotation12 = radians(-29.720*pitime); vec3 color12 = vec3(0.0,0.0,0.0); float a13 = 0.012; float b13 = 0.012; float curvature13 = 2.; vec2 translation13 = vec2(-0.080+moves,0.620+moves); float rotation13 = radians(29.720*pitime); vec3 color13 = vec3(1.); vec2 translation14 = vec2(0.080+moves,0.620+moves); float rotation14 = radians(29.720*pitime); vec3 color14 = vec3(1.); float a15 = 0.29+moves; float b15 = 0.01; float curvature15 = 4.984; vec2 translation15 = vec2(-0.040,0.620); float rotation15 = radians(30.280*pitime+amoves); vec3 color15 = vec3(0.005,0.005,0.005); float a16 = 0.29+moves; float b16 = 0.01; float curvature16 = 4.984; vec2 translation16 = vec2(0.040,0.620); float rotation16 = radians(-30.280*pitime+amoves); vec3 color16 = vec3(0.005,0.005,0.005); if(isInsideEllipse(uv, a16, b16, curvature16, translation16, rotation16)) { vec3 noisyColor = color16; finalColor = noisyColor; } if(isInsideEllipse(uv, a15, b15, curvature15, translation15, rotation15)) { vec3 noisyColor = color15; finalColor = noisyColor; } if(isInsideEllipse(uv, a8, b8, curvature8, translation9, rotation9)) { vec3 noisyColor = color6 + vec3(noisedot(uvdot)*1.996+-1.004); finalColor = noisyColor; } if(isInsideEllipse(uv, a8, b8, curvature8, translation8, rotation8)) { vec3 noisyColor = color6 + vec3(noisedot(uvdot)*1.996+-1.004); finalColor = noisyColor; } if(isInsideEllipse(uv, a7, b7, curvature7, translation7, rotation7)) { vec3 noisyColor = color6 + vec3(noisedot(uvdot)*1.996+-1.004); finalColor = noisyColor; } if(isInsideEllipse(uv, a6, b6, curvature6, translation6, rotation6)) { vec3 noisyColor = color6 + vec3(noisedot(uvdot)*1.996+-1.004); finalColor = noisyColor; } if(isInsideEllipse(uv, a1, b1, curvature1, translation1, rotation1)) { vec3 noisyColor = color1 + mix(vec3(0.192,0.340,1.000), vec3(0.009,0.025,1.000), fract(DF)); finalColor = noisyColor; } if(isInsideEllipse(uv, a2, b2, curvature2, translation2, rotation2)) { vec3 noisyColor = color2 + mix(vec3(0.192,0.340,1.000), vec3(0.009,0.025,1.000), fract(DF)); finalColor = noisyColor; } if(isInsideEllipse(uv, a3, b3, curvature3, translation3, rotation3)) { vec3 noisyColor = color3 + mix(vec3(0.192,0.340,1.000), vec3(0.009,0.025,1.000), fract(DF)); finalColor = noisyColor; } if(isInsideEllipse(uv, a4, b4, curvature4, translation4, rotation4)) { vec3 noisyColor = color3 + mix(vec3(0.192,0.340,1.000), vec3(0.009,0.025,1.000), fract(DF)); finalColor = noisyColor; } if(isInsideEllipse(uv, a5, b5, curvature5, translation5, rotation5)) { vec3 noisyColor = color5; finalColor = noisyColor-bodypattern; } if(isInsideEllipse(uv, a10, b10, curvature10, translation10, rotation10)) { vec3 noisyColor = color5; finalColor = noisyColor-bodypattern; } if(isInsideEllipse(uv, a11, b11, curvature11, translation11, rotation11)) { vec3 noisyColor = color11; finalColor = noisyColor; } if(isInsideEllipse(uv, a11, b11, curvature11, translation12, rotation12)) { vec3 noisyColor = color11; finalColor = noisyColor; } if(isInsideEllipse(uv, a13, b13, curvature13, translation13, rotation13)) { vec3 noisyColor = color13; finalColor = noisyColor; } if(isInsideEllipse(uv, a13, b13, curvature13, translation14, rotation14)) { vec3 noisyColor = color13; finalColor = noisyColor; } colour_out = vec4(finalColor, 1.0); }
Blue Morpho by chen
meize
uniform vec2 u_resolution; uniform float u_time; #define shear(g) mat2(1.0, 0.0, g, 1.0) const float PI = 3.1415926; const float scale = 22.8; float function(float r, float t); float solve(vec2 p); float value(vec2 p, float size); float voronoi_noise2(vec2 p); vec2 hash2_2(vec2 p); vec2 domain(vec2 uv, float s); vec3 butterfly_mat(vec2 p, float snd); void main() { vec2 fragCoord = gl_FragCoord.xy; vec2 uv = domain(fragCoord, 0.7); float snd = 0.5; uv.x *= 1.0 - sin(u_time * 1.0) * 0.2; if (uv.x > 0.0) { uv *= shear((0.3 + sin(snd * 0.2)) * sin(1.2 * u_time)); } else { uv *= shear(-(0.3 + sin(snd * 0.2)) * sin(1.2 * u_time)); } float butterfly = value(uv * scale, 0.005 * scale); vec3 c = vec3(0.0); vec3 bfmat = butterfly_mat(uv * 33.0, snd); vec3 solar = smoothstep(0.05, 0.01, butterfly) + bfmat; vec3 frozen = smoothstep(0.05, 0.01, butterfly) / bfmat; c = mix(solar, frozen, abs(sin(2.0 * u_time))); c = max(c, vec3(0.238,0.314,0.770)); colour_out = vec4(c, 1.0); } // Domain transformation vec2 domain(vec2 uv, float s) { return (uv / u_resolution * 2.0 - 1.0) * s; } // Butterfly color vec3 butterfly_mat(vec2 p, float snd) { float t = abs(sin(u_time * 0.5)) * 0.2; return max(vec3(0.4 + t, 0.5 + t * 0.5, 1.0 - t * 0.3), vec3(0.2)); } // Butterfly mathematical function float function(float r, float t) { return 6.2 - 0.5 * sin(t) + 2.5 * sin(3.0 * t) + 2.0 * sin(5.0 * t) - 1.7 * sin(7.0 * t) + 3.0 * cos(2.0 * t) - 2.0 * cos(4.0 * t) - 0.4 * cos(16.0 * t) - r; } float solve(vec2 p) { float r = length(p); float t = atan(p.y, p.x); float v = 1000.0; for (int i = 0; i < 25; i++) { v = min(v, abs(function(r, t))); t += PI * 2.0; } return v; } // Value calculation float value(vec2 p, float size) { float error = size; return 1.0 / max(solve(p) / error, 1.0); } // Hashing function for noise vec2 hash2_2(vec2 p) { p = vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3))); return -1.0 + 2.0 * fract(sin(p) * 43758.5453123); } // Voronoi noise function float voronoi_noise2(vec2 p) { vec2 g = floor(p), o; p -= g; vec3 d = vec3(1.0); for (int y = -2; y <= 2; y++) { for (int x = -2; x <= 2; x++) { o = vec2(x, y); o += hash2_2(g + o) - p; d.z = max(dot(o, o), d.z); d.y = max(d.x, min(d.y, d.z)); d.x = min(d.x, d.z); } } return max(d.y / 2.5 - d.x * 1.0, 0.0) / 1.2; }
Unknown by Anonymous
// Submission Name: Emily // Butterfly: Papilio Ulysses uniform vec2 u_resolution; uniform float u_time; float dot2(in vec2 v ) { return dot(v,v); } float cro( vec2 a, vec2 b ) { return a.x*b.y-a.y*b.x; } float cos_acos_3( float x ) { x=sqrt(0.5+0.5*x); return x*(x*(x*(x*-0.008972+0.039071)-0.107074)+0.576975)+0.5; } float hash(float n) { return fract(sin(n) * 43758.5453123); } 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 sdBox( in vec2 p, in vec2 b ) { vec2 d = abs(p)-b; return length(max(d,0.0)) + min(max(d.x,d.y),0.0); } float sdCircle( vec2 p, float r ) { return length(p) - r; } float sdBumpy(vec2 point, float edgeBumpiness) { float distance = sdBox(point, vec2(0.2, 0.2)) + 0.05; float edgeThreshold = 0.75; if (abs(distance) < edgeThreshold) { float noiseValue = sin(point.x * 30.0 + point.y * 20.0 + u_time * 0.5) * edgeBumpiness; distance += noiseValue * (edgeThreshold - abs(distance)); } return distance; } 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 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 sdBezier( in vec2 pos, in vec2 A, in vec2 B, in vec2 C ) { vec2 a = B - A; vec2 b = A - 2.0*B + C; vec2 c = a * 2.0; vec2 d = A - pos; float kk = 1.0/dot(b,b); float kx = kk * dot(a,b); float ky = kk * (2.0*dot(a,a)+dot(d,b)) / 3.0; float kz = kk * dot(d,a); float res = 0.0; float p = ky - kx*kx; float p3 = p*p*p; float q = kx*(2.0*kx*kx-3.0*ky) + kz; float h = q*q + 4.0*p3; if( h >= 0.0) { h = sqrt(h); vec2 x = (vec2(h,-h)-q)/2.0; vec2 uv = sign(x)*pow(abs(x), vec2(1.0/3.0)); float t = clamp( uv.x+uv.y-kx, 0.0, 1.0 ); res = dot2(d + (c + b*t)*t); } else { float z = sqrt(-p); float v = acos( q/(p*z*2.0) ) / 3.0; float m = cos(v); float n = sin(v)*1.732050808; vec3 t = clamp(vec3(m+m,-n-m,n-m)*z-kx,0.0,1.0); res = min( dot2(d+(c+b*t.x)*t.x), dot2(d+(c+b*t.y)*t.y) ); // the third root cannot be the closest // res = min(res,dot2(d+(c+b*t.z)*t.z)); } return sqrt( res ); } float sdUnion(float d1, float d2) { return min(d1, d2); } float sdRound( in float d, in float r ) { return d - r; } float sdDifference(float d1, float d2) { return max(d1, -d2); } vec2 rotate(vec2 p, float theta) { float cosTheta = cos(theta); float sinTheta = sin(theta); return vec2( p.x * cosTheta - p.y * sinTheta, p.x * sinTheta + p.y * cosTheta ); } vec2 translate(vec2 p, vec2 offset) { return p - offset; } float smod(float x, float n) { float period = 2.0 * n; float mod_x = mod(x, period); return abs(mod_x - n); } float zigzagNoise(vec2 p, float frequency) { float y_coord = p.y * 1000.; float x_offset = smod(y_coord, 50.); float normalized = x_offset / 50.; return normalized; } // Taken from stegu/psrdnoise float psrdnoise(vec2 x, vec2 period, float alpha, out vec2 gradient) { // Transform to simplex space (axis-aligned hexagonal grid) vec2 uv = vec2(x.x + x.y*0.5, x.y); // Determine which simplex we're in, with i0 being the "base" vec2 i0 = floor(uv); vec2 f0 = fract(uv); // o1 is the offset in simplex space to the second corner float cmp = step(f0.y, f0.x); vec2 o1 = vec2(cmp, 1.0-cmp); // Enumerate the remaining simplex corners vec2 i1 = i0 + o1; vec2 i2 = i0 + vec2(1.0, 1.0); // Transform corners back to texture space 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); // Compute vectors from v to each of the simplex corners vec2 x0 = x - v0; vec2 x1 = x - v1; vec2 x2 = x - v2; vec3 iu, iv; vec3 xw, yw; // Wrap to periods, if desired 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); // Transform back to simplex space and fix rounding errors iu = floor(xw + 0.5*yw + 0.5); iv = floor(yw + 0.5); } else { // Shortcut if neither x nor y periods are specified iu = vec3(i0.x, i1.x, i2.x); iv = vec3(i0.y, i1.y, i2.y); } // Compute one pseudo-random hash value for each corner 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); // Pick a pseudo-random angle and add the desired rotation vec3 psi = hash * 0.07482 + alpha; vec3 gx = cos(psi); vec3 gy = sin(psi); // Reorganize for dot products below vec2 g0 = vec2(gx.x,gy.x); vec2 g1 = vec2(gx.y,gy.y); vec2 g2 = vec2(gx.z,gy.z); // Radial decay with distance from each simplex corner 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; // The value of the linear ramp from each of the corners vec3 gdotx = vec3(dot(g0, x0), dot(g1, x1), dot(g2, x2)); // Multiply by the radial decay and sum up the noise value float n = dot(w4, gdotx); // Compute the first order partial derivatives 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); // Scale the return value to fit nicely into the range [-1,1] return 10.9 * n; } float noise(vec2 p) { vec2 i = floor(p); vec2 f = fract(p); float a = hash(i.x + i.y * 57.0); float b = hash(i.x + 1.0 + i.y * 57.0); float c = hash(i.x + (i.y + 1.0) * 57.0); float d = hash(i.x + 1.0 + (i.y + 1.0) * 57.0); vec2 u = f * f * (3.0 - 2.0 * f); return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y; } vec4 mainImage(vec2 fragCoord ) { vec2 p = (2.0*fragCoord-u_resolution.xy)/u_resolution.y; ///////////// // Shape // ///////////// // Mirror coordinates vec2 p_n = p; p.x = abs(p.x); // Uper Wing vec2 p_curve = translate(p, vec2(-0.01, 0.125)); float d_curve = sdOrientedVesica(p_curve, vec2(0.7, 0.576), vec2(0.0, 0.0), 0.1); float d_upper_triag = sdRound(sdTriangle(p, vec2(0.1, 0.1), vec2(0.7, 0.6), vec2(0.6, 0.1)), 0.1); float d_upper_wing = sdUnion(d_curve, d_upper_triag); // Lower Wing vec2 p_bump = rotate(translate(p, vec2(0.45, -0.4)), 0.2); float d_bump = sdBumpy(p_bump, 0.1); float d_lower_triag = sdRound(sdTriangle(p, vec2(0.1, 0.0), vec2(0.25, -0.5), vec2(0.65, -0.25)), 0.05); float d_lower_wing = sdUnion(d_bump, d_lower_triag); // Body vec2 v1_torso = cos( 2.0 + vec2(-0.425,-0.2) ); vec2 v2_torso = cos( 0.5 + vec2(-0.425,3.10) + 1.5 ); float th_torso = 0.3+0.5*cos(2.0); float d_torso = sdSegment( p_n, v1_torso, v2_torso ) - th_torso; vec2 v0_ant = vec2(0.05,0.3); vec2 v1_ant = vec2(0.05,0.5); vec2 v2_ant = vec2(0.2,0.8); float d_ant = sdBezier( p, v0_ant, v1_ant, v2_ant) - 0.01; float d_body = sdUnion(d_torso, d_ant); // Eyes vec2 p_left_eye = translate(p, vec2(-0.1, 0.4)); float d_left_eye = sdCircle(p_left_eye, 0.04); vec2 p_right_eye = translate(p, vec2(0.1, 0.4)); float d_right_eye = sdCircle(p_right_eye, 0.04); float d_eyes = sdUnion(d_left_eye, d_right_eye); // Union float d_wings = sdUnion(d_upper_wing, d_lower_wing); ///////////// // Color // ///////////// // Border Shape float d_color_circle = sdCircle(p, 0.5); float noisy = d_color_circle + zigzagNoise(p + u_time * 0.02, 5.0) * 0.1; // Inner vec2 noisy_p = vec2(p.x + (hash(p.x) * 0.05), p.y); float radius = length(p) * 20.0; vec2 radial_p = vec2(radius - u_time * 0.5, hash(p.y)) * 0.75; float n_inner = noise(radial_p); const float nscale = 4.0; vec2 v = nscale * (p - 0.5); const vec2 p_inner = vec2(4.0, 4.0); float alpha = u_time; vec2 g, gsum; float warp = 0.13; float n = 0.0; float w = 1.0; float s = 1.0; gsum = vec2(0.0); for(float i = 0.0; i<4.0; i++) { n += w*psrdnoise(s * v + warp * gsum, s * p_inner, s * alpha, g); gsum += w * g; w *= 0.5; s *= 2.0; } n_inner += 0.5 - 0.4 * n; float dist_from_center = length(p); vec3 col_inner = mix(vec3(0.8, 0.95, 0.95), vec3(0.24, 0.87, 0.89), n_inner); col_inner = vec3(col_inner.r, col_inner.g + mix(0.3, 0.0 , min(dist_from_center * 4.0, 1.0)), col_inner.b); // Outer vec2 v_outer = 6.0 * (p - 0.5); const vec2 p_outer = vec2(8.0, 8.0); float alpha_outer = 0.5 * u_time; vec2 g_outer; float n_outer = 0.5; n_outer += 0.4 * psrdnoise(v_outer, p_outer, alpha_outer, g_outer); n_outer += 0.2 * psrdnoise(2.0 * v_outer + 0.1, p_outer * 2.0, 2.0 * alpha_outer, g_outer); n_outer += 0.1 * psrdnoise(3.0 * v_outer + 0.2, p_outer * 4.0, 4.0 * alpha_outer, g_outer); vec3 col_outer = mix(vec3(0.15, 0.15, 0.1), vec3(0.1, 0.1, 0.1), n_outer); // Coloring vec3 col_body = (d_eyes < 0.0) ? vec3(0.97, 0.73, 0.82) : vec3(0.25, 0.25, 0.25); float wing_blend = smoothstep(0.0, 0.05, noisy); vec3 col_wings = mix(col_inner, col_outer, wing_blend); vec3 col_butterfly = (d_body > 0.0 && d_wings < 0.01) ? col_wings : col_body; float outer_blend = smoothstep(0.0, 0.01, min(d_body, d_wings)); vec3 col_background = vec3(1.0, 1.0, 1.0); vec3 col = mix(col_butterfly, col_background, outer_blend); vec4 fragColor = vec4(col, 1.0); return fragColor; } void main() { colour_out = mainImage(gl_FragCoord.xy); }
Papilio Ulysses by Emily
More Student Works
The rest of the student works from 2024 are shown below. Note that some are very computationally expensive and may potentially cause issues with your browser. Show Other Student Works
uniform vec2 u_resolution; uniform float u_time; float sdRectangle( vec2 p, vec2 r ) { vec2 d = abs(p)-r; return length(max(d,0.0)) + min(max(d.x,d.y),0.0); } float sdParallelogram(vec2 p, float wi, float he, float sk ){ vec2 e = vec2(sk,he); float e2 = sk*sk + he*he; p = (p.y<0.0)?-p:p; // horizontal edge vec2 w = p - e; w.x -= clamp(w.x,-wi,wi); vec2 d = vec2(dot(w,w), -w.y); // vertical edge float s = p.x*e.y - p.y*e.x; p = (s<0.0)?-p:p; vec2 v = p - vec2(wi,0); v -= e*clamp(dot(v,e)/e2,-1.0,1.0); d = min( d, vec2(dot(v,v), wi*he-abs(s))); return sqrt(d.x)*sign(-d.y); } float sdEllipse(vec2 p, 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 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(max(1.0-co*co,0.0))); return length(r-p) * sign(p.y-r.y); } float dot2( in vec2 v ) { return dot(v,v); } float sdHeart( 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 sdUnion( float d1, float d2 ) { return min( d1, d2 ); } float sdDifference( float d1, float d2 ) { return max( -d1, d2 ); // Remove d1 from d2 } float sdf1( vec2 p ) { float c=cos(-0.5); float s=sin(-0.5); float u=cos(-1.5); float v=sin(-1.5); float d1 = sdHeart(vec2(c*p.x-s*p.y,s*p.x+c*p.y)+vec2(0.0,0.5)); float d2 = sdEllipse(vec2(c*p.x-s*p.y,s*p.x+c*p.y)+vec2(0.0,0.5),vec2(0.5,0.1)); float d5 = sdRectangle(vec2(u*p.x-v*p.y,v*p.x+u*p.y)+vec2(-0.15,0.65),vec2(0.3,0.01)); return sdUnion(d1, sdUnion(d2,d5)); } float sdf2(vec2 p){ float d3 = sdEllipse(p+vec2(-0.1,-0.35),vec2(0.1,0.1)); float d4 = sdEllipse(p+vec2(0.35,-0.1),vec2(0.1,0.1)); return sdUnion(d3,d4); } void main(){ vec2 p = (gl_FragCoord.xy * 2.0 - u_resolution.xy) / min(u_resolution.x, u_resolution.y); float d = sdf1(p); float ee = sdf2(p); vec3 col = (d>0.0) ? vec3(0.0,0.32-0.5*p.y,0.2) : vec3(0.66,0.59,0.39); //col *= 1.0 - exp(-6.0*abs(d)); //col *= 0.8 + 0.2*cos(150.0*d); col = mix( col, vec3(1.0), 1.0-smoothstep(0.0,0.01,abs(d)) ); col += (ee>0.0)? vec3(0.0) : vec3(p.x,p.y-0.5,abs(sin(u_time))); colour_out = vec4(col, 1.0); }
Unknown by Anonymous
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); } float sky_fbm(vec2 p, float u_time) { float f = 0.0, scale; for (int i=0; i<4; i++) { scale = pow(pow(2.0, 4.0/3.0), float(i)); //// change the shape and amount of clouds f += snoise(vec2(p.x-cos(u_time*0.5),p.y) * scale + u_time*0.2) / scale; } return f; } float sdCircle(vec2 p, vec2 a, float r) { //// (p,position,radius) return length(p-a) - r; } float sdRectangle(vec2 p, vec3 r) { //// (p,(x_width,y-position,y_width)) vec2 d = vec2(abs(p.x)-r.x, abs(p.y-r.y)-r.z); return length(max(d,0.0)) + min(max(d.x,d.y),0.0); } 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 smin(float a, float b, float k) { // A or B float h = max(k-abs(a-b), 0.0)/k; return min(a, b) - h*h*k*(1.0/4.0); } float smax(float a, float b, float k) { // A and B float h = max(k-abs(a-b),0.0); return max(a, b) + h*h*0.25/k; } float fore_wing(vec2 p) { float d1 = sdCircle(p, vec2(0.21,0.18), 0.2); float d2 = sdRectangle(p, vec3(0.25,0.1,0.11)); float d3 = sdCircle(p, vec2(0.34,-0.58), 0.8); return smax(smin(d1, d2, 0.03), d3, 0.03); } float hind_wing(vec2 p) { float d1 = sdCircle(p, vec2(0.13,-0.05), 0.15); float d2 = sdRectangle(p, vec3(0.265,-0.1,0.1)); float d3 = sdCircle(p, vec2(0.27,-0.03), 0.025); return smax(smax(d1, -d3, 0.04), d2, 0.01); } float body_top(vec2 p){ vec2 P = (p-vec2(0.0,0.12))*15.0; float d1 = sdEquilateralTriangle(P); float d2 = sdCircle(p, vec2(0.0,0.185), 0.01); return smin(d1, d2, 0.1); } float body_under(vec2 p){ vec2 P =(vec2(p.x,-p.y)-vec2(0.0,0.08))*15.0; float d1 = sdEquilateralTriangle(P); float d2 = sdCircle(p, vec2(0.0,-0.145), 0.01); return smin(d1, d2, 0.1); } float body(vec2 p) { float body_u = smax(body_under(p), sdRectangle(p, vec3(0.025,0.0,0.17)), 0.1); float body_t = mix(body_top(p), sdRectangle(p, vec3(0.023,0.02,0.17)), 0.65); body_t = smax(body_t, sdCircle(p, vec2(0.0, 0.15), 0.115), 0.17); float body_tc = smin(body_t, sdRectangle(p, vec3(0.025,0.0,0.1)), 0.1); return smin(body_u, body_tc, 0.01); } float butterfly(vec2 p) { float wing_t = fore_wing(p); float wing_u = hind_wing(p); float body_t = body_top(p); float body_u = body_under(p); return smin(smin(smin(wing_t, wing_u, 0.02), body_t, 0.01) ,body_u ,0.01); } float antennas(vec2 p, vec2 v){ return sdRectangle(p, vec3(v,0.003)); } void main() { vec2 pos = 0.5* (2.0 * gl_FragCoord.xy - u_resolution.xy) / u_resolution.x; // flapping float flapEffect = 1.0 + 0.3 * abs(pos.y) * sin(u_time * 10.0); pos.x *= flapEffect; // background (sky) float n = sky_fbm(gl_FragCoord.xy / 250.0, u_time); colour_out = vec4(0.9*n+0.1, 0.9*n+0.1, 0.1*n+0.9, 1.0); pos.x = abs(pos.x); // antennas float c = cos(2.4); float s = sin(2.4); mat2 R = mat2(c, s, -s, c); vec2 rp = R * (pos - vec2(-0.1,0.35)); for (float i=0.0; i<15.0; i+=1.0) { float da = antennas(rp, vec2(0.14-i*0.01,0.2)); if (da < 0.0){ if (mod(i,2.0)== 0.0) colour_out = vec4(vec3(0.0),1.0); else colour_out = vec4(1.0); } } // butterfly float db = butterfly(pos); vec3 colorStart = vec3(186.0, 210.0, 224.0); //// center's colour vec3 colorEnd = vec3(245.0, 245.0, 255.0); //// corner's colour float dd = smoothstep(0.0, 0.85, sin(pos.x+0.01+abs(pos.y+0.03))); if (db < -0.005) colour_out = vec4(mix(colorStart/255.0, colorEnd/255.0, dd),1.0); else if (db < -0.002) colour_out = vec4(vec3(0.0), 1.0); // black else if (db < 0.004) colour_out = vec4(1.0); // white colorStart = colorStart + vec3(-4.5, -4.5, 3.0); colorEnd = colorEnd + vec3(-4.5, -4.5, 3.0); if (body(pos)< -0.003) colour_out = vec4(mix(colorStart/255.0, colorEnd/255.0, dd),1.0); }
Polyommatus bellargus by taka
// 学名: 分かりませんでした… uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; // ---- https://github.com/stegu/webgl-noise/blob/master/src/noise2D.glsl ---- 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 sdBody(in vec2 p) { vec2 b = vec2(0.01, 0.4); vec2 d = abs(p)-b; return length(max(d,0.0)) + min(max(d.x,d.y),0.0); } float sdRoundedBody(in vec2 p) { float r = 0.02; return sdBody(p) - r; } 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 sdRoundedTriangle( in vec2 p, in vec2 p0, in vec2 p1, in vec2 p2, in float r ) { return sdTriangle(p, p0, p1, p2) - r; } // 線分 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 butterfly_mask(vec2 p) { float mask = 1.0; p = vec2(abs(p.x), p.y); // 左右対称 // チョウの領域の内部の点のとき、mask=0 if (sdRoundedBody(p) <= 0.) { mask = 0.; } float speed_f = 0.8; float anim_s = sin(u_time * speed_f); float anim_s_2 = sin(3.0 * u_time * speed_f); float wave_coef = (1.0 - anim_s * 0.1 + anim_s_2 * 0.01); float wave_coef_s = (1.0 - anim_s * 0.05); // 触覚 if (sdSegment(p, vec2(0.01, 0.4), vec2(0.05 * wave_coef_s, 0.6 * wave_coef_s)) <= 0.01) { mask = 0.; } // 羽(上) if (sdRoundedTriangle(p, vec2(0.1, 0.3), vec2(0.8 * wave_coef, 0.3 * wave_coef), vec2(0.8, 0.7 * wave_coef), 0.1) <= 0.) { mask = 0.; } // 羽(下) if (sdRoundedTriangle(p, vec2(0.1, 0.2), vec2(0.7 * wave_coef, -0.2 * wave_coef), vec2(0.5, -0.8 * wave_coef), 0.1) <= 0.) { mask = 0.; } return mask; } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; st = (st - 0.5) * 2.0; // 座標を[-1.0, 1.0]に変換する float mask = butterfly_mask(st); float sc = 2.0; // noise scale vec2 mv = vec2(sin(st.x * sc + u_time * 0.3), sin(st.y * sc + u_time * 0.5)); float noise = snoise(mv) - snoise(mv * 5.0) * abs(sin(u_time * 0.7)) * 0.2; // 適当にノイズ重ねてみる noise = max(noise, 0.1); colour_out = vec4( noise, noise, abs(sin(0.5*u_time)) * 0.2, 1.0 ); colour_out *= 1.0-mask; }
Unknown by aoi
uniform vec2 u_resolution; uniform float u_time; bool isInCircle(vec2 p, vec2 center, float radius) { return distance(p, center) < radius; } bool isInRect(vec2 p, vec2 position, vec2 size) { return (p.x > position.x && p.x < position.x + size.x && p.y > position.y && p.y < position.y + size.y); } bool isInTriangle(vec2 p, vec2 a, vec2 b, vec2 c) { vec2 v0 = c - a; vec2 v1 = b - a; vec2 v2 = p - a; float d00 = dot(v0, v0); float d01 = dot(v0, v1); float d11 = dot(v1, v1); float d20 = dot(v2, v0); float d21 = dot(v2, v1); float denom = d00 * d11 - d01 * d01; float v = (d11 * d20 - d01 * d21) / denom; float w = (d00 * d21 - d01 * d20) / denom; float u = 0.080 - v - w; return (u >= -0.040 && v >= 0.0 && w >= 0.0); } vec2 rotate(vec2 p, float angle) { float c = cos(angle); float s = sin(angle); mat2 rotationMatrix = mat2(c, -s, s, c); return rotationMatrix * p; } // ホワイトノイズを生成 float whiteNoise(vec2 p) { return fract(sin(dot(p.xy, vec2(12.9898, 78.233))) * 43758.5453); } vec3 createBushyGrass(vec2 st) { float noiseValue = whiteNoise(st * u_time * 0.3); noiseValue = smoothstep(0.720, 1.816, noiseValue); vec3 grassColor = vec3(0.1, 0.5, 0.1) + noiseValue * 0.5; return grassColor; } void main() { vec2 st = gl_FragCoord.xy / u_resolution.xy; vec3 background = createBushyGrass(st); float wing1 = isInCircle(st, vec2(0.430, 0.660), 0.08) ? 1.0 : 0.0; float wing2 = isInCircle(st, vec2(0.590, 0.590), 0.10) ? 1.0 : 0.0; float wing3 = isInCircle(st, vec2(0.410, 0.570), 0.060) ? 1.0 : 0.0; float wing4 = isInCircle(st, vec2(0.5, 0.524), 0.065) ? 1.0 : 0.0; float wings = max(max(wing1, wing2), max(wing3, wing4)); vec2 bodyCenter = vec2(0.197, 0.400); vec2 bodySize = vec2(0.03, 0.24); float angle = 2.75; vec2 rotatedPos = rotate(st - bodyCenter, angle) + bodyCenter; float body = isInRect(rotatedPos, vec2(0.0), bodySize) ? 1.0 : 0.0; vec2 a = vec2(0.590, 0.730); vec2 b = vec2(0.070, 0.210); vec2 c = vec2(0.55, 1.5); float antenna1 = isInTriangle(st, a, b, c) ? 1.0 : 0.0; a = vec2(0.500, 0.720); b = vec2(0.520, 1.6); c = vec2(0.660, 0.420); float antenna2 = isInTriangle(st, a, b, c) ? 1.0 : 0.0; float noiseValueWing = whiteNoise(st * 8.0 + u_time * 0.3); vec3 noiseColorWing = vec3(0.056, 0.003, 1.000) * noiseValueWing; colour_out = vec4(noiseColorWing * wings, 0.448); float noiseValueBody = whiteNoise(rotatedPos * 2.0 + u_time * 0.001); vec3 noiseColorBody = vec3(0.001, 0.049, 0.600) * noiseValueBody; colour_out += vec4(noiseColorBody * body, 1.032); colour_out += vec4(0.1, 0.2, 0.3, 1.0) * (antenna1 + antenna2); colour_out *= max(max(wings, body), max(antenna1, antenna2)); colour_out += vec4(background, 1.0); }
Adonis blue (Polyommatus bellargus) by
Takahashi Hayato
uniform vec2 u_resolution; float rotatedEllipseSDF(vec2 p, vec2 center, float rx, float ry, float angle) { vec2 relP = p - center; float cosTheta = cos(angle); float sinTheta = sin(angle); vec2 rotatedP = vec2( cosTheta * relP.x + sinTheta * relP.y, -sinTheta * relP.x + cosTheta * relP.y ); vec2 normalizedP = rotatedP / vec2(rx, ry); return length(normalizedP) - 1.0; } float wingSDF(vec2 p) { float leftTopWing = rotatedEllipseSDF(p, vec2(-0.5, 0.3), 0.6, 0.3, -3.14159 / 4.0); float rightTopWing = rotatedEllipseSDF(p, vec2(0.5, 0.3), 0.6, 0.3, 3.14159 / 4.0); float rightBottomWing = rotatedEllipseSDF(p, vec2(0.3, -0.3), 0.4, 0.2, -3.14159 / 6.0); float leftBottomWing = rotatedEllipseSDF(p, vec2(-0.3, -0.3), 0.4, 0.2, 3.14159 / 6.0); return min(min(leftTopWing, rightTopWing), min(leftBottomWing, rightBottomWing)); } float ellipseSDF(vec2 p, vec2 center, float radiusX, float radiusY) { vec2 normalized = (p - center) / vec2(radiusX, radiusY); return length(normalized) - 1.0; } float bodySDF(vec2 p) { return ellipseSDF(p, vec2(0.0, 0.0), 0.1, 0.5); } float lineSDF(vec2 p, vec2 a, vec2 b) { vec2 pa = p - a; vec2 ba = b - a; float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0); return length(pa - h * ba); } float antennaSDF(vec2 p) { float leftAntenna = lineSDF(p, vec2(-0.03, 0.48), vec2(-0.3, 0.8)); float rightAntenna = lineSDF(p, vec2(0.03, 0.48), vec2(0.3, 0.8)); return min(leftAntenna, rightAntenna); } void main() { vec2 p = (gl_FragCoord.xy * 2.0 - u_resolution.xy) / min(u_resolution.x, u_resolution.y); float body = bodySDF(p); float wings = wingSDF(p); float antenna = antennaSDF(p); float butterfly = min(min(body, wings), antenna); float border = smoothstep(0.02, 0.0, butterfly); vec3 bgColor = vec3(0.2, 1.0, 0.3); vec3 butterflyColor = vec3(0.0, 0.0, 0.0); if (antenna < 0.0) { butterflyColor = vec3(0.3, 0.3, 0.3); } else if (body < 0.0) { butterflyColor = vec3(0.3, 0.5, 0.9); } else if (wings < 0.0) { float gradient = smoothstep(-0.4, -0.05, wings); butterflyColor = mix(vec3(0.3, 0.5, 0.9), vec3(1.0, 1.0, 1.0), gradient); } colour_out = vec4(mix(bgColor, butterflyColor, border), 1.0); }
adonis blue by yamada
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.25, distance( st.xy, vec2(0.35, 0.55) ) ); mask *= step( 0.25, distance( st.xy, vec2(0.65, 0.55) ) ); mask *= step( 0.13, distance( st.xy, vec2(0.25, 0.24) ) ); mask *= step( 0.13, distance( st.xy, vec2(0.75, 0.24) ) ); mask *= step( 0.07, distance( st.xy, vec2(0.5, 0.8) ) ); colour_out = vec4( st.x, st.y, abs(sin(3.0*u_time)), 1.0 ); colour_out *= 1.0-mask; }
Unknown by Ruppy
uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; float sdEllipse(vec2 p, vec2 r) { float d = length(p / r) - 1.0; return d * min(r.x, r.y); } float sdRectangle(vec2 p, vec2 b) { vec2 d = abs(p) - b; return length(max(d, vec2(0.0))) + min(max(d.x, d.y), 0.0); } mat2 rotate2d(float angle) { float s = sin(angle); float c = cos(angle); return mat2(c, -s, s, c); } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; float mask = 1.0; vec2 uv = (gl_FragCoord.xy - 0.5 * u_resolution.xy) / u_resolution.y; float wingBeat = sin(u_time * 3.0) * 0.2; float body = sdRectangle(uv, vec2(0.02, 0.2)); vec2 lfwPos = rotate2d(-0.7 - wingBeat) * (uv - vec2(-0.1, 0.1)); float leftForewing = sdEllipse(lfwPos, vec2(0.25, 0.15)); vec2 rfwPos = rotate2d(0.7 + wingBeat) * (uv - vec2(0.1, 0.1)); float rightForewing = sdEllipse(rfwPos, vec2(0.25, 0.15)); vec2 lhwPos = rotate2d(-1.0 - wingBeat) * (uv - vec2(-0.1, -0.05)); float leftHindwing = sdEllipse(lhwPos, vec2(0.2, 0.12)); vec2 rhwPos = rotate2d(1.0 + wingBeat) * (uv - vec2(0.1, -0.05)); float rightHindwing = sdEllipse(rhwPos, vec2(0.2, 0.12)); mask *= step(0.01, min(body, min(leftForewing, min(rightForewing, min(leftHindwing, rightHindwing))))); colour_out = vec4(st.x, st.y, abs(sin(3.0*u_time)), 1.0); colour_out *= 1.0-mask; }
Flying Butterfly by Anonymous
uniform vec2 u_resolution; uniform float u_time; /* Description: I created a fragment shader using shader.toy. The work I referenced is from: https://www.shadertoy.com/view/sdBSWc */ float position_bad( float t, in float T ) { return smoothstep(0.0,T,t)*t; //return (t<T) ? (t*t*t)/(T*T*T)*(3.0*T-2.0*t) : t; } // Correct integral of EaseInOut/Smoothstep float position_good( float t, in float T ) { if( t>=T ) return t - 0.5*T; float f = t/T; return f*f*f*(T-t*0.5); } // ======================================= vec3 trackMin( in vec3 v, in float d ) { if( d<v.x ) v=vec3(d,v.x,v.y); else if( d<v.y ) v=vec3(v.x,d,v.y); else if( d<v.z ) v=vec3(v.x,v.y,d); return v; } // 色の修正部分を変更しました vec4 butterfly( in vec2 p ) { p.x = abs(p.x); p.y *= 0.9; vec4 col = vec4(0.0); float a = atan(p.x,p.y); float r = length(p); if( p.y<0.0 ) { float f = 0.6 + 0.01*sin( 24.0*a ); float w = 1.1*a-0.8; f *= sin(w)*sin(w); float th = f + 0.001; float th2 = th; // ここで色を黒と青に変更 vec3 wcol = mix( vec3(0.0,0.0,0.0), // 黒 vec3(0.0,0.0,1.0), // 青 smoothstep( 0.0, 0.7, r ) ); wcol *= 1.5; wcol *= 1.0+0.1*sin(17.0*p.x+vec3(0,0,4))*sin(23.0*p.y+vec3(0,0,4)); vec2 q = p; q.xy += 0.02*sin(q.yx*12.0); q.y = min(q.y,0.0); vec3 v = vec3(10); v = trackMin(v,length(q-vec2(0.29,-0.20))); v = trackMin(v,length(q-vec2(0.10,-0.30))); v = trackMin(v,length(q-vec2(0.20,-0.26))); v = trackMin(v,length(q-vec2(0.28,-0.29))); v = trackMin(v,length(q-vec2(0.34,-0.27))); v = trackMin(v,length(q-vec2(0.38,-0.24))); v = trackMin(v,length(q-vec2(0.39,-0.20))); v = trackMin(v,length(q-vec2(0.38,-0.15))); v = trackMin(v,length(q-vec2(0.35,-0.08))); v.yz -= v.x; float g = 1.25*v.y*v.z/max(v.y+v.z,0.001); wcol *= smoothstep(0.0,0.01,g); th -= 0.05*(1.0-smoothstep(0.0,0.05,g))-0.02; wcol *= smoothstep(0.02,0.03,(th-r)*th); q = vec2( mod(a,0.1)-0.05, (r-th+0.025)*3.1415*0.5 ); float d = length( q )-0.015; wcol = mix( wcol, vec3(1,1,1), 1.0-smoothstep( 0.0, 0.005,d) ); wcol *= smoothstep(0.01,0.03,length(p-vec2(0.235,-0.2))); d = r-(th+th2)*0.5; col = vec4(wcol,smoothstep( 0.0,2.0*fwidth(d),-d) ); } if( a<2.2 ) { float f = 0.65 + 0.015*sin( 24.0*a ); float w = a*(3.1416/2.356); float th = f*sin(w)*sin(w) + 0.001; float th2 = th; th += 0.25*exp2( -50.0*(w-1.4)*(w-1.4) ); // ここで色を黒と青に変更 vec3 wcol = mix( vec3(0.0,0.0,0.0), // 黒 vec3(0.0,0.0,1.0), // 青 smoothstep( 0.0, 1.0, r ) ); wcol *= 1.4; wcol *= 1.0+0.1*sin(13.0*p.x+vec3(0,0,4))*sin(19.0*p.y+vec3(0,0,4)); vec3 v = vec3(10); v = trackMin(v,length(p-vec2(0.25,0.2))); v = trackMin(v,length(p-vec2(0.35,0.0))); v = trackMin(v,length(p-vec2(0.4,0.1))); v = trackMin(v,length(p-vec2(0.45,0.2))); v = trackMin(v,length(p-vec2(0.45,0.3))); v.yz -= v.x; float g = 2.0*v.y*v.z/max(v.y+v.z,0.001); wcol *= smoothstep(0.0,0.02,g); th2 -= 0.05*(1.0-smoothstep(0.0,0.05,g)); float isblack = smoothstep(0.02,0.03,(th2-r)*th2); vec2 q = vec2( mod(a,0.1)-0.05, (r-th+0.025)*3.1415*0.5 ); float d = length( q )-0.015; float ww = 1.0-smoothstep( 0.0, 0.01,d); if( r>th2 ) { vec2 q = fract(p*18.0)-0.5; vec2 iq = floor(p*18.0); float id= iq.x*111.0+iq.y*13.0; q += 0.25*sin(id*vec2(15,17)+vec2(0,2)); float r = 1.0+0.75*sin(id*431.0); ww = max( ww, 1.0-smoothstep(0.0,0.01,length(q)-0.2*r)); } wcol = mix( wcol, vec3(ww), 1.0-isblack ); d = r-th; float al = smoothstep( 0.0,2.0*fwidth(d),-d); col.xyz = mix( col.xyz, wcol, al ); col.w = 1.0 - (1.0-col.w)*(1.0-al); } return col; } int hash( ivec2 z ) { int n = z.x+z.y*11111; n = (n<<13)^n; return (n*(n*n*15731+789221)+1376312589)>>16; } // HW_PERFORMANCE の定義(必要に応じて設定) #define HW_PERFORMANCE 1 // 0 または 1 に設定 // HW_PERFORMANCE に基づく条件分岐 #if HW_PERFORMANCE == 0 const int AA = 2; #else const int AA = 4; #endif // 虹色の背景色を生成する関数 vec3 getRainbowBackgroundColor(vec2 fragCoord) { vec2 q = fragCoord / u_resolution.xy; return 0.5 + 0.5 * cos(u_time + q.xyx + vec3(0.0, 2.0, 4.0)) * vec3(1.0, 0.8, 0.6); } void main() { vec2 fragCoord = (gl_FragCoord.xy * 2.0 - u_resolution.xy) / min(u_resolution.x, u_resolution.y); float stime = mod(u_time, 6.0); vec3 col = vec3(0.0); for (int j = 0; j < AA; j++) for (int i = 0; i < AA; i++) { vec2 of = vec2(i, j) / float(AA); vec2 p = (2.0 * (fragCoord + of) - u_resolution.xy) / u_resolution.y; p *= 1.6; float di = float(hash(ivec2(fragCoord) * AA + ivec2(i, j)) & 255) / 255.0; float time = stime + ((float(j * AA + i) + di) / float(AA * AA)) * (0.5 / 30.0) - 0.5 * 0.5 / 30.0; time += 0.07 * sin(p.y); // 一つの蝶々にするためにp.xの条件分岐を削除 float wing = position_good(time, 2.0); // 常に良い方の動きを適用 // 位置の補正を削除 float an = 1.55 * (0.5 - 0.5 * cos(2.0 * 6.283185 * wing)); vec2 pl = vec2(sin(an), -cos(an)); vec3 ro = vec3(0.0, 0.085, 2.1); vec3 rd = vec3(p, -3.0); vec3 pos = ro - rd * dot(ro.xz, pl) / dot(rd.xz, pl); vec2 q = vec2(length(pos.xz), pos.y); vec4 tmp = butterfly(q); tmp = clamp(tmp, 0.0, 1.0); tmp.xyz *= 0.1 + 0.9 * mix(1.0, abs(q.y) * 0.5 + min(q.x * 2.0, 1.0), pl.x * pl.x); tmp.xyz *= clamp(0.25 + 0.75 * (pl.x - pl.y + 1.0), 0.0, 1.0); col += mix(vec3(0.5), tmp.xyz, tmp.w); } col /= float(AA * AA); // 背景を虹色の関数で取得 vec3 bgColor = getRainbowBackgroundColor(fragCoord); bgColor = mix(bgColor, vec3(0.0, 0.0, 0.1), 0.6); // 暗い宇宙背景 col += bgColor * 0.5; // 背景に虹色の輝きを加える colour_out = vec4(col, 1.0); }
Blue Morpho by Taira Kunitomi
uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; float butterfly(vec2 st, float scale) { float t = atan(st.y - 0.5, st.x - 0.5); float r = sin(t) * cos(t) * sin(t); float distance = length(st - vec2(0.5 + r * cos(t), 0.5 + r * sin(t))) - 0.01; float lines = abs(sin(st.x * 0.5 + u_time * 0.8)); float noise = fract(sin(dot(st, vec2(12.9898, 78.233))) * 43758.5453); noise = smoothstep(0.4, 0.6, noise * 2.0); float mask = smoothstep(0.013, 0.015, abs(distance)) * (1.0 - lines * 0.5); mask = mix(mask, mask + noise * 0.03, noise); float littlemask = smoothstep(0.037, 0.047, abs(distance * scale)) * (1.0 - lines * 0.652); littlemask = mix(littlemask, littlemask + noise * 0.03, noise); return mask + littlemask; } float ellipse(vec2 st, vec2 center, vec2 size) { vec2 rotated = vec2(-st.y + center.y, st.x - center.x); vec2 normalized = (rotated - center) / size; float ellipse = smoothstep(0.005, 0.015, 1.0 - dot(normalized, normalized)); float spacing = 0.02; float width = 0.002; float lines = abs(sin(st.y * 30.0)) * step(abs(mod(st.y, spacing)), width); return ellipse * (1.0 - lines); } float whisker(vec2 st) { float y = sin(st.x * 4.800) * -0.572 + 1.108; float curve = step(abs(st.y - y), 0.004); return curve; } void main() { vec2 st = gl_FragCoord.xy / u_resolution.xy; float separation = -0.214; st.x = abs(st.x - 0.484) + 0.652 + separation; float mask = butterfly(st, 0.4); float ellipse = ellipse(st, vec2(-0.210, 0.280), vec2(0.250, 0.430)); mask = max(mask, ellipse); vec3 butterflycolor = vec3(0.130,0.381,1.000); vec3 ellipsecolor = vec3(0.095,0.047,0.054); vec3 finalcolor = mix(butterflycolor, ellipsecolor, ellipse); float whiskermask = whisker(st); finalcolor = mix(finalcolor, vec3(0.010,0.033,0.060), whiskermask); colour_out = vec4(finalcolor, mask); }
Morpho menelaus by Sololemon
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.49, distance( st.xy, vec2(0.99, 0.45) ) ); mask *= step( 0.49, distance( st.xy, vec2(0.01, 0.45) ) ); float mask_2 = 1.0; mask_2 *= step( 0.42, distance( st.xy, vec2(0.2, 0.8) ) ); mask_2 *= step( 0.42, distance( st.xy, vec2(0.8, 0.8) ) ); mask_2 *= step( 0.3, distance( st.xy, vec2(0.3, 0.18) ) ); mask_2 *= step( 0.3, distance( st.xy, vec2(0.7, 0.18) ) ); mask_2 *= step( 0.3, distance( st.xy, vec2(0.5, 0.5) ) ); float mask_3 = 1.0; float ellipseDistance1 = (pow((st.x - 0.15) / 0.2, 2.0) + pow((st.y - 0.01) / 0.01, 2.0)); mask_3 = step(1.0, ellipseDistance1); float mask_4 = 1.0; float ellipseDistance2 = (pow((st.x - 0.85) / 0.2, 2.0) + pow((st.y - 0.01) / 0.01, 2.0)); mask_4 = step(1.0, ellipseDistance2); float mask_5 = 1.0; float ellipseDistance3 = (pow((st.x - 0.49) / 0.005, 2.0) + pow((st.y - 0.57) / 0.2, 2.0)); mask_5 = step(1.0, ellipseDistance3); float mask_6 = 1.0; float ellipseDistance4 = (pow((st.x - 0.51) / 0.005, 2.0) + pow((st.y - 0.57) / 0.2, 2.0)); mask_6 = step(1.0, ellipseDistance4); float a = 0.05; float b = 0.2; vec2 center = vec2(0.5, 0.49); float ellipseDistance = (pow((st.x - 0.5) / a, 2.0) + pow((st.y - 0.49) / b, 2.0)); float mask_1 = step(1.0, ellipseDistance); vec3 blueColor = vec3(0.5, 0.7, 1.0); float gradient = abs(0.9+0.2*sin(u_time)); colour_out = vec4(blueColor * gradient, 1.0); colour_out *= 1.0-mask*mask_1*mask_5*mask_6-mask_2/(mask_3*mask_4); }
Simple Blue Butterfly(Morpho Menelaus) by
GY
uniform vec2 u_resolution; uniform float u_time; vec3 mod289(vec3 x){ return x-floor(x*(1./289.))*289.; } vec2 mod289(vec2 x){ return x-floor(x*(1./289.))*289.; } vec3 permute(vec3 x){ return mod289(((x*34.)+10.)*x); } float snoise(vec2 v){ const vec4 C=vec4(.211324865405187,.366025403784439,-.577350269189626,.024390243902439); vec2 i=floor(v+dot(v,C.yy)); vec2 x0=v-i+dot(i,C.xx); vec2 i1=(x0.x>x0.y)?vec2(1.,0.):vec2(0.,1.); vec4 x12=x0.xyxy+C.xxzz; x12.xy-=i1; i=mod289(i); vec3 p=permute(permute(i.y+vec3(0.,i1.y,1.))+i.x+vec3(0.,i1.x,1.)); vec3 m=max(.5-vec3(dot(x0,x0),dot(x12.xy,x12.xy),dot(x12.zw,x12.zw)),0.); m=m*m; m=m*m; vec3 x=2.*fract(p*C.www)-1.; vec3 h=abs(x)-.5; vec3 ox=floor(x+.5); vec3 a0=x-ox; m*=1.79284291400159-.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.*dot(m,g); } void main(){ vec2 st=(gl_FragCoord.xy/u_resolution)*2.-1.; st.x*=u_resolution.x/u_resolution.y; // Butterfly body parameters float bodyWidth=.04; float bodyHeight=.4; float taper=1.-abs(st.y/bodyHeight)*.4; float adjustedWidth=bodyWidth*taper; float ellipse=pow(st.x/adjustedWidth,2.)+pow(st.y/bodyHeight,2.); float body=smoothstep(0.,.01,1.-ellipse); // Head parameters float headRadius=.04; vec2 headCenter=vec2(0.,.40); float head=smoothstep(0.,.01,headRadius-distance(st,headCenter)); // Wing movement animation using sine wave float wingFlap=sin(u_time*3.)*.05; // Left upper wing vec2 leftWingUpper=st-vec2(-.3+wingFlap,.15); float leftWingUpperShape=smoothstep(.6,0.,pow(leftWingUpper.x*2.5,2.)+pow(leftWingUpper.y*.8,2.)); // Left lower wing vec2 leftWingLower=st-vec2(-.25+wingFlap,-.15); float leftWingLowerShape=smoothstep(.9,0.,pow(leftWingLower.x*2.2,2.)+pow(leftWingLower.y*1.5,2.)); // Right upper wing vec2 rightWingUpper=st-vec2(.3-wingFlap,.15); float rightWingUpperShape=smoothstep(.6,0.,pow(rightWingUpper.x*2.5,2.)+pow(rightWingUpper.y*.8,2.)); // Right lower wing vec2 rightWingLower=st-vec2(.25-wingFlap,-.15); float rightWingLowerShape=smoothstep(.9,0.,pow(rightWingLower.x*2.2,2.)+pow(rightWingLower.y*1.5,2.)); // Wing horn shapes synchronized with wingFlap and inclined outward vec2 leftHorn=st-vec2(-.45+wingFlap*1.2,-.7+wingFlap*.3); leftHorn.x-=leftHorn.y*.1; float leftHornShape=smoothstep(.02,0.,pow(leftHorn.x*6.,2.)+pow(leftHorn.y*4.,4.)); vec2 rightHorn=st-vec2(.45-wingFlap*1.2,-.7+wingFlap*.3); rightHorn.x+=rightHorn.y*.1; float rightHornShape=smoothstep(.02,0.,pow(rightHorn.x*6.,2.)+pow(rightHorn.y*4.,4.)); // Combine wings and horns float leftWing=max(leftWingUpperShape,max(leftWingLowerShape,leftHornShape)); float rightWing=max(rightWingUpperShape,max(rightWingLowerShape,rightHornShape)); // Add noise to wing contours float contourNoise=snoise(st*20.+vec2(u_time)); float wingContour=smoothstep(.15,.2,leftWing+rightWing)*contourNoise; vec3 wingColor=mix(vec3(0.),vec3(.6,0.,.8),smoothstep(0.,.4,length(st))); wingColor=mix(wingColor,vec3(1.,0.,1.),smoothstep(.4,1.,length(st))); vec3 contourColor=mix(vec3(0.),wingColor,wingContour); float butterflyShape=max(body,max(head,max(leftWing,rightWing))); vec3 color=mix(vec3(1.),contourColor,butterflyShape); colour_out = vec4(color,1.); }
Unknown by Anonymous