WebGL 形式
形式就是波浪:stripe.com 的折叠纸张,正如 stripe.com 所绘制的那样。 用户在多次尝试后的评价是:“我只喜欢波浪,因为它确实是一个好的形式。波浪正是我想要的。” 所有尝试过的其他形式(环、结、弹簧、螺旋漏斗、缠绕的纸张)都被拒绝了。因此,一个想法永远不会变成一个新的形状。它会变成一个带有自己颜色、裁剪和设置的波浪。
| 文件 | 说明 |
|---|---|
reference/stripe-three.js | 核心引擎。 Three.js r178:在顶点着色器内构建的折叠纸张,Stripe 的扭曲作为旋转列表,Stripe 的非光照着色,绘制的调色板,后处理通道,以及五个可用波浪的 TAKES / PRESETS。复制它,然后添加预设。 |
reference/stripe-notes.md | stripe.com 的英雄区波浪的正式发布状态:折叠几何体、着色器、相机以及其所有四个波浪的设置。在调整前阅读。 |
reference/twist-ribbon.js, reference/nib-ribbon.ts | 较早的纯 WebGL2 丝带(OpenRouter, OpenEvidence)。仅用于已经运行它们的项目。 |
reference/ReactMount.tsx | 带有后备方案的 React/Next 挂载组件。 |
0. 需要询问的内容
提示承载的是意义,而非形状。形状曾导致失败:每一个按字面构建的命名形式(莫比乌斯环、结、弹簧、龙卷风)最终都看起来像 3D 剪贴画。OpenRouter 丝带之所以有效,是因为其意义(“许多模型,一个端点输出”)变成了设置(纸张何处转向边缘),而非产品的图画。
在一次消息中最多询问三件事:
- 想法,用一句话概括:产品做什么,或者艺术作品要表达的唯一内容。(“每个模型通过一个端点。”)
- 颜色:品牌的颜色,或者“从代码中读取”(
globals.css中的标记、Tailwind 主题、Logo 的颜色)。 - 位置:英雄带(在文字下方或周围)、单元格、卡片;亮色或暗色页面。
完全没有提示也是一种有效用法:从代码中读取颜色,在 Stripe 的亮色英雄区位置使用 wave 预设,并用一行说明。
一个命名的形状(例如“制作一个龙卷风”):不要构建该形状。将其视为关于意义的提示(龙卷风:上升、旋转、力量),并映射到下面的设置。用一行告诉用户该技能保留波浪及其原因。如果他们仍然坚持,就构建该形状作为一个额外的选项(与波浪并列,并标注),供他们比较。
从意义到设置(起点,非规则):
| 想法感觉 | 从以下开始 | 更改 |
|---|---|---|
| 平静、信任、金钱、健康 | deep | 节奏 4e-5,冷色或暖中性调色板,宽裁剪 |
| 多归于一、焦点、端点 | wave | 将边缘拉伸(收窄处)放在文字下方或旁边 |
| 能量、实时、速度 | petal 或 fold | 节奏提升至 8e-5,暖色调色板 |
| 变化、两面、转折 | turn | 翻卷展示两面 |
| 无特定内容 | wave | 仅品牌调色板 |
输出: 在选项页面上提供两个或三个选项,同一波浪系列的不同预设、裁剪或调色板。用户选择一个;删除其余的。
1. 形式
- 折叠纸张:一个 400 x 400 的平面(128 x 256 分段)对折:顶层是一个 32 单位宽的条带,弯曲成半个圆柱体(圆角折叠),底层折叠在下方,末端相距 4 个单位,中间相距 2 个单位。直立起来经过两个四分之一转:长度沿 x 轴,厚度沿 y 轴,宽度沿 z 轴。厚重,带有圆边,绝无线宽。在顶点着色器中通过 UV 构建(
folded(uv)),因此法线是精确的。 - Stripe 的三个扭曲塑造了它:围绕对角线轴
(.5, 0, .5)和(0, .5, .5)的旋转,每个都通过 Stripe 的软阶梯函数exp2(-exp2(n) * pow(x, n))沿宽度 (u) 或长度 (v) 进行渐变。在引擎中:使用 Stripe 的参数stripeTwists([x, y, z], [powX, powY, powZ])。x 扭曲沿长度在噪声上漂移:这,连同噪声波,就是全部的运动。部分移动;整体从不旋转。 - 噪声波:
p.y += amount * noise(x * fx + t, z * fz + t)。 - 在 Stripe 画框中的位置:一个 1392 像素宽的画布(像素单位),正交相机位于
(100, 0, 5000),绕 y 轴旋转 0.02 弧度;每个数字按画布宽度 / 1392缩放。始终大尺寸并被其画框裁剪,从不显得小而浮动。 - 节奏:Stripe 的时钟,每毫秒
4e-5到8e-5。刻意缓慢。
2. 五种有效的波浪
其中四个是 stripe.com 发布的波浪,带有其精确设置(扭曲 x, y, z;幂次;噪声波;位置;发光;节奏)。第五个增加了一个旋转。
| 预设 | 来源 | 扭曲 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 方向长度 (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,提升幂次,通过斜坡函数进行平滑阶梯处理。其符号指示纸张的两个面;接近零时纸张正在折叠。 - 对比度、饱和度、色相,然后
+ (1 - pdy) * 0.25:另一面以及折叠处变淡。这就是 Stripe 折叠处那奶油色的带子。 - 不透明,深度测试。后处理通道:一个 0.02 弧度的旋转模糊,保持在画面中部的一个锐利条带之外,然后在有颜色的区域添加颗粒(1.1)。颗粒是 Stripe 的静态抖动:
color + mix(1, -1, random( gl_FragCoord.xy * 0.01)) * 4/255 * amount。它从不逐帧变化。每帧都重新随机化的颗粒会闪烁并被视为噪声(“与 Stripe 相比噪声太多”),并且在视频中还会使文件大小增加数倍。
没有绘制的线条,没有运动的光线,没有法线光照,没有折痕高光:引擎中较旧的有光照着色仅作为选项保留(shading: "lit"),并且不是默认设置。
4. 调色板
按照 Stripe 运行的方式绘制它,而不是随机色块(随机色块在纸张的大部分可见区域产生了一种平坦的颜色):
- 沿长度 (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 不会将其遮罩掉,也不会让波浪覆盖文字。它会两次绘制文字:
- 在画布下方:文字使用其正常颜色(Stripe:标题海军蓝
#061b31,正文灰色)。当波浪经过它时,波浪将其隐藏。 - 在画布上方(
z-index高于波浪层):一个完全相同的文字副本,相同的大小和位置,aria-hidden,带有mix-blend-mode: hard-light和半透明的着色颜色(Stripe:标题rgb(45, 37, 100),深紫色;正文rgba(0, 14, 255, 0.5),半透明蓝色)。在白色页面上,它看起来像普通文字;在波浪上,字母会呈现波浪的颜色,因此它们保持可读,看起来像是印在丝绸上。
规则:
-
从品牌中选择顶部文字副本的色调:标题颜色的一种深邃、高饱和版本,以及半透明的品牌蓝色(或强调色)用于正文。检查一张波浪最亮时的截图:每个单词仍然可读。
-
两个文字副本必须完全匹配(相同的元素样式,相同的换行):从一个源构建它们,并在一个网格单元格中堆叠(
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;在屏幕外和隐藏标签页中暂停;减少动画模式绘制一个静止帧。无指针交互。 - 页面上最多大约 13 个波浪;超过 16 个时浏览器会丢失上下文。
- 绝不要将 GLSL 变量命名为
step、mix或fract。
7. 工作流程
- 获取输入(第 0 节):想法、颜色、位置。无提示:颜色从代码中获取,使用
wave预设。将想法映射到预设、裁剪和调色板;绝不映射到新形状。 - 与真实事物对比:截取 stripe.com 英雄区在 1440x900 下的屏幕截图,在 Stripe 的精确画框(1392 x 761,位于 x 337)中渲染我们的版本,并在相同裁剪下比较两者。纹理和颜色以这种方式判断,而非凭记忆。
- 对于包含多个波浪的页面,使用上面的预设,重新放置以适配每个画框;在选项页面上展示备选方案。
- 全尺寸验证(无头 Chrome):控制台干净,每个画布都构建成功;验证 1440 和 375 宽度;比较相隔四秒的两帧的每个四分之一区域(不均匀变化:部分在移动;均匀变化:旋转);波浪填满其画框。
- 提交时附带一条消息,说明视觉上改变了什么。
已被拒绝,请勿重复
- 按字面理解一个命名的形状。 像“制作一个龙卷风”这样的提示是关于意义的提示,而非几何体。
- 任何波浪以外的形式。 环、结、弹簧和沿路径扫掠的管状物(“其他那些看起来并不真正酷”),以及通过强劲扭曲推入其他形状的折叠纸张:螺旋漏斗、缠绕的线圈、纠缠(“纠缠、线圈和漏斗都非常糟糕”)。只有温和的翻转(
turn)通过了,被评价为“也许还行”。 - 有光照、有阴影的纸张:它们靠近 Stripe 的非光照表面时会显得像塑料。
- 随机色块调色板:会导致纸张可见区域填满一种平坦的颜色。
- 单层纸张:“你可以看到薄薄的侧边”。
- 整个物体旋转:“整个东西在动,而不是某些部分”。
- 移动的光线:“那只是 OpenRouter 的东西,这里我们模仿 Stripe”。
- 画框中间浮动的小波浪。
- 在任何透明物体上使用普通 Alpha 混合:会产生接缝。
- 在艺术作品内绘制线条、节点-连线图、网格线、标签或计数;波浪延伸到导航栏下方。