Communityコーディング&開発github.com

WebGL フォーム

Three.js r178 で Stripe スタイルのヒーローウェーブを構築します。stripe.com 独自の折り畳まれたシート、折り目が丸く厚みのある平面を、Stripe の設定と無光源シェーディングで描画。フレームで切り抜かれ、各部分が個別のノイズで漂います。

WebGL フォーム とは?

このスキルは、Stripe のヒーローページに見られる特徴的なウェーブ形状を Three.js で再現するためのものです。シート状の平面を頂点シェーダーで折り畳み、丸みを帯びた厚みを持たせ、Stripe 独自の無光源シェーディング(パレットによる塗り分け、長く細かい光条、淡い下面)を適用します。ユーザーが「3Dヒーロービジュアル」「Stripe ウェーブ」「シェーダーリボン」「WebGLモデル」などを要求した際に使用します。 スキルの核心は「形状は変えず、色・切り抜き・設定のみを変える」点にあります。ユーザーのプロンプトは意味(製品の説明、ブランドカラー、配置)のみを伝え、具体的な形状(トルネードやリングなど)を指定しても形状には反映されません。意味から適切なプリセット(wave, deep, fold, petal, turn)を選択し、色とトリミングを調整します。 対応プラットフォームは Three.js r178 で、import map を用いてプロジェクトに導入します。パフォーマンスに関しては、DPR 上限 2、オフスクリーン時の一時停止、モーション抑制対応などを含みます。ページ全体のレイアウトとしては、テキストの上にウェーブを重ねる「二重コピー」手法を用い、視認性を保ちながら Stripe らしい質感を実現します。

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

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

WebGL フォーム は何をしますか?

フォームとは ウェーブ のことです:stripe.com が描くように折り畳まれたシートです。 多くの試行錯誤の末のユーザーの評価は「ウェーブだけが好き。本当に良いフォームだから。これが欲しかった。」というものでした。他のすべてのフォーム(リング、結び目、スプリング、渦巻き漏斗、絡まったシート)は却下されました。したがって、アイデアが新しい形状になることはありません。アイデアは独自の色、切り抜き、設定を持つウェーブになります。

ファイル説明
reference/stripe-three.jsエンジン。 Three.js r178:頂点シェーダーで構築された折り畳みシート、Stripe のひねりをターンのリストとして表現、Stripe の無光源シェーディング、塗り分けパレット、ポストパス、および以下の 5 つの動作するウェーブを含む TAKES / PRESETS。コピーしてプリセットを追加してください。
reference/stripe-notes.mdstripe.com のヒーローウェーブそのまま:折り畳みジオメトリ、シェーダー、カメラ、および 4 つすべてのウェーブの設定。チューニング前に読んでください。
reference/twist-ribbon.js、reference/nib-ribbon.ts古いプレーンな WebGL2 リボン(OpenRouter、OpenEvidence)。すでにそれらを実行しているプロジェクトのみ対象。
reference/ReactMount.tsxReact/Next マウント(フォールバック付き)。

0. 何を尋ねるか

プロンプトは 意味 を伝え、形状は決して伝えません。形状は失敗の原因でした。文字通りに構築された名前付きのフォーム(メビウスの輪、結び目、スプリング、トルネード)はすべて 3D クリップアートになりました。OpenRouter のリボンが機能したのは、その意味(「多数のモデルを1つのエンドポイントに」)が設定(シートがエッジオンになる場所)になったからであり、製品を描画したからではありません。

最大3つのことだけを、1つのメッセージで尋ねてください:

  1. アイデア:製品が何をするか、またはアートが伝えるべき1つのことを一文で。(「すべてのモデルを1つのエンドポイントに。」)
  2. 色:ブランドの色、または「コードから読み取ってください」(globals.css のトークン、Tailwind テーマ、ロゴの色)。
  3. 配置場所:ヒーローバンド(コピーの下または周囲)、セル、カード;明るいページまたは暗いページ。

プロンプトがまったくない場合 も有効な使用法です:コードから色を読み取り、wave プリセットを Stripe のライトヒーロー配置で使用し、その旨を1行で伝えてください。

