WebGL フォーム は何をしますか?
フォームとは ウェーブ のことです:stripe.com が描くように折り畳まれたシートです。 多くの試行錯誤の末のユーザーの評価は「ウェーブだけが好き。本当に良いフォームだから。これが欲しかった。」というものでした。他のすべてのフォーム(リング、結び目、スプリング、渦巻き漏斗、絡まったシート)は却下されました。したがって、アイデアが新しい形状になることはありません。アイデアは独自の色、切り抜き、設定を持つウェーブになります。
| ファイル | 説明 |
|---|---|
reference/stripe-three.js | エンジン。 Three.js r178:頂点シェーダーで構築された折り畳みシート、Stripe のひねりをターンのリストとして表現、Stripe の無光源シェーディング、塗り分けパレット、ポストパス、および以下の 5 つの動作するウェーブを含む TAKES / PRESETS。コピーしてプリセットを追加してください。 |
reference/stripe-notes.md | stripe.com のヒーローウェーブそのまま:折り畳みジオメトリ、シェーダー、カメラ、および 4 つすべてのウェーブの設定。チューニング前に読んでください。 |
reference/twist-ribbon.js、reference/nib-ribbon.ts | 古いプレーンな WebGL2 リボン(OpenRouter、OpenEvidence)。すでにそれらを実行しているプロジェクトのみ対象。 |
reference/ReactMount.tsx | React/Next マウント(フォールバック付き)。 |
0. 何を尋ねるか
プロンプトは 意味 を伝え、形状は決して伝えません。形状は失敗の原因でした。文字通りに構築された名前付きのフォーム(メビウスの輪、結び目、スプリング、トルネード)はすべて 3D クリップアートになりました。OpenRouter のリボンが機能したのは、その意味(「多数のモデルを1つのエンドポイントに」)が設定(シートがエッジオンになる場所)になったからであり、製品を描画したからではありません。
最大3つのことだけを、1つのメッセージで尋ねてください:
- アイデア:製品が何をするか、またはアートが伝えるべき1つのことを一文で。(「すべてのモデルを1つのエンドポイントに。」)
- 色:ブランドの色、または「コードから読み取ってください」(
globals.cssのトークン、Tailwind テーマ、ロゴの色)。 - 配置場所:ヒーローバンド(コピーの下または周囲)、セル、カード;明るいページまたは暗いページ。
プロンプトがまったくない場合 も有効な使用法です:コードから色を読み取り、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 / パワー | ノイズウェーブ | 回転;スケール;位置 | グロー | ペース、オフセット |
|---|---|---|---|---|---|---|
wave | Stripe のライトヒーロー | -0.65, 0.41, -0.58 / 3.63, 0.7, 3.95 | 0.005831, 0.016001, -7.821 | -0.4496, -0.1176, 1.8744; 9, 8, 5; 380, -301.7, -11.1 | 1.98, 0.806, 0.834 | 4e-5, 17500 |
deep | Stripe のダークヒーロー、白地に描画 | -0.055, 0.077, -0.518 / 3.95, 5.85, 6.33 | 0.003234, 0.00799, 6.051 | -0.1596, -0.2836, -2.8156; 10, 10, 7; -24.3, -56.4, -11.1 | 0.6, 0.589, 1 | 4e-5, 1150 |
fold | Stripe の請求ヒーロー、セルに収まるように回転 | -0.424, 0.024, -1.312 / 1.81, 0.94, 4.76 | 0.005, 0.0212, 6.68 | -0.666, -0.0314, 1.9; 6.05, 8.4, 6.99; 50, -100, -11.1 | 1.55, 1.174, 0.972 | 5.25e-5, 17500 |
petal | Stripe の小さなアクセントウェーブ、拡大・回転 | 0.059, 0.32, -0.397 / 3.63, 0.44, 5.99 | 0.005831, 0.016001, -7.821 | -2.8756, 3.0959, -1.6; 9, 9, 9; 0, -50, -11.1 | 3.86, 0.923, 1 | 8e-5, 2275 |
turn | ライトヒーローを完全にロールオーバー(機能した唯一の追加ターン) | ライトヒーローのものに加えて、v に沿って LENGTH (1, 0, 0)、2pi、ドリフト 0.15 | ライトヒーローのもの | ライトヒーローのもの | ライトヒーローのもの | ライトヒーローのもの |
太字の数値は Stripe の独自配置とは異なります:Stripe はそれらのウェーブを自社のフレーム用に配置したため、より小さなセルでは平坦な部分にトリミングされたり、小さく浮遊したりしました。再配置し、形状は変えないでください:異なるフレームに合わせるには、回転、スケール、位置のみを変更します(HTML の data-overrides)。
3. シェーディング:Stripe 独自の無光源
実際の stripe.com のヒーローには光源がまったくありません。そのため、プラスチックのように見えず、明るく輝いて見えます。その表面は:
- パレット がシートの (u, v) に適用されます。
- 長く細かい光条 が長さ方向に沿って:
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 に下げてください。 - グロー項
pdy:dFdy(v) * resolution.y * amount。範囲 -1..1 から 0..1 にマッピングし、べき乗し、ランプでスムーズステップします。その符号はシートの 2 つの面を区別します。ゼロに近い場合、シートは折り曲げられています。 - コントラスト、彩度、色相、次に
+ (1 - pdy) * 0.25:反対側の面と折り目は淡くなります。これが Stripe の折り目にあるクリーミーな帯です。 - 不透明、深度テストあり。ポストパス: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 回 描画します:
- キャンバスの下:通常の色のコピー(Stripe:見出しはネイビー
#061b31、本文はグレー)。ウェーブがその上を通過すると、ウェーブがそれを隠します。 - キャンバスの上(
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. ワークフロー
- 入力(セクション 0)を取得:アイデア、色、場所。プロンプトがない場合:コードから色を、
waveプリセットを使用。アイデアをプリセット、トリミング、パレットにマッピングします。新しい形状には決してマッピングしません。 - 実物と比較:1440x900 で stripe.com のヒーローをスクリーンショットし、Stripe の正確なフレーム(1392 x 761、x 337)のキャンバスにレンダリングし、同じトリミングで 2 つを比較します。テクスチャと色はこの方法で判断し、記憶からは判断しません。
- 複数のウェーブを含むページの場合、上記のプリセットを使用し、各フレームに合わせて再配置します。テイクページで代替案を表示します。
- フルサイズで検証(ヘッドレス Chrome):コンソールがクリーンで、すべてのキャンバスが構築されていること。1440 と 375 の両方で。4 秒間隔の 2 つのフレームを 4 分の 1 ずつ比較(不均一な変化:パーツが動いている;均一な変化:回転している)。ウェーブがそのフレームを埋めていること。
- 視覚的に何が変わったかを説明するメッセージをコミットします。
却下されたもの、繰り返さないこと
- 名前付きの形状を文字通りに受け取ること。「トルネードを作って」のようなプロンプトは意味に関するヒントであり、ジオメトリに関するものではありません。
- ウェーブ以外のフォーム。 リング、結び目、スプリング、パスに沿って掃引されたチューブ(「他のものは本当にクールではない」)、および強いターンによって他の形状に押し出された折り畳みシート:渦巻き漏斗、巻かれたコイル、絡まり(「絡まり、コイル、漏斗は本当に悪い」)。穏やかなロールオーバー(
turn)だけが「まあ良いかも」として合格しました。 - 光源あり、シェーディングされたシート:Stripe の無光源表面の隣ではプラスチックのように見えます。
- ランダムなブロッチのパレット:可視シートが 1 つの平坦な色で埋まります。
- 単一層のシート:「薄い側面が見える」。
- オブジェクト全体の回転:「全体が動いていて、一部だけではなかった」。
- 移動する光の線:「それは OpenRouter の時だけのもので、ここでは Stripe を模倣している」。
- フレームの中央に浮かぶ小さなウェーブ。
- 透明なものに対する通常のアルファブレンド:継ぎ目が見える。
- 描画線、ノード&ワイヤーダイアグラム、グリッド線、ラベル...