Communitygithub.com

automatorsplus/immersive-3d-site

搭建沉浸式实时3D网站:将实时Three.js场景置于真实HTML文字后方,由滚动和鼠标驱动。包含玻璃金属英雄物体、辉光效果、可变形粒子云、摄像机路径飞行、产品分解视图、着色器背景和实例化世界。

immersive-3d-site 是什么?

这是一个帮助开发者和AI代理构建令人惊叹的沉浸式3D网站的技能(Skill),核心是将实时Three.js 3D渲染与真实HTML文字层完美结合,而非使用预渲染视频。它通过精心设计的

兼容平台~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/automatorsplus/immersive-3d-site-skill/tree/HEAD/.claude/skills/immersive-3d-site

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

沉浸式3D网站

这是一个页面,其中的3D是实时的,而非3D视频。访客的滚动就是时间线,光标则是第二个摄像头。真实的文字位于上方,可读且可选;WebGL画布位于其后。

你所交付的内容: 一个包含以下内容的构建文件夹:BRIEF.md、一个真正的 index.html、旁边的引擎文件,以及来自桌面端、手机端和减少动效模式的一系列截图,外加一份简短报告,说明你检查了什么以及哪些内容你无法检查。

是什么导致这些页面失败

大多数“3D网站”在整个页面中只使用一种技巧:一个旋转的模型,文字在其上淡入。到第三个部分时,访客已经看完了所有内容并停止滚动。四条规则可以防止这种情况:

  1. 每一幕都做不同的事情。 从 references/scene-kit.md 中使用至少四种不同的场景设备,且连续两次不使用相同的设备。
  2. 一个峰值。 有一幕是某人会向朋友描述的那个时刻。它获得最多的滚动空间、最好的场景,以及前一幕的平静,以便它能够更好地展现。
  3. 3D服务于信息。 每个场景都展现关于主题的真实内容:它是由什么构成的、它如何工作、它给人什么感觉。纯装饰性的场景会被删除。
  4. 文本在任何滚动位置都应保持可读。 如果在任何帧中,某行文字在场景之上难以阅读,那么移动的是场景,而不是文字。

第0步:简报

重复使用用户已经提供给你的内容。如果他们提供了完整的简报或说了“由你判断”,则自己编写 BRIEF.md,标记为在创意授权下编写,自行以品牌的口吻回答下面的每个问题,然后继续。否则,在一条消息中提出全部八个问题,以真实问题的形式提出,而不是你编造的菜单:

  1. 它是什么,为谁而建,以及他们最终应该做什么? 一个操作,一个随处使用的标签。
  2. 用三到五个词描述感觉,外加最多三个来自非网站领域的参考:一部电影、一个游戏、一张专辑封面、一家商店。命名网站会导致页面抄袭。
  3. 用他们的话来描述旅程: 访客最先看到什么,然后是什么,最后是什么。
  4. 什么地方应该平静,什么地方应该激烈。
  5. 在每个阶段,人们应该有什么感觉,以及他们应该记住的哪个时刻。 参见 references/feel.md。
  6. 这个网站应该做一件他们没有见过的网站做过的事情。 标志性动作的种子。推动他们给出真实的答案;“令人难忘”不算。
  7. 距离高端简约有多远: 提供 references/structures.md 中的范围。
  8. 一个连续的世界,还是独立的场景? 最大的结构性分支,由他们决定。此外:他们已经拥有的东西(标志、颜色、字体、产品照片、.glb格式的3D模型)。

在构建文件夹中编写 BRIEF.md,使用他们自己的话记录他们的答案,然后添加:

  • 旅程: 四到七个节拍,每个节拍都代表访客所知或所感的变化。
  • 情感曲线: 每个节拍一行,描述感觉以及屏幕上导致这种感觉的内容。相邻节拍不能相同。
  • 峰值: 访客会用来描述它的那个句子,以及它位于哪一幕中。
  • 这是一个___的网站: 填入一种体验,而非一种技术。
  • 标志性动作: 一种仅在这个网站上存在、被编码在页面中的交互。使用套件设备加上新数字不算。
  • 任何有意的留白, 进行标记,以便检查时能够将其与死滚动区分开。

第1步:结构、记录日志,然后评分

按此顺序做三件事。所有三件事都在任何代码之前完成。

从 references/structures.md 中选择一个结构: 一个世界、章节、产品舞台、展览、游乐场、带有插图的编辑页、广播。导航、开场和结尾都由此决定。在 BRIEF.md 中说明为什么选择这个而不是其他的。

运行指纹记录日志。 读取保存你构建的文件夹中的 FINGERPRINTS.md(如果不存在则创建;初始为空)。你的计划必须在以下至少四个方面与所有现有行不同:结构、导航、英雄设备、幕序列、结尾、标志性动作。如果不符合要求,则修改计划,而不是日志。

进行评分。 首先是情感曲线,然后在 BRIEF.md 中以表格形式列出每个节拍的设备:

节拍幕感觉设备跨度为什么选择这个设备
识别英雄好奇玻璃物体 + 推拉2产品在文字被阅读之前就活生生地展现在眼前
转变变形期待粒子变形3噪声变为形状,再变为名称
峰值轨道敬畏摄像机轨道3.5穿过它,意味着里面有很多内容
证明分解信任分解视图2.5展示部件,这正是其主张
承诺结尾平静平静保持1.5页面停止并等待点击

构建前的检查:

  • 结构的禁令得以遵守。
  • 来自 references/scene-kit.md 的四个或更多设备系列,且连续两次不使用相同的。
  • 没有两个相邻的幕共享同一种感觉。
  • 峰值拥有明显最大的跨度,且其前的一幕更为平静。
  • 结尾是解决并保持,而不是淡入页脚。
  • 跨度以屏幕高度为单位。一部电影般的页面通常在8到14之间;编辑和游乐场页面可以更短。永远不要为了达到数字而填充。