名前付きの形状(「トルネードを作って」):形状を構築しないでください。それを意味(トルネード:上昇、回転、力)に関するヒントとして読み取り、以下の設定にマッピングしてください。スキルがウェーブを維持する理由を1行でユーザーに伝えてください。それでもユーザーが主張する場合は、ウェーブとは別のテイクとして形状を構築し、ラベルを付けて比較できるようにしてください。

意味から設定へ(開始点であり、ルールではありません):

アイデアの雰囲気開始点変更点
穏やか、信頼、お金、健康deepペース 4e-5、寒色系または暖色系ニュートラルパレット、広いトリミング
多を一つに、集中、エンドポイントwaveエッジオンのストレッチ(ピンチ)をコピーの下または横に配置
エネルギー、リアルタイム、速度petal または foldペースを 8e-5 まで上げる、暖色系パレット
変化、二面性、転換turnロールオーバーで両面が見える
特に指定なしwaveブランドパレットのみ

出力: 2 つまたは 3 つのテイクを含むテイクページ。同じウェーブファミリーの異なるプリセット、トリミング、またはパレット。ユーザーが1つを選び、残りは削除します。

1. フォーム

  • 折り畳まれたシート:400 x 400 の平面(128 x 256 セグメント)を半分に折ります:上部レイヤーは 32 ユニットのストリップが半円筒状に曲げられ(丸みを帯びた折り目)、下部レイヤーはその下に折り畳まれ、端で 4 ユニット、中間で 2 ユニットの間隔があります。2 つの 1/4 ターンで立てられます:長さは x 軸方向、厚さは y 軸方向、幅は z 軸方向。厚く、角は丸く、決してヘアライン状ではありません。頂点シェーダーで UV から構築されるため(folded(uv))、法線は正確です。
  • Stripe の 3 つのひねり が形状を決定します:対角軸 (.5, 0, .5) と (0, .5, .5) を中心とした回転。それぞれが Stripe のソフトステップ exp2(-exp2(n) * pow(x, n)) によって幅 (u) または長さ (v) に沿ってランプされます。エンジン内では stripeTwists([x, y, z], [powX, powY, powZ]) として Stripe の数値で表現されます。x のひねりは長さに沿ってノイズ上をドリフトします。これとノイズウェーブがすべての動きです。パーツは動きますが、全体が回転することはありません。
  • ノイズウェーブ:p.y += amount * noise(x * fx + t, z * fz + t)。
  • Stripe のフレーム内での 配置:ピクセル単位の 1392px 幅のキャンバス、(100, 0, 5000) にある正投影カメラを y 軸周りに 0.02 rad 回転。すべての数値は キャンバス幅 / 1392 でスケーリングされます。常に大きく、フレームで切り抜かれ、小さく浮遊することはありません。
  • ペース:Stripe のクロック、ミリ秒あたり 4e-5 ~ 8e-5。意図的に遅く。

2. 動作する5つのウェーブ

4 つは stripe.com が配信しているウェーブで、その正確な設定(ひねり x, y, z;パワー;ノイズウェーブ;配置;グロー;ペース)を持ちます。5 つ目は 1 つのターンを追加したものです。

プリセットソースひねり x, y, z / パワーノイズウェーブ回転;スケール;位置グローペース、オフセット
waveStripe のライトヒーロー-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
deepStripe のダークヒーロー、白地に描画-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
foldStripe の請求ヒーロー、セルに収まるように回転-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
petalStripe の小さなアクセントウェーブ、拡大・回転0.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
turnライトヒーローを完全にロールオーバー(機能した唯一の追加ターン)ライトヒーローのものに加えて、v に沿って LENGTH (1, 0, 0)、2pi、ドリフト 0.15ライトヒーローのものライトヒーローのものライトヒーローのものライトヒーローのもの

太字の数値は Stripe の独自配置とは異なります:Stripe はそれらのウェーブを自社のフレーム用に配置したため、より小さなセルでは平坦な部分にトリミングされたり、小さく浮遊したりしました。再配置し、形状は変えないでください:異なるフレームに合わせるには、回転、スケール、位置のみを変更します(HTML の data-overrides)。

3. シェーディング:Stripe 独自の無光源

