学生作品選集
2024年度授業「コンピュータグラフィックス特論」の生徒作品を紹介します。一つのフラグメントシェーダーを使って蘭の花の画像を生成Aすることが目的でした。もし興味あったら宿題の説明をご覧ください。
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
その他の学生作品
2024年の学生作品の残りは以下の通りです。なお、一部の作品は非常に計算量が多いため、お使いのブラウザで問題が発生する可能性があります。 全学生の作品を表示
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