第2步:构建

mkdir -p <构建目录> && cp <技能>/engine/stage.js <技能>/engine/stage.css <构建目录>/

从 templates/starter/index.html 开始构建结构(导入映射、画布、章节、一个模块脚本),并借用你评过分的幕模式。永远不要交付起始模板或其Orbis副本。 每个页面都应基于其自身的简报来编写。

引擎的工作原理(engine/stage.js,阅读头部注释):

  • 页面是一个 <section data-act="name" data-span="2"> 的堆栈。每个部分持有一个.frame,该帧在该部分持续期间保持固定。
  • stage.act(name, { scene, camera, update(p, s), render(renderer, s), resize(w, h) }) 注册一个场景。p 在0到1之间横跨整个幕。s 包含 time、dt、pointer(平滑后的值,范围为-1到1)、velocity(滚动速度)、width、height、reduced、coarse。
  • 哪个幕占据屏幕中央,哪个就渲染。共享同一个scene对象的幕会一起更新,因此单个连续世界仅仅是多个幕指向同一个场景。
  • 一个幕需要跨度大于1才能使p移动。 p 是在帧保持固定的距离上测量的,因此跨度恰好为1时没有移动:p 会从0直接跳到1,任何与其绑定的内容都不会显示。请使用1.25或更大的值。
  • 每个部分都会获得 --p 作为CSS变量,因此标题可以在与3D相同的时间线上移动。
  • data-reveal 属性可以使任何元素在进入时淡入;使用 style="--i:2" 进行交错。
  • 使用 seg(p, a, b) 将一个幕拆分为多个节拍,并使用 ease.inOut 及其同类函数来塑造它们。
  • 无WebGL时:html.no-webgl 会显示每个幕的 .poster。为每个幕提供一个海报(图片或渐变)。

使用 stage.css 顶部的令牌(画布、表面、墨水、柔和墨水、强调色、强调色墨水、两种字体)设计主题。永远不要为单个项目编辑引擎;特定行为应放在页面自身的脚本中。

Three.js 来自导入映射中固定的CDN版本(jsdelivr上的 [email protected])。保持固定。如果你需要更新的版本,选择至少两周前的版本并重新运行检查。

在编写标记之前阅读 references/design.md,在添加第二个场景之前阅读 references/performance.md。

第3步:证明

cd <构建目录> && npm i playwright-core          # 每个构建文件夹执行一次;需要安装 Google Chrome
node <技能>/scripts/serve.mjs --root . --port 4600 &
node <技能>/scripts/shoot.mjs --url http://localhost:4600 --out shots/desktop
node <技能>/scripts/shoot.mjs --url http://localhost:4600 --out shots/phone --width 390 --height 844 --touch
node <技能>/scripts/shoot.mjs --url http://localhost:4600 --out shots/reduced --reduced-motion --positions 0,1

该脚本会将每一幕滚动到五个位置,等待平滑效果稳定,截取每个位置的截图,并写入 sheet.png。脚本在以下情况下会失败:页面错误、请求失败、无WebGL、某个幕绘制了空白内容、以及横向滚动。通过意味着脚本可以运行,但并不代表效果良好。

然后打开每个 sheet.png 并查看。 对于每个幕的每个位置:每行文字都能被阅读吗?场景是否展示了节拍所说的内容?在手机上,是否有任何内容被裁剪、遮挡或过小?峰值看起来像峰值吗?结尾是否解决?修复,再次截图,再次查看。

然后是感觉检查(references/feel.md):冷启动滚动,对每一幕用一个词描述你的感觉,然后与 BRIEF.md 中的曲线进行比较。如果两者不一致,则修复页面。

坦言哪些内容没有被覆盖:无头Chrome以软件方式渲染WebGL,因此它报告的帧率并非真实设备的情况,并且它无法告诉你滚动在实际手机上的感觉。在宣布完成之前,请要求用户在手机上打开它。

硬性规则

绝不而是
整个页面只使用一种场景设备四个或更多系列,且连续两次不使用相同的
将文字烘焙到纹理或图像中在画布上方使用真实的HTML
滚动箭头、鼠标图标或“滚动探索”什么都不做。英雄部分本身就已足够
像 01/05 这样的章节计数器删除它们
每个幕都居中排版多样化:左、右、居中、拆分、顶部、底部
使用全屏深色覆盖层来制造对比只在文本块后面使用 .scrim
渐变文字、霓虹光晕用字重和字号来强调
虚构的数字或统计数据仅使用来自用户的真实数据
在可见文本中使用长破折号使用句号、逗号、冒号
永不停止旋转的东西运动跟随滚动或指针;静止时的运动应缓慢且微小
每个部分都使用全新的WebGL渲染器一个画布、一个渲染器、多个场景(引擎已实现)
交付起始页面根据简报编写页面
在结构、日志和评分完成之前进行构建执行第1步,全部三件事
两个峰值,或没有峰值一个,拥有最大空间,且前一个幕较为平静
计划与之前的构建在日志的三列或更多列上匹配修改计划,永不修改日志
未完成第3步就宣布完成执行第3步,查看截图表格,进行感觉检查

输出

构建文件夹,然后是一份简短报告:结构和原因、针对每一行的指纹结果、旅程、情感曲线和峰值、评分表格、标志性动作、shoot.mjs 在所有三次运行中的报告、你在截图上看到的内容以及所做的修复、感觉检查(预期感觉与实际感觉的对比),以及你无法检查的内容。提供本地URL。然后将构建的行添加到 FINGERPRINTS.md 中。

相关技能