実際の stripe.com のヒーローには光源がまったくありません。そのため、プラスチックのように見えず、明るく輝いて見えます。その表面は:

  1. パレット がシートの (u, v) に適用されます。
  2. 長く細かい光条 が長さ方向に沿って:n0 = noise(u * 0.1, v * 0.5)、n1 = noise(u * (600 + 300 n0), v * 4 n0)(非常に細かく、ほぼ一定)。n1 * 0.2 ~ 0.26 * (1 - blue * 0.9) * pdy * edge として加算。ここで edge = 1 - pow(4u(1 - u), 3)(開いた端に向かって最も強い)。暖色系で最もよく見えます。全面青のパレットの場合は青のフェードを約 0.4 に下げてください。
  3. グロー項 pdy:dFdy(v) * resolution.y * amount。範囲 -1..1 から 0..1 にマッピングし、べき乗し、ランプでスムーズステップします。その符号はシートの 2 つの面を区別します。ゼロに近い場合、シートは折り曲げられています。
  4. コントラスト、彩度、色相、次に + (1 - pdy) * 0.25:反対側の面と折り目は淡くなります。これが Stripe の折り目にあるクリーミーな帯です。
  5. 不透明、深度テストあり。ポストパス:0.02 rad の回転ブラー(中央の鋭い帯を避けて適用)、次にグレイン(1.1)(色がある場所)。グレインは Stripe の静的ディザです:color + mix(1, -1, random(gl_FragCoord.xy * 0.01)) * 4/255 * amount。フレームごとに変化することはありません。毎フレーム再ランダム化されるグレインはきらめき、ノイズとして認識され(「Stripe と比較してノイズが多すぎる」)、動画ではファイルサイズが数倍に膨れ上がります。

描画線、移動するライト、法線光源、折り目ハイライトはありません:エンジンの古い光源ありシェーディングはオプション(shading: "lit")としてのみ保持され、デフォルトではありません。

4. パレット

Stripe の動作方法でペイントします。ランダムなブロッチではありません(ランダムなブロッチでは、可視シートの大部分が1つの平坦な色になりました):

  • 長さ方向 (v) に沿って、メイングラデーション。ライトヒーロー:ラベンダーブルー #9fb6ff、バイオレット #a978ff、マゼンタ #e05cff、ホットピンク #ff4fa8、オレンジ #ff7a2a、アンバー #ffa318。
  • 幅方向 (u) に沿って、開いた端に向かってティント(約 75%、両側から u = 0.22 でフェードアウト):ライトヒーローではラベンダー #a9b6ff。
  • いくつかの淡いブロッチ(14 個、25%)がバリエーションのためにのみ追加されます。
  • エンジンの palette(along, edge, blobs) がこれを構築します。他の動作するセット:オーシャン(青~シアン)、ダスク(オレンジ、ピンク、バイオレット)、ライム(ティール、緑、黄、オレンジ)、エンバー(ピンク、赤、オレンジ、黄)。
  • 色はブランドのもの、または Stripe 風です。装飾的であり、データではありません。

5. ページ内の配置

ウェーブの上にコピーを重ねる(Stripe の重なり)

