webgl-form

Construisez une vague héroïque de style Stripe avec Three.js r178 : la feuille pliée de stripe.com, avec son ombrage non éclairé, grande et recadrée par son cadre, chaque partie dérivant sur son propre bruit.

Qu'est-ce que webgl-form ?

Cette compétence permet de générer une vague 3D héroïque inspirée de celle de stripe.com, en utilisant Three.js r178. Elle construit une feuille pliée en deux, épaisse, avec un bord arrondi, et applique l'ombrage non éclairé de Stripe : une palette peinte le long de la feuille, de longues stries soyeuses, un dessous pâle, et un post-traitement avec flou de rotation et grain statique. La vague est toujours grande et recadrée par son cadre, chaque partie se déplaçant indépendamment sur son propre bruit. L'entrée utilisateur ne doit jamais décrire une forme, mais uniquement le sens (ce que fait le produit, les couleurs de la marque, l'emplacement). L'idée modifie la couleur, le recadrage et les réglages, jamais la forme. La compétence est destinée aux développeurs créant des visuels de héros 3D, des vagues Stripe, des rubans shader, ou des modèles WebGL pour des sites ou applications web. Elle fonctionne avec n'importe quel framework, en utilisant un import map pour Three.js, et nécessite de capturer une capture d'écran de référence pour l'étalonnage des couleurs.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Rahuchpred/raha/tree/main/skills/webgl-form

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

WebGL form

La forme est la vague : la feuille pliée de stripe.com, telle que stripe.com la dessine. Le verdict de l'utilisateur après de nombreux essais : « Je n'aime la Vague que parce que c'est vraiment une bonne forme. La Vague est ce que je voulais. » Toute autre forme essayée (anneaux, nœuds, ressorts, un entonnoir enroulé, une feuille emmêlée) a été rejetée. Ainsi, une idée ne devient jamais une nouvelle forme. Elle devient une vague avec ses propres couleurs, recadrage et réglages.

FichierCe que c'est
reference/stripe-three.jsLe moteur. Three.js r178 : la feuille pliée construite dans le vertex shader, les torsions de Stripe sous forme d'une liste de virages, l'ombrage non éclairé de Stripe, la palette peinte, le post-pass, et TAKES / PRESETS avec les cinq vagues fonctionnelles ci-dessous. Copiez-le, puis ajoutez des presets.
reference/stripe-notes.mdLa vague héroïque de stripe.com telle qu'elle est livrée : la géométrie du pli, les shaders, la caméra, et les réglages de ses quatre vagues. Lisez-le avant d'ajuster.
reference/twist-ribbon.js, reference/nib-ribbon.tsD'anciens rubans WebGL2 simples (OpenRouter, OpenEvidence). Uniquement pour les projets qui les utilisent déjà.
reference/ReactMount.tsxMontage React/Next avec fallback.

0. Ce qu'il faut demander

L'invite porte le sens, jamais une forme. Les formes ont été l'échec : chaque forme nommée construite littéralement (un anneau de Möbius, un nœud, un ressort, une tornade) donnait un clip art 3D. Le ruban OpenRouter a fonctionné parce que le sens (« plusieurs modèles entrent, un point de terminaison sort ») est devenu des réglages (où la feuille se tourne sur la tranche), pas un dessin du produit.

Demandez au maximum trois choses, en un seul message :

  1. L'idée, en une phrase : ce que fait le produit, ou la seule chose que l'art doit dire. ("Chaque modèle via un point de terminaison.")
  2. Les couleurs : celles de la marque, ou "les lire depuis le code" (les tokens dans globals.css, un thème Tailwind, les couleurs du logo).
  3. Où il se trouve : une bande héroïque (sous ou autour du texte), une cellule, une carte ; une page claire ou sombre.

Aucune invite du tout est une utilisation valide : lisez les couleurs depuis le code, utilisez le preset wave dans le placement héroïque clair de Stripe, et dites-le en une ligne.

Une forme nommée ("fais une tornade") : ne construisez pas la forme. Interprétez-la comme un indice sur le sens (une tornade : élévation, rotation, force) et mappez-le aux réglages ci-dessous. Dites à l'utilisateur en une ligne que la compétence conserve la vague et pourquoi. S'il insiste toujours, construisez la forme comme une prise supplémentaire à côté des vagues, étiquetée, afin qu'il puisse comparer.

Du sens aux réglages (points de départ, pas des règles) :

L'idée évoqueCommencez parModifiez
Calme, confiance, argent, santédeepRythme 4e-5, palette froide ou neutre-chaude, recadrage large
Plusieurs en un, focus, un point de terminaisonwavePlacez l'étirement sur la tranche (le pincement) sous ou à côté du texte
Énergie, temps réel, vitessepetal ou foldRythme jusqu'à 8e-5, palette chaude
Changement, deux faces, un retournementturnLe retournement montre les deux faces
Rien de spécifiquewavePalette de la marque uniquement

Sortie : deux ou trois prises sur une page de prises, la même famille de vagues dans différents presets, recadrages ou palettes. L'utilisateur en choisit une ; supprimez le reste.

1. La forme

  • La feuille pliée : un plan de 400 x 400 (128 x 256 segments) plié en deux : la couche supérieure, une bande de 32 unités courbée en demi-cylindre (le pli arrondi), la couche inférieure repliée en dessous, espacées de 4 unités aux extrémités et de 2 à mi-longueur. Dressée avec deux quarts de tour : longueur le long de x, épaisseur le long de y, largeur le long de z. Épaisse, avec un bord arrondi, jamais une ligne fine. Construite à partir de l'uv dans le vertex shader (folded(uv)), donc les normales sont exactes.
  • Les trois torsions de Stripe la façonnent : des rotations autour des axes diagonaux (.5, 0, .5) et (0, .5, .5), chacune progressant par le pas doux de Stripe exp2(-exp2(n) * pow(x, n)) le long de la largeur (u) ou de la longueur (v). Dans le moteur : stripeTwists([x, y, z], [powX, powY, powZ]) à partir des nombres de Stripe. La torsion x dérive sur le bruit le long de la longueur : c'est, avec la vague de bruit, tout le mouvement. Des parties bougent ; l'ensemble ne tourne jamais.
  • La vague de bruit : p.y += amount * noise(x * fx + t, z * fz + t).
  • Placement dans le cadre de Stripe : un canevas de 1392 px de large en unités de pixels, une caméra orthographique à (100, 0, 5000) tournée de 0,02 rad autour de y ; chaque nombre est mis à l'échelle par largeur du canevas / 1392. Toujours grand et recadré par son cadre, jamais petit et flottant.
  • Rythme : l'horloge de Stripe, 4e-5 à 8e-5 par milliseconde. Lent exprès.

2. Les cinq vagues qui fonctionnent

Quatre sont les vagues livrées par stripe.com, avec leurs réglages exacts (torsion x, y, z ; puissances ; vague de bruit ; placement ; lueur ; rythme). La cinquième ajoute un tour.

PresetSourceTorsion x, y, z / puissancesVague de bruitRotation ; échelle ; positionLueurRythme, décalage
waveHéroïque clair de Stripe-0,65, 0,41, -0,58 / 3,63, 0,7, 3,950,005831, 0,016001, -7,821-0,4496, -0,1176, 1,8744 ; 9, 8, 5 ; 380, -301,7, -11,11,98, 0,806, 0,8344e-5, 17500
deepHéroïque sombre de Stripe, dessinée sur blanc-0,055, 0,077, -0,518 / 3,95, 5,85, 6,330,003234, 0,00799, 6,051-0,1596, -0,2836, -2,8156 ; 10, 10, 7 ; -24,3, -56,4, -11,10,6, 0,589, 14e-5, 1150
foldHéroïque de facturation de Stripe, tournée pour tenir dans une cellule-0,424, 0,024, -1,312 / 1,81, 0,94, 4,760,005, 0,0212, 6,68-0,666, -0,0314, 1,9 ; 6,05, 8,4, 6,99 ; 50, -100, -11,11,55, 1,174, 0,9725,25e-5, 17500
petalPetite vague d'accentuation de Stripe, agrandie et tournée0,059, 0,32, -0,397 / 3,63, 0,44, 5,990,005831, 0,016001, -7,821-2,8756, 3,0959, -1,6 ; 9, 9, 9 ; 0, -50, -11,13,86, 0,923, 18e-5, 2275
turnL'héroïque clair, complètement retournée (le seul tour ajouté qui fonctionne)celle de l'héroïque clair, plus LENGTH (1, 0, 0) along v, 2pi, drift 0,15celle de l'héroïque claircelle de l'héroïque claircelle de l'héroïque claircelle de l'héroïque clair

Les nombres en gras diffèrent du placement de Stripe lui-même : Stripe a placé ces vagues pour ses propres cadres, donc dans une cellule plus petite, elles étaient recadrées en une zone plate ou flottaient petites. Replacez, ne refaçonnez jamais : pour ajuster à un cadre différent, modifiez uniquement la rotation, l'échelle et la position (data-overrides en HTML).

3. L'ombrage : celui de Stripe, non éclairé

L'héroïque live de stripe.com n'a aucun éclairage ; c'est pourquoi elle a l'air lumineuse et brillante, pas plastique. Sa surface est :

  1. La palette à la (u, v) de la feuille.
  2. De longues et fines stries le long de la longueur : n0 = noise(u * 0.1, v * 0.5), n1 = noise(u * (600 + 300 n0), v * 4 n0) (très fines en travers, presque constantes le long), ajoutées comme n1 * 0.2 à 0.26 * (1 - bleu * 0.9) * pdy * edge, où edge = 1 - pow(4u(1 - u), 3) (plus fortes vers les bords ouverts). Elles ressortent le mieux sur les couleurs chaudes ; pour une palette tout bleu, réduisez la décoloration bleue à environ 0,4.
  3. Le terme de lueur pdy : dFdy(v) * resolution.y * amount, mappé de -1..1 à 0..1, élevé à une puissance, lissé par la rampe. Son signe distingue les deux faces de la feuille ; près de zéro, la feuille se plie.
  4. Contraste, saturation, teinte, puis + (1 - pdy) * 0.25 : l'autre face et le pli deviennent pâles. C'est la bande crémeuse au pli de Stripe.
  5. Opaque, testé en profondeur. Post-pass : un flou de rotation de 0,02 rad maintenu hors d'une bande nette au milieu, puis du grain (1,1) là où il y a de la couleur. Le grain est le tramage statique de Stripe : color + mix(1, -1, random(gl_FragCoord.xy * 0.01)) * 4/255 * amount. Il ne change jamais d'une image à l'autre. Un grain ré-aléatoire à chaque image scintille et est perçu comme du bruit ("trop de bruit par rapport à Stripe"), et dans une vidéo, il gonfle aussi le fichier plusieurs fois.

Pas de lignes dessinées, pas de lumières mobiles, pas d'éclairage normal, pas de surbrillance de pli : l'ancien ombrage éclairé du moteur est conservé uniquement comme option (shading: "lit") et n'est pas la valeur par défaut.

4. La palette

Peignez-la comme Stripe le fait, pas comme des taches aléatoires (les taches aléatoires donnaient une couleur unique et plate sur la majeure partie de la feuille visible) :

  • Le long de la longueur (v), le dégradé principal. L'héroïque clair : bleu lavande #9fb6ff, violet #a978ff, magenta #e05cff, rose vif #ff4fa8, orange #ff7a2a, ambre #ffa318.
  • À travers la largeur (u), une teinte vers les bords ouverts (environ 75 %, s'estompant à partir de u = 0,22 de chaque côté) : lavande #a9b6ff pour l'héroïque clair.
  • Quelques taches faibles (14, à 25 %) uniquement pour varier.
  • Le palette(along, edge, blobs) du moteur construit cela. Autres ensembles fonctionnant : océan (bleu à cyan), crépuscule (orange, rose, violet), citron vert (sarcelle, vert, jaune, orange), braise (rose, rouge, orange, jaune).
  • La couleur est celle de la marque, ou de style Stripe. Décorative, jamais des données.

5. Placement dans la page

Copier par-dessus la vague (le chevauchement de Stripe)

Mesuré sur stripe.com, 2026-10-22. Quand la vague passe sous le titre, Stripe ne la masque pas et ne laisse pas la vague couvrir les mots. Il dessine le texte deux fois :

  1. Sous le canevas : le texte dans ses couleurs normales (Stripe : titre navy #061b31, corps gris). Là où la vague passe dessus, la vague le cache.
  2. Au-dessus du canevas (z-index au-dessus de la couche de la vague) : un texte identique, même taille et position, aria-hidden, avec mix-blend-mode: hard-light et des couleurs teintées transparentes (Stripe : titre rgb(45, 37, 100), un violet profond ; corps rgba(0, 14, 255, 0.5), un bleu semi-transparent). Sur la page blanche, il se lit comme le texte normal ; sur la vague, les lettres prennent les couleurs de la vague, donc elles restent lisibles et semblent imprimées sur la soie.

Règles :

  • Choisissez les teintes du texte supérieur à partir de la marque : une version profonde et saturée de la couleur du titre, et un bleu de marque semi-transparent (ou accent) pour le corps. Vérifiez une capture d'écran là où la vague est la plus lumineuse : chaque mot reste lisible.

  • Les deux textes doivent correspondre exactement (mêmes styles d'éléments, même habillage) : construisez-les à partir d'une seule source et empilez-les dans une seule cellule de grille (grid-area: 1 / 1), de sorte qu'un changement de police ou de largeur les déplace tous les deux.

  • Les lecteurs d'écran obtiennent uniquement le texte inférieur ; le texte supérieur est aria-hidden et ne prend aucun événement de pointeur. Les boutons et les liens restent dans la couche inférieure et ne sont jamais couverts par le canevas (gardez-les hors du chemin de la vague, ou soulevez uniquement les boutons au-dessus).

  • La réduction de mouvement et le fallback d'image fixe conservent les deux textes ; le mélange fonctionne aussi sur l'image fixe.

  • Ne faites jamais dévier le texte de la vague avec une plaque blanche ou un masque : c'est l'aspect que la double copie existe pour éviter.

  • La vague remplit ou recadre sa cellule ou sa bande héroïque. Les légendes reposent sur une petite pastille de la couleur de la page.

  • Jamais sous la navigation ou dans la section suivante. Là où une vague recadrée rencontre le haut d'une bande, fondez-la avec un masque CSS ; là où elle rencontre du texte, utilisez la double copie ci-dessus.

  • Pas d'étiquettes, de chiffres ou de lignes de quadrillage à l'intérieur de l'art.

6. Règles d'ingénierie

  • Three.js r178 installé dans le projet, chargé avec une import map ("three": "/node_modules/three/build/three.module.js").
  • THREE.ColorManagement.enabled = false ; palette NoColorSpace ; ShaderMaterial en style GLSL1.
  • failIfMajorPerformanceCaveat: true ; en cas d'échec, une image fixe de la même vague. Surveillez les temps d'image : supprimez le post-pass, puis le DPR, puis arrêtez-vous sur une image fixe.
  • DPR plafonné à 2 ; ResizeObserver ; pause hors écran et dans les onglets cachés ; la réduction de mouvement dessine une image figée. Aucune réactivité au pointeur.
  • Jusqu'à environ 13 vagues sur une page ; au-delà de 16, le navigateur abandonne les contextes.
  • Ne nommez jamais une variable GLSL step, mix ou fract.

7. Flux de travail

  1. Obtenez l'entrée (section 0) : l'idée, les couleurs, le lieu. Pas d'invite : couleurs du code, le preset wave. Mappez l'idée à un preset, un recadrage et une palette ; jamais à une nouvelle forme.
  2. Comparez avec la réalité : faites une capture d'écran de l'héroïque de stripe.com en 1440x900, rendez la nôtre dans un canevas au cadre exact de Stripe (1392 x 761 à x 337), et comparez les deux au même recadrage. La texture et la couleur sont jugées de cette façon, pas de mémoire.
  3. Pour une page de plusieurs vagues, utilisez les presets ci-dessus, replacés pour correspondre à chaque cadre ; montrez les alternatives sur une page de prises.
  4. Vérifiez en taille réelle (Chrome headless) : console propre et chaque canevas construit ; 1440 et 375 ; deux images à quatre secondes d'intervalle comparées par quart (changement inégal : parties en mouvement ; changement égal : une rotation) ; la vague remplit son cadre.
  5. Commitez avec un message qui dit ce qui a changé pour l'œil.

Rejeté, ne répétez pas

  • Prendre une forme nommée au pied de la lettre. Une invite comme "fais une tornade" est un indice sur le sens, pas sur la géométrie.
  • Toute forme autre que la vague. Anneaux, nœuds, ressorts et tubes balayés le long d'un chemin ("les autres n'ont pas l'air vraiment cool"), et la feuille pliée poussée dans d'autres formes par des torsions fortes : un entonnoir enroulé, une bobine enroulée, un enchevêtrement ("l'enchevêtrement, la bobine et l'entonnoir sont vraiment mauvais"). Seul le doux retournement (turn) a été accepté, comme "peut-être acceptable".
  • Des feuilles éclairées et ombrées : elles semblent plastiques à côté de la surface non éclairée de Stripe.
  • Une palette de taches aléatoires : une couleur unie remplit la feuille visible.
  • Une feuille monocouche : "on voit les côtés fins".
  • L'objet entier qui tourne : "l'ensemble a bougé, pas certaines parties".
  • Des lignes de lumière mobiles : "c'était juste un truc OpenRouter, ici nous imitons Stripe".
  • Une petite vague flottant au milieu de son cadre.
  • Un mélange alpha ordinaire sur tout ce qui est transparent : des coutures.
  • Des lignes dessinées, des diagrammes nœuds-et-fils, des lignes de quadrillage, des étiquettes...

Skills associés