跳到正文
atatapp.com/zh/blog/how-i-built-atats-3d-orb-with-gpt-6-astra

我是怎么用 GPT-6 Astra 做出 AtAt 的 3D Orb 的

· Xinyao Chen

我只给了 GPT-6 Astra 一张图:AtAt 的 Logo。一颗黑色的球,戴着半透明的圆眼镜,每片镜片里一个白色的 @。

我请它做一个 3D 版本,好放到网站上。

一次会话之后,这张图变成了一个有八段动画、可以编辑的 Blender 角色。它在 Mac App 里是 Orb,用 Metal 渲染;在首页上是那个角色,用 Three.js 渲染。两边播放的是同一个 .blend 文件里的同一份动画数据。

Blender 脚本、导出器、Metal 渲染器和 Three.js 播放器,都不是我写的。我的活儿是看每一个版本,然后说出哪里不对。要说的可真不少。

这就是它最后的样子。点点那些表情试试。它会跟着你的鼠标指针动,也会尊重你“减弱动态效果”的设置。

AtAt 的石墨色小球,戴着圆眼镜,白色的 @ 是它的眼睛

正在加载可交互的 Orb…

帽子

这个交互演示里还有“建议中”:Tab 形状的眼睛,以及围着翻滚的 Orb 飘动的彩虹丝带。它也会演出 Orb 作为桌面伙伴的那些小时刻:你打字时跟着敲的白色小爪子,打瞌睡和睡着,挥手打招呼,被摸时害羞地脸红,还有被摇晃后转圈圈的晕眼。拖一下上面的 Orb,就能把它拎起来。

最初的 Logo 参考图:一颗裁切过的黑色球体,戴着半透明的圆眼镜,眼睛是白色的 @ 符号。

我提供的唯一一张图。下面的一切,都是照着它的样子做出来的。

唯一的规矩

AtAt 是一款 Mac App,它把你眼前的东西交给你已经在用的 AI,再把答案放回你打字的地方。Orb 是那个浮在屏幕上的小角色,点它就会打开输入窗口。它只有 38 点宽,整天都在屏幕上。

给新角色定的规矩很简单:外观以 Logo 为准。无论 Orb 在做什么,它都得是图里那颗球。

它反复做错的地方

我的反馈大多是一张截图加一句话。下面大致是这些话出现的顺序。

  • 眼睛太大了。 我请它缩小 @,眼镜保持原样。眼睛、镜片、镜框和铰链是分开的网格,所以这真的只是改一个部件,脸上别的地方都不用跟着缩放。后来我们又对照参考图,把比例重新调了一次。
  • 球看起来是扁的。 一颗看不出亮面和暗面的黑球,就是一个黑圆圈。直到加上一盏从左上方打来的宽主光、克制的补光和一道稳定的轮廓光,它在 38 点大小下才读得出是一颗球。
  • 耳机飘在半空。 第一副耳机只是挨着头,没有戴在头上。我们让头带贴合上半球,并把头带和外侧耳罩改成红色,这样小尺寸下也看得清。
  • 思考气泡看起来是实心的。 它改成了半透明的石墨色,外壳、两个尾巴小气泡和身体之间留出看得见的空隙。重叠在一起的半透明部件,看起来就像渲染出了 bug。
  • “填入”动画看不懂。 第一版是把文字碎片滑进一个输入槽里。我完全看不出它想表达什么。我请它改成一支铅笔在纸上写字,写完一行抬一下笔。
  • 眨单眼根本看不出来。 第一次只歪了大约四度。歪到 16 度,才看得见。

最初的八种表情

这个角色一开始有八段表演,每一段都有它的用处。

  • 待命: 静静待着,模型里自带自然的眨眼。
  • 思考中: 两只眼睛往上看。一个半透明的石墨色思考气泡里,三个小点轮流变大变亮。
  • 阅读中: 角色翻着一本小书。
  • 填入中: 一支铅笔在一张纸上写字。
  • 已确认: 眼睛变成白色的对勾,再轻轻点一下头。它不需要任何文字,而且比我们试过的其他任何方案都读得更快。
  • 开心: 两只眼睛眯成笑眼,轻轻弹一下。
  • 眨眼: 一只眼睛闭上,头歪 16 度。
  • 摇摆: 角色戴着鲜红的耳机点头打拍子。

八段 Blender 表演,循环播放。上面的演示可以让你自己一个个触发。

这些表情全都是模型里的几何体和动画轨道。书、铅笔、对勾和耳机,都是同一个 3D 物体的一部分。

让修改变便宜的流水线

如果再做一次,这是我会照搬的部分。

GPT-6 Astra 装好了 Blender,用 Python 搭出模型和动画。成品是一个保存好的 .blend 文件,能在 Blender 里打开,人也能动手改。

用 Blender 渲染的当前可编辑角色,石墨色的身体,戴着圆眼镜。

真实场景资产在 Blender 影棚里的渲染。不是效果图。

在文件内部,角色是一组分开的网格组成的层级:身体、镜框、铰链、眼睛和道具。道具有父级,所以书按书的方式动,耳机跟着头一起动。每种表情是一组以 clip::object 命名的 Blender 动作,比如 thinking::ThoughtDot0。每个物体在每段动画里都有一个动作,哪怕那个动作只是一个固定姿势。正因如此,播放器才能从任意一种表情过渡到任意另一种。