2026-10-22 に stripe.com で測定。ウェーブが見出しの下で動作する場合、Stripe はそれをマスクで隠したり、単語を覆わせたりしません。コピーを 2 回 描画します:

  1. キャンバスの下:通常の色のコピー(Stripe:見出しはネイビー #061b31、本文はグレー)。ウェーブがその上を通過すると、ウェーブがそれを隠します。
  2. キャンバスの上(z-index でウェーブのレイヤーの上):同一のコピー、同じサイズと位置、aria-hidden、mix-blend-mode: hard-light と半透明の着色(Stripe:見出し rgb(45, 37, 100)(深いバイオレット)、本文 rgba(0, 14, 255, 0.5)(半透明の青))。白いページの上では通常のテキストとして読めます。ウェーブの上では文字がウェーブの色を帯びるため、読みやすく、シルクに印刷されたように見えます。

ルール:

  • 上部のコピーの色合いはブランドから選びます:見出し色の深く彩度の高いバージョンと、本文用の半透明のブランドブルー(またはアクセントカラー)。ウェーブが最も明るい場所のスクリーンショットで確認し、すべての単語が読みやすいことを確認してください。

  • 2 つのコピーは完全に一致している必要があります(同じ要素スタイル、同じラップ):1 つのソースから構築し、1 つのグリッドセル(grid-area: 1 / 1)に重ねて配置します。これにより、フォントや幅の変更が両方に適用されます。

  • スクリーンリーダーは下部のコピーのみを取得します。上部のコピーは aria-hidden であり、ポインターイベントを受け取りません。ボタンとリンクは下部レイヤーに残り、キャンバスで覆われることはありません(ウェーブのパスから外すか、ボタンのみを上に持ち上げてください)。

  • モーション抑制と静止画フォールバックでも両方のコピーが保持されます。ブレンドは静止画の上でも機能します。

  • 白いプレートやマスクでコピーをウェーブから逃がさないでください。二重コピーが存在するのはその外観を避けるためです。

  • ウェーブはセルまたはヒーローバンドを埋めるか、トリミングします。キャプションはページカラーの小さなチップの上に配置します。

  • ナビゲーションの下や次のセクションには決して配置しません。トリミングされたウェーブがバンドの上部に接する場合は、CSS マスクでフェードアウトします。コピーに接する場合は、上記の二重コピーを使用します。

  • アート内にラベル、数字、グリッド線は配置しません。

6. エンジニアリングルール

  • Three.js r178 をプロジェクトにインストールし、import map("three": "/node_modules/three/build/three.module.js")で読み込みます。
  • THREE.ColorManagement.enabled = false;パレットは NoColorSpace;ShaderMaterial は GLSL1 スタイル。
  • failIfMajorPerformanceCaveat: true;失敗した場合は同じウェーブの静止画像。フレームタイムを監視:ポストパスを削除し、次に DPR を下げ、それでもダメなら静止フレームで停止。
  • DPR 上限 2;ResizeObserver;オフスクリーン時と非表示タブでは一時停止;モーション抑制設定の場合は1つの静止フレームを描画。ポインターの応答性はなし。
  • 1 ページあたり最大約 13 ウェーブ。16 を超えるとブラウザがコンテキストをドロップします。
  • GLSL 変数に step、mix、fract という名前を決して付けないでください。

7. ワークフロー

  1. 入力(セクション 0)を取得:アイデア、色、場所。プロンプトがない場合:コードから色を、wave プリセットを使用。アイデアをプリセット、トリミング、パレットにマッピングします。新しい形状には決してマッピングしません。
  2. 実物と比較:1440x900 で stripe.com のヒーローをスクリーンショットし、Stripe の正確なフレーム(1392 x 761、x 337)のキャンバスにレンダリングし、同じトリミングで 2 つを比較します。テクスチャと色はこの方法で判断し、記憶からは判断しません。
  3. 複数のウェーブを含むページの場合、上記のプリセットを使用し、各フレームに合わせて再配置します。テイクページで代替案を表示します。
  4. フルサイズで検証(ヘッドレス Chrome):コンソールがクリーンで、すべてのキャンバスが構築されていること。1440 と 375 の両方で。4 秒間隔の 2 つのフレームを 4 分の 1 ずつ比較(不均一な変化:パーツが動いている;均一な変化:回転している)。ウェーブがそのフレームを埋めていること。
  5. 視覚的に何が変わったかを説明するメッセージをコミットします。

却下されたもの、繰り返さないこと

  • 名前付きの形状を文字通りに受け取ること。「トルネードを作って」のようなプロンプトは意味に関するヒントであり、ジオメトリに関するものではありません。
  • ウェーブ以外のフォーム。 リング、結び目、スプリング、パスに沿って掃引されたチューブ(「他のものは本当にクールではない」)、および強いターンによって他の形状に押し出された折り畳みシート:渦巻き漏斗、巻かれたコイル、絡まり(「絡まり、コイル、漏斗は本当に悪い」)。穏やかなロールオーバー(turn)だけが「まあ良いかも」として合格しました。
  • 光源あり、シェーディングされたシート:Stripe の無光源表面の隣ではプラスチックのように見えます。
  • ランダムなブロッチのパレット:可視シートが 1 つの平坦な色で埋まります。
  • 単一層のシート:「薄い側面が見える」。
  • オブジェクト全体の回転:「全体が動いていて、一部だけではなかった」。
  • 移動する光の線:「それは OpenRouter の時だけのもので、ここでは Stripe を模倣している」。
  • フレームの中央に浮かぶ小さなウェーブ。
  • 透明なものに対する通常のアルファブレンド:継ぎ目が見える。
  • 描画線、ノード&ワイヤーダイアグラム、グリッド線、ラベル...

関連スキル