Untitled Shader
By Hiyoko
Image
precision mediump float;
uniform float uAspect;
uniform float uDeltaTime;
uniform float uFrameRate;
uniform float uTime;
uniform int uFrameCount;
uniform vec2 uResolution;
uniform vec3 uMouse;
uniform vec4 uDate;
// Metaball avec adoucissement
float metaball(vec2 p, vec2 center, float radius) {
float d = length(p - center);
return (radius * radius) / (d * d + 0.001);
}
// Déformation élastique type gelée / slime
vec2 jellyDistort(vec2 p, float t) {
p += vec2(
sin(p.y * 7.0 + t * 2.5) * 0.07 + sin(p.y * 14.0 - t * 3.5) * 0.025,
cos(p.x * 7.0 + t * 2.2) * 0.07 + cos(p.x * 13.0 - t * 3.0) * 0.025
);
return p;
}
// Évaluation du champ global de gelée
float getJellyField(vec2 p, vec2 mouse, float t) {
vec2 jp = jellyDistort(p, t);
// Mouvements flottants et élastiques des blobs
vec2 p1 = vec2(sin(t * 0.8) * 0.45, mod(t * 0.35, 2.4) - 1.2);
vec2 p2 = vec2(cos(t * 0.6 + 1.2) * 0.55, mod(t * 0.28 + 0.8, 2.4) - 1.2);
vec2 p3 = vec2(sin(t * 1.1 + 2.5) * 0.4, mod(t * 0.42 + 1.6, 2.4) - 1.2);
vec2 p4 = vec2(cos(t * 0.5 + 3.8) * 0.6, mod(t * 0.22 + 0.4, 2.4) - 1.2);
float f = 0.0;
f += metaball(jp, p1, 0.34);
f += metaball(jp, p2, 0.38);
f += metaball(jp, p3, 0.28);
f += metaball(jp, p4, 0.42);
f += metaball(jp, mouse, 0.35); // Slime contrôlé au curseur
return f;
}
// Palette de teintes acidulées
vec3 jellyPalette(float t) {
vec3 a = vec3(0.5, 0.5, 0.5);
vec3 b = vec3(0.5, 0.5, 0.5);
vec3 c = vec3(1.0, 1.0, 1.0);
vec3 d = vec3(0.1, 0.45, 0.75);
return a + b * cos(6.28318 * (c * t + d));
}
void main() {
vec2 uv = (gl_FragCoord.xy * 2.0 - uResolution.xy) / min(uResolution.x, uResolution.y);
vec2 mouse = (uMouse.xy * 2.0 - uResolution.xy) / min(uResolution.x, uResolution.y);
float t = uTime * 1.6;
float f = getJellyField(uv, mouse, t);
// Découpage organique du blob
float mask = smoothstep(0.95, 1.05, f);
// Calcul du relief pour l'effet volume 3D bien rebondi
float eps = 0.012;
float fx = getJellyField(uv + vec2(eps, 0.0), mouse, t) - getJellyField(uv - vec2(eps, 0.0), mouse, t);
float fy = getJellyField(uv + vec2(0.0, eps), mouse, t) - getJellyField(uv - vec2(0.0, eps), mouse, t);
// Normale de surface (comme une bulle de savon épaisse ou du silicone)
vec3 normal = normalize(vec3(fx, fy, 0.65));
// Lumières : une principale en haut à gauche et un contre-jour doux
vec3 lightDir1 = normalize(vec3(-0.6, 0.8, 1.0));
vec3 lightDir2 = normalize(vec3(0.6, -0.6, 0.5));
// Reflet Spéculaire 1 : gros spot blanc wet / glossy
float spec1 = pow(max(dot(normal, lightDir1), 0.0), 16.0);
// Reflet Spéculaire 2 : point ultra net très brillant
float spec2 = pow(max(dot(normal, lightDir1), 0.0), 64.0) * 1.5;
// Reflet secondaire plus doux
float rimLight = pow(1.0 - max(normal.z, 0.0), 2.5);
// Cycle des couleurs bonbon / yaourt
float colorShift = uTime * 0.14;
vec3 bodyCol = jellyPalette(colorShift);
vec3 deepCol = jellyPalette(colorShift + 0.2) * 0.45; // Cœur plus dense et sombre
vec3 rimCol = jellyPalette(colorShift - 0.1) * 1.3; // Bords translucides éclatants
// Dégradé de volume interne (effet matière gélifiée)
vec3 jellyMat = mix(deepCol, bodyCol, clamp((f - 0.9) * 0.7, 0.0, 1.0));
// Ajout de la brillance translucide sur les côtés (Fresnel)
jellyMat = mix(jellyMat, rimCol, rimLight * 0.6);
// Ajout des reflets brillants blancs (aspect humide / glacé)
jellyMat += vec3(1.0) * (spec1 * 0.6 + spec2 * 0.8);
// Fond sombre style cuve
vec3 bg = vec3(0.04, 0.03, 0.06);
// Halo élastique autour des blobs
vec3 glow = bodyCol * smoothstep(0.65, 1.0, f) * (1.0 - mask) * 0.5;
vec3 finalColor = mix(bg, jellyMat, mask) + glow;
gl_FragColor = vec4(finalColor, 1.0);
}