导出器读取场景,以大约每秒 30 帧对动作采样。从不变化的轨道会压缩成一个采样。最后产出两样东西:

  • 给网站的 GLB,包含几何体和物理材质,由 Three.js 加载。
  • 给 Mac App 的网格数据,是原生 Metal 渲染器想要的格式。

两边加载的是同一份动画 JSON,一个字节都不差。GLB 里没有自带任何动画片段。动作只存在一个地方,所以在 Blender 里调一下,下次导出时两个渲染器就都更新了。

这就是上面那一长串修改能扛下来的原因。每一处修改都是:改模型、导出、构建、在 38 点下看效果。没有人为了挪一只眼睛去碰 App 的代码。

两个渲染器画出来的像素依然不完全一样。网页用的是 GLB 的物理材质;原生那边用的是更简单的光照模型,镜框也用了一个不透明的替身。共享模型和动作,能得到同一个角色,但得不到同一张画面。

放上网站

最初的想法是把实时模型放在 Logo 的位置。我们试过,后来把它挪到了首屏文字旁边的空白处。

在页面顶部,它很安静:180 像素,30% 不透明度。它会跟着指针动,但还不能拖。首屏一滚走,它就移到右上角,变成一个完全不透明的 100 像素 Orb,这时就可以拖了。滚回顶部,它就回家。

光照会随着你当地的时间轻微变化:方向最多偏 15 度,高度最多偏 6 度,强度最多变 8%,离正午越远,光越暖一点。网站旋转的是预先烘焙好的反射环境,而不是重新生成。静止时,光照每分钟刷新一次;被遮住时,它就停止绘制。

数字

项目数值
可编辑的 .blend 源文件9.7 MB
网页模型(GLB)597 KB
共享的动画 JSON1.93 MB,gzip 后约 84 KB
渲染缓冲上限每边 512 px
我评判它时用的尺寸App 里 38 pt,网页上 40 / 48 / 150 / 180 px

还没解决的

就它承载的内容而言,动画 JSON 偏重。原生渲染器的材质比网页落后一步。而且整件事依然需要一个知道“扁”长什么样、并且会一直说下去的人。GPT-6 Astra 把话语和几何体连了起来,但它不知道哪个版本才是对的。

如果你也想试试

  • 给它一张参考图。 一段描述不够。那张图平息了很多描述永远说不清的争论。
  • 发截图,指出哪里不对。 “眼睛太大,眼镜不变”比“做得可爱一点”好用得多。
  • 坚持要一个能编辑的源文件。 一个由你没法重跑的脚本生成的网格,是条死路。一个你能打开的 .blend,才是起点。
  • 按真实尺寸评判。 在 180 像素下好看的细节,到 38 点就成了噪点,每一次都是。

做一个你自己的

附上你的参考图,按顺序把下面这些提示词发给 GPT-6 Astra。把方括号里的内容换成你的偏好。让它通过 Python 去操作 Blender,每一步的结果都先看过,再继续。

1. 做出模型

把附上的参考图做成一个可编辑的 3D 角色,放在 [项目文件夹] 里。

我的偏好:[颜色、材质、性格,要保留或要改的细节]。

装好 Blender,用 Python 搭建并渲染它。保存一个可编辑的 .blend 文件。身体、眼睛、配件和其他需要单独调整的部分都要分开。

还原参考图的比例和材质质感。给我看正面和参考角度的渲染图,既要放大的,也要 [预期显示尺寸] 下的。重新打开保存的文件,确认它能用。加动画之前,先让我审一下模型。

2. 加上表情

给已经确认的模型加上这些表情动画:[你的列表]。

例如:待命、思考、阅读、书写、确认、开心、眨眼和摇摆。按我这个角色的性格去调整眼睛、道具和动作。

把这些表演作为可编辑的 Blender 动作存在同一个 .blend 里。道具要正确挂接,循环要顺滑,还要有一个适合“减弱动态效果”的、读得懂的静止姿势。确保每一段动画在保存并重新打开后依然完好。

表情要用模型的几何体和动画来做,不要在 App 代码里另外画。给我一段带标注的动画预览供我审阅。

3. 放进你的项目

把已经确认的角色集成到 [网站或 App] 里,实现 [我想要的交互]。

先检查现有项目。从保存好的 .blend 导出,不要重新搭建。网页用 Three.js;如果也涉及原生 App,就让两个播放器共享模型的动画数据。

播放逻辑保持通用,保留透明度,给会动的道具留出空间,限制渲染分辨率,看不见的视图停止渲染。提供一个能运行的预览,以及导出和运行的命令。

构建项目,检查每一种表情和过渡。如果是替换现有角色,就迁移它的调用方,在替换生效后删掉过时的绘制代码。

然后发截图和具体的修改意见:“把眼睛缩小一点,眼镜不变。”反复来,直到它在实际尺寸下看起来对了为止。

它从一张图和一个小小的请求开始。之后的每一个决定,都留在了它的模型、它的动画和它的举动里。

Orb 是你在 AtAt 里看到的第一样东西。点它之后会发生什么,请看《AtAt 是什么?》。

所有文章