Surface métallique liquide en WebGL : bruit simplex FBM 4 octaves, normales par différences finies, éclairage diffus-spéculaire et iridescence, 3 palettes.
WebGLShaderMetal
Survolez ou cliquez la scène pour interagir
Cet effet est gratuit — la catégorie Atmosphère en contient 57 au total, dont 10 gratuits. Effect.Labs regroupe 811 effets vanilla. Découvrir la catégorie →
QuandEn fond de section hero sur une landing B2B ou SaaS voulant signaler « technologie de pointe » sans image ni vidéo externe.
PourquoiLe shader silver animé remplace une vidéo HD : 0 requête réseau, ~1,5 Ko de JS, rendu 100 % GPU. Il retient l'attention sans distraire du CTA principal.
Réglagessettings.color = 'silver' (défaut), settings.speed = 0.7 pour un mouvement lent et premium, settings.lightAngle = 30 pour une lumière rasante dramatique.
Pro
49 €
/ mois
Effets illimités
Support prioritaire
Accès API
② Composant produit — Carte offre Pro / pricing premium
QuandEn fond de la carte « Plan Pro » ou d'une tuile produit haut de gamme, pour la distinguer visuellement des offres standard.
PourquoiLa palette gold transforme un arrière-plan statique doré en surface vivante et renforce la perception de valeur sans asset externe.
③ Fond plein-écran — Héro d'une marque horlogère ou tech luxe
QuandEn fond de section héro ou de page produit pour une marque positionnée sur le luxe, la précision ou la matière — horlogerie, audio haute-fidélité, carte bancaire métal, produit physique premium.
PourquoiLa surface métallique animée incarne le matériau de la marque : le métal liquide couvre 100 % du cadre, sans élément UI qui réduise son impact. C'est l'effet lui-même qui est le fond, pas une décoration superposée.
Réglagessettings.color = 'gold' pour une dominante chaude et précieuse, settings.speed = 0.5 (mouvement imperceptiblement lent), settings.distortion = 0.7 (ondulations visibles), settings.lightAngle = 20 pour une lumière rasante qui sculpte chaque relief.
Comment ça marche
Un quad plein-écran en WebGL 1 pilote l'effet. À l'initialisation, deux shaders GLSL (vertex minimal + fragment) sont compilés et liés ; un Float32Array de 4 sommets (−1/+1) forme le triangle-strip qui couvre tout le canvas. Les uniforms u_res et u_time sont mis à jour à chaque frame par requestAnimationFrame. Le canvas est dimensionné au vrai DPR physique (devicePixelRatio, plafonné à 2) via gl.viewport, et un écouteur resize le recalibre dynamiquement.
La surface est entièrement générée dans le fragment shader par du bruit simplex 2D classique (Ashima Arts, licence MIT). Une fonction FBM (fractal brownian motion) enchaîne 4 octaves : chaque octave double la fréquence spatiale et divise l'amplitude par deux, accumulant un champ de hauteur h = fbm(uv × 2 + vec2(t, t×0,7)). u_distortion module l'amplitude globale (0,6 par défaut), u_speed la vitesse de défilement temporel.
Le vecteur normal de surface est estimé par différences finies : deux échantillons FBM décalés de ε = 0,01 en x et y reconstruisent normal = normalize(vec3(Δh/Δx, Δh/Δy, 1)). La composante diffuse (produit scalaire normal × lightDir) et un spéculaire de puissance 32 (modèle Phong) sont mélangés avec un facteur d'iridescence — 0,5 + 0,5 × sin(h×8 + t×2) — pour interpoler les trois stops de couleur de la palette active. Un vignettage radial (1 − 0,4 × |uv|) assombrit les bords. Un IntersectionObserver suspend le rendu quand le canvas sort du viewport.
Accessibilité
prefers-reduced-motion : réduit → initMetal() retourne immédiatement ; le canvas reste vide et aucune boucle ne tourne. Le commentaire du shader mentionne un « fallback CSS gradient via @media » mais aucune règle @media (prefers-reduced-motion) n'est définie dans le CSS livré : à ajouter selon votre contexte.
Le canvas fourni dans le HTML n'a ni aria-hidden ni role : ajoutez aria-hidden="true" si l'effet est purement décoratif, ou enveloppez-le dans un role="img" aria-label="Surface métallique animée" s'il est porteur de sens.
L'effet est purement passif (aucune interaction pointeur ou clavier) — aucune gestion de focus n'est requise.
Fallback WebGL : si WebGL n'est pas disponible, le canvas est masqué (style.display = 'none') sans message alternatif — le contenu texte superposé reste visible.
Compatibilité navigateur
Nécessite WebGL 1 (aucune extension optionnelle) — présent dans tous les navigateurs modernes depuis 2015. Zéro dépendance externe.
Chrome 56+✓ Complet
Firefox 51+✓ Complet
Safari 15+✓ Complet
Edge 79+✓ Complet
Mobile iOS✓ WebGL OK
Android Chrome✓ Complet
Sans WebGL, le canvas est masqué silencieusement (display:none) — aucune erreur JS fatale. Le contenu texte ou UI superposé reste intégralement visible.
Le code
Copiez les trois blocs dans votre page. Aucune dépendance.
Direction de la lumière en degrés (passé à radians() dans le shader). 0 = rasante horizontale ; 90 = zénithale ; 180 = contre-jour.
PALETTES (objet JS)
3 presets
Ajoutez une palette custom : PALETTES.copper = { a:[0.25,0.10,0.03], b:[0.80,0.45,0.20], c:[0.60,0.28,0.10] }, puis settings.color = 'copper'. Valeurs en linéaire [0,1] par canal.
Octaves FBM (ligne shader)
4
Dans le FS, la boucle for (int i=0;i<4;i++) — changer 4 par 2 (plus rapide, texture grossière) ou 6 (détail fin, GPU légèrement plus sollicité).
FAQ
La description parle de « Perlin » mais le code dit « simplex » — quelle est la différence ?
Le fragment shader implémente le bruit simplex 2D de Ken Perlin (variante Ashima Arts, MIT), pas le bruit de Perlin classique à grille carrée. Le simplex utilise une grille triangulaire : il élimine les artefacts directionnels des axes et est environ 2× moins coûteux en 2D. La carte catégorie emploie « Perlin » comme raccourci courant.
L'effet fonctionne-t-il sur GPU intégré (Intel Iris, Apple M-series) ?
Oui. Le shader est volontairement léger : highp float, 4 octaves FBM, un seul draw call, pas d'extension GL. Il tient 60 fps confortablement sur GPU intégré. L'IntersectionObserver suspend le rendu hors viewport pour ne pas consommer de ressources inutilement.
Peut-on animer <code>lightAngle</code> en temps réel pour un effet de rotation de lumière ?
settings.lightAngle est lu à chaque frame dans la boucle render. Un simple RAF externe qui fait settings.lightAngle += 0.3 produit une rotation continue de la lumière. Combiné à settings.color = 'gold', ça simule un métal doré qui tourne sous un projecteur.