站点 landing-hero 组件(blocklets/arcblock/.web/components/landing-hero/)新增了一个可选的
heroVisual prop:打开后会在文案后面渲染一个全屏铺满的 .landing-hero-visual 挂载点。配合 AUP 的
widget 子块指定一个 Web Device widget(这里用的是 webgl-hero —— 运行时自带、24 种模式的 WebGL 3D
背景),Hero 就变成了 Web Device widget 层能力的真实展示,而不是贴在页面上的无关装饰。
这页是一份持续维护的候选目录,不是教程:下面每个候选都是真实渲染出来的效果,带着精确配置留在这里 —— 这样以后再回来选设计时不用重新踩一遍哪些 mode 真的能用、哪些不适合这个站的编辑气质。不适合的记在 「死胡同」一节。
一览
webgl-hero 全部 24 个 mode,用的是本站自己的 ::gallery{folder} 媒体块(见
文件夹驱动的媒体画廊),不是手搭的网格。每个 mode 的说明只写它渲染的是什么、
是否读取 colors 配置还是调色板写死在 shader 里;完整配置和更大的截图在本页下方的参考小节里。
























怎么接的
component hero slot=site-introduction component=landing-hero variant=home
headlineVariant=balanced-statement maxLines=3 heroVisual=webgl
title=:k0 subtitle=:k1 ... {
widget hero-bg name=webgl-hero target=".landing-hero-visual" mode=topo
colors="#008f7a,#fcfdfc" opacity=0.5 speed=0.4 mouse=false
}heroVisual=webgl 会把组件切到单列布局,文案区域固定一个最大宽度,再加一层可读性遮罩。水平方向按
文案框自身的尺寸计算 —— 不是按 section 或视口百分比算,否则窗口越宽遮罩和文字就越对不上(和下面
topo 那个「平面覆盖不够宽」的坑是同一类问题)。垂直方向必须铺到 Hero 的上下边:文案在带 padding、
垂直居中的 inner 里,遮罩如果只比文案框多伸出几个 rem,header 下面就会露出一条没被盖住的 canvas。
开了 heroVisual 之后,这个站在其他页面用的 trace/geometry 侧栏会自动隐藏 —— 一个 Hero 只挑一种
视觉,不叠加。
760px 以下 widget 完全不会跑:一段内联脚本会尽早注册 DOMContentLoaded 监听器,抢在引擎自己的监听器
扫描之前把 widget 的配置 <script> 删掉,所以手机上不会创建 WebGL 上下文、不会加载 Three.js、也不会有
渲染循环。符合这个站「移动端不跑 WebGL/canvas 效果」的规矩;手机上渲染的是纯文案 Hero(标题、副标题、
按钮)。
真实对比页(内部用,不进导航):/zh/hero-lab-topo/、/zh/hero-lab-aurora/、/zh/hero-lab-cubegrid/
—— 文案和首页一样,只是 heroVisual 配置不同,方便在真实浏览器里并排判断,不必先上首页才能看效果。
这几个对比页只有在本地自己构建的 arc 上才能正确渲染。
下面说的 CSS 覆盖 + opacity bug 已经在上游合并修复
(ArcBlock/arc#4402),topo 的覆盖/宽高比修复在
ArcBlock/arc#4490。这两个里只要有一个还没发版,实际服务
这个 blocklet 的 arc 二进制就可能还是旧行为——widget 挂载点正常挂上但高度塌成 0,或者 topo 在宽屏上
被拉伸。每个候选下面的截图是在修复过的构建上拍的如实记录;这些链接是给"在修复过的构建上本地核实"用的,
不代表当前部署站点上会长这样。
候选
topo —— 密集等高线

mode=topo colors="#008f7a,#fcfdfc" colorsDark="#2ec8ae,#061211" opacity=0.5 speed=0.4 mouse=false评价:目前最强的候选。读起来像真实的技术纹理(等高线),不是通用 AI 站的渐变套壳;下面那条平面尺寸
修复上线后,窄屏和超宽屏都撑得住。opacity 也是真的生效(这个 mode 正确响应 opacity 配置)。
搭这个的过程中发现并修掉了三个坑:
TopoEngine原来用固定尺寸的PlaneGeometry(30, 20),只能覆盖到约 2.4 的宽高比,浏览器窗口一旦 更宽,平面边缘之外就会露出纯色背景(两侧留白)。已上游修复为按相机在渲染时的实际可视锥体动态算平面 尺寸(见下方「上游修复」)。- 上面这条覆盖修复暴露了第二个坑:噪声 shader 在两个轴上都用
vUv * 6.0采样,而 vUv 是每轴 0-1, 跟平面的实际宽高比无关——平面越宽,每个噪声周期覆盖的物理宽度就比高度多,等高线在画面上看起来是 被横向拉长的条纹,而不是圆润的等高线团块。已上游修复为只把 x 方向的采样按平面宽高比缩放,让噪声 周期在两个方向上物理尺寸一致。 - widget 的
colors配置是静态的、不感知主题——浅色模式的配置在深色模式下会渲染成一块突兀的亮色矩形。landing-hero的 render.js 现在支持配一组对应的colorsDark/bgDark,如果页面加载时深色模式已经 生效,会在 widget 解析配置之前在客户端把颜色换掉。已知还没解决的缺口:如果是在页面已经加载完之后 实时点击主题切换按钮(不刷新),画布不会跟着重新上色——这个替换只在加载时生效一次。
aurora —— 大气渐变

mode=aurora colors="#008f7a,#2ec8ae,#0f3d38" opacity=0.5 speed=0.4 mouse=false评价:视觉上很抓眼,但更像通用「AI 产品」演示站的调调,和这个站克制的编辑气质不太搭。要么换一套 对比度低得多的配色,要么把副标题的行宽再收窄,现在只是「能跑」,还不是真正的候选。
搭这个的过程中发现一个 bug:每张截图里,header 正下方都横着一条硬边黑带。更早一轮用
getBoundingClientRect() 量过 section、.landing-hero-visual 挂载点和 canvas,三者像素坐标完全
一致,于是断定不是 CSS,转头在 aurora / ocean / retrowave 上调了三次 camera.lookAt()。
这个诊断是错的。canvas 确实铺满了 section;缺的是 .landing-hero-copy::before 那层可读性遮罩。
文案在带 padding、垂直居中的 inner 里,遮罩只比文案框多伸出 ±8rem——1440px 下 header 下面会露出
大约 45px 没被盖住的 canvas,换宽度还会变。深色 mode 这条缝特别显眼;topo 这种浅色 mode 会把它
藏住。当时当作「已修好」发出去的 retrowave 截图,黑带其实还在。
真正的修法在 landing-hero 的 CSS:水平方向继续按文案框算,垂直方向把遮罩拉过 section
(top/bottom: -100vmax,由 .landing-hero { overflow: hidden } 裁掉)。在
600/868/1221/1440/1920px 验证过。相机倾斜仍可能在 3D 场景里留下空天空,那是 widget 里另一件事,
不是这条 header 缝。
cubegrid —— 几何线框网格

mode=cubegrid colors="#008f7a" opacity=0.6 speed=0.5 mouse=false评价:主题上贴合度最高 —— 旋转的线框立方体直接呼应 ArcBlock 真实的 cube/pyramid 标志,而不是一段无关
纹理,单一强调色也够克制。定稿前值得再过一遍 positioning.md 的自查句「换成任何 AI 技术站是否仍然
成立」——几何关系本身是我们特有的论据,但「线框立方体」这个效果本身是个通用套路。
死胡同
以下都是真的渲染出来截图看过的,不是只读源码就下结论——「照源码看应该行」不代表实际画面行,反过来也
成立(见下面 rings 那条,实际看过之后改判)。同样有真实对比页(内部用,不进导航),本地构建限制同上:
/zh/hero-lab-network/、/zh/hero-lab-wave/、/zh/hero-lab-rings/。
network —— 死路,完全不认品牌色

mode=network colors="#008f7a,#0f3d38" opacity=0.5 speed=0.4 mouse=false评价:死路,不是审美判断——NetworkEngine 把调色板直接写死在 GLSL 片元着色器里,从不读
cfg.colors,上面配的青绿色完全没用;实际渲染出来是一套跟本站配色毫无关系的通用蓝白星座效果。颜色
写死这条没在这次 PR 里修(改动面比机械式的 opacity 修复大得多),上游 issue 里跟踪,暂时不能用。
wave —— 死路,太稀疏撑不起一个背景

mode=wave colors="#008f7a,#1f7a6e" bg="#fcfdfc" opacity=0.85 speed=0.4 mouse=false评价:死路。技术上是这几个 mode 里表现最规矩的一个(opacity 和 colors 都正确响应,没有上游 bug),
但线框球本身相对 1440×600 以上的全屏画布来说太小太稀疏——看起来像悬在大片空白里的一小簇星芒,撑不起
一个背景。
rings —— 没选,但之前判断「太稀疏」是错的

mode=rings colors="#008f7a" bg="#fcfdfc" opacity=0.85 speed=0.4 mouse=false评价:纠正——这页早前的版本只读了 engine 源码就把 rings 和 wave 归到一起判「太稀疏」,没有实际
渲染过。真实效果一点都不稀疏:18 个重叠的环读起来是一个大胆、完整的线框地球仪。最终没选它是另一个
原因——按 positioning.md 的自查句「换成任何通用 AI 站是否还成立」——线框地球仪/轨道是科技营销里的
一个常见套路,跟本站自己的内容没有关系,不像 cubegrid 直接呼应了真实的 cube/pyramid 标志。是因为这个
原因放弃的,不是因为渲染效果不好。
其余全部普查
webgl-hero 一共 24 个 mode。上面 6 个是真正值得拍板的;剩下的也都渲染出来截了图,不是读源码就下
结论。以下没特别标注的都用同一套配置:青绿系 colors、bg="#fcfdfc"、opacity=0.6、speed=0.4、
mouse=false。本页涉及的每个 mode 都有对应的真实对比页(内部用,不进导航),地址是
/zh/hero-lab-<mode>/,本地构建限制同上。
完全不读颜色配置(读过源码确认,不只是看渲染效果猜的)
crystal、phantom、lightcube、reflect、gyroid、tunnel、abstract 都不读 cfg.colors——
调色板各自写死在 shader 里,跟 network 是同一类 bug。这条不修,这几个都不能用(这次没动手修——改动面
比机械式的 opacity 修复大得多)。
| Mode | 截图 | 备注 |
|---|---|---|
| crystal | ![]() | 紫蓝色玻璃碎片,跟品牌色无关。 |
| phantom | ![]() | 白色发光散景,跟品牌色无关。 |
| lightcube | ![]() | 浑浊、跟品牌色无关,画面一部分是纯黑。 |
| reflect | ![]() | 看起来像堆叠的纸箱,不是抽象效果。 |
| gyroid | ![]() | 迷幻、刺眼,调性完全不对。 |
| tunnel | ![]() | 品红金色跟品牌色无关,大部分是黑色空洞。 |
| abstract | ![]() | 虹彩油渍效果,跟品牌色无关。 |
太稀疏或太小,撑不起一个背景

blob、collapse、meshline——跟 wave 一个毛病:技术上没问题,但几何本身相对 1440×600 以上的
全屏画布太单薄,一眼扫过去撑不起一个背景。
渲染没问题,但读起来是通用科技营销套路

galaxy——一个大胆、密集的网络球体。跟 rings 同样的判断:常见的「区块链网络」通用素材图,跟本站
没有特定关联。

landscape——全屏的山脉/道路/日落场景。读起来像通用图库图片;而且忽略了青绿色配置(不管怎么配都
渲染成中性灰褐色)。因为图库照片这个理由,还是不是候选。

retrowave——教科书式的合成波落日。整个普查里最套路化的「AI 演示站」既视感,而且跟副标题文字
重叠得够严重,影响可读性。这个 mode 上的 header 缝就是上面 aurora 那条说的 CSS 遮罩 bug(上面这张
是修好之后的截图;网格地面还在场景里)。套路化这条理由仍然成立,还是不是候选。
混乱、视觉噪音大

cube——顶点抖动很重的线框方块。读起来像渲染故障而不是刻意的效果,右边缘还压在副标题文字上。
品牌色正确、渲染效果不错,但内容上没选

ocean——确实正确读取了青绿配置(「海水」填充是品牌色),效果也平静。没选是因为内容本身——一个
字面意义上的海洋/日落场景——跟软件或本站主题没有关联。

metaball——同样正确用上了品牌色(柔和的青绿光晕团块),是这组里效果最好看的一个。读起来是通用的
「熔岩灯」氛围效果;留着——如果三个主候选后续设计评审都没通过,这个值得重新考虑。
坏的

clouds——渲染出来只是一片纯色渐变,看不出任何体积云细节。CloudsEngine 有 GPU 档位检测,探测到
低端/软件渲染器时会调低步进精度;这次是在 headless Chromium(SwiftShader)下跑的,可能是原因——没有
真实 GPU 做对比,这里如实标注「不确定」,不瞎猜。

marble——原来什么都不渲染:它 loader.load() 的两个贴图文件(marble-noise.jpg、
marble-noise3d.jpg)在任何环境下都是 404,因为这两个文件从来没有随 widget 一起打包过。已提
ArcBlock/arc#4417,并在上游合并修复
ArcBlock/arc#4440(用程序化噪声替换了缺失的贴图)。
现在能渲染了——一个大的、有光泽的球体,颜色是品牌色,但程序化替换后看不出明显的大理石纹理,读起来
更像一个通用的玻璃/铬合金球,跟这个站没有特定关联。没选的理由和 metaball 一样:正确、品牌色、但
是个通用效果。
背后的上游修复
搭上面这些候选的过程中撞到四个 webgl-hero 的真实 bug,现在都已在上游修复:
- ArcBlock/arc#4392 —— widget 自己注入的 CSS
(
.wh{position:relative})在同优先级、后加载的情况下把本站position:absolute;inset:0悄悄覆盖 掉,导致挂载点高度塌成 0 —— 不管配的是哪个 mode 都一样。另外 24 个 mode 里有 17 个通过重复调用setClearColor(x, 1)把opacity配置扔掉了。 修复:ArcBlock/arc#4402(已合并)——改成通过 canvas 的 CSS opacity 应用cfg.opacity,而不是走 WebGL 的 clear alpha:three.js 的WebGLBackground只要scene.background是个 Color,就会无视setClearColor的 alpha 参数、始终按 alpha=1 清屏。更早一版 同一个修复(#4403,已关闭,判定为重复 PR)走的是逐个 mode 把scene.background置空的路子——真正合并上线的是 #4402 这个改一处共享函数就够了的版本。 topo的平面原来是固定尺寸的PlaneGeometry(30, 20),只能覆盖到约 2.4 的宽高比——hero 一旦更宽, 平面边缘之外就会露出纯色背景。改成按相机实际可视锥体动态算尺寸之后,又暴露出第二个坑:噪声 shader 在两个轴上采样速率一样,导致宽 hero 上等高线被横向拉长。 修复:ArcBlock/arc#4490。marble加载两个 widget 包里根本不存在的贴图文件,什么都不渲染。已提 ArcBlock/arc#4417,修复见 ArcBlock/arc#4440(已合并)——见上文该条目。
上面 aurora 那节调查的顶部黑带,问题出在 arcblock-site 自己的可读性遮罩,跟这个 widget 无关——
webgl-hero 的相机行为从来都不是原因。修法见那一节。
在上面这些修复都发版之前,本页的候选只有在本地自己构建的 arc 上才能正确渲染 —— 「上游关闭」和
「我们真的能用」之间的差距,参见本仓库的 arc-upstream skill。






