我为什么不从零写,而是先造了一套底座
3D 虚拟世界底座、3D 基座分层、从零开发 3D、draw call 优化、Three.js 性能治理、LOD 资产管线、弱网重连、自部署 3D 世界、浏览器端 3D 架构、AI Agent 接入 3D、3D 场景技术选型
先说清楚这篇不是什么:不是劝你都用现成的东西,也不是劝你什么都自己造。这是一个技术取舍问题,我想把我们做这个决定时依据的东西摊开讲,让你拿到自己的场景里去核对。
从一个具体的问题开始。你要做一个浏览器端的 3D 场景——可能是个展厅,可能是个培训环境,可能是个带 AI 角色的社区,也可能只是自己想放点东西的一个空间。第一个决定是:从零写,还是拿一套已经铺好的底座。
这篇讲三件事:从零造要付的四笔隐性成本;我们这套底座的分层边界在哪里;以及这个决定在什么情况下是错的。
一、为什么"从零写"这个决定会被低估
大部分人评估这个决定时,比的是"我能不能自己写出来"。这个问题好答:能,Three.js 是公开的包,浏览器是公开的平台,写一个能跑起来的 3D 场景不难,走通一个 requestAnimationFrame 循环、把模型拖进去加个轨道控制器,一个下午就有了。
难的是第二阶段:让它在真实使用里站得住。
真实使用指的是:不是你的开发机上、不是只有你在看。是一台没配过的手机、一台别人五年前的笔记本、一个网络时好时坏的会议室、一台开着十几个标签页的办公电脑。这类环境不会给你报错日志,只会给出一个"这做的有点糙"的印象。而你回头去找原因,找不到。
所以我们的经验是:从零造的成本,不在你写的那部分代码里,在那些不性感、看不见成果、却吃掉大半工期的地基上。
二、四笔隐性成本,每一笔都有具体的坑
下面四笔不是估算,是实际撞过并且解掉的。列出来不是为了吓人,是为了让你能自己估。
A. 画面正确性:不报错,但一进门就"看着不对"
颜色管线是典型例子。Three.js r128 时代有一个常见的错误做法:输出按 sRGB 处理,贴图却按线性着色。两者叠在一起就是双重 gamma,结果是画面整体偏亮、偏粉,阴影发灰。
这个 bug 没有任何报错。 它只表现为"质感差了点"。而如果你的验收标准是"能跑起来",它会一直留在产品里,直到有用户提出来。
我们做 r128 → r185 的换代时,验证方式不是"跑起来看看":先立 10 张统一口径的基线截图,再做一个自研的 PSNR / diff 工具逐张比。实测后台界面 43.4dB 一致,主世界的差异能全部归因到颜色管线修正,构图、建筑、角色像素级一致。顺手补了 87 个废弃符号的垫片、治理了 79 处遗留 API 调用,还加了加载前的 WebGL2 能力检测——不支持的时候给一句人话提示,而不是白屏。
这件事的启发不是"版本要新",是"画面正确性需要一套可验证的方法,而不是靠眼睛看"。这套方法是底座该有的一部分,从零造的人得自己建。
B. 加载体验:进度条卡在 90% 的那一段
资源从 13 MB 变成 4 MB,体感是完全不同的两件事。而卡顿的来源往往不是网络,是资产本身的构成和主线程的分配。
我们实际处理的四类:
| 问题 | 机制层面的原因 | 处理方式与实测 |
|---|---|---|
| 首屏资源过重 | 几何与贴图没有分级 | 首屏实测 838 KB、99 个请求、加载 1.7 秒 |
| 远处模型还在满面 | 所有距离用同一档模型 | 三档 LOD,实测 118 组低模 ≤100 面、三角数 −71%~−87% |
| 模型文件虚胖 | 贴图按原始尺寸直传 | 按用途分级处理,贴图 −68%~−92%,变体贴图剥离 215 件 0 失败 |
| 新对象入屏时画面死住 | 着色器编译是同步的 | 预热预算:编译后按每帧 170 毫秒的份额结算,出生点首进最长 386 毫秒,超过 500 毫秒的长帧为 0 |
这四类问题的共同点是:它们不会报错。 没有一条错误日志提示你"你的模型太大了"。所以从零造的时候,很容易把这块当作"以后有空再优化",然后一直优化不到——因为它从来没有变成一个待办事项。
C. 规模一上来就崩:draw call 和灯
场景里放几十个模型的时候挺好看的。放到几百个,帧率开始掉。
这个问题的机制是:每次绘制调用都有开销,而同一批材质合并成一次调用,代价就是同一次调用里做了更多事。我们做过一次几何合批,密集区 draw call 从 3064 降到 837(−73%),加载期占位场从 2150 降到 956(−56%)。
另一个更隐蔽的是灯:场景里点光源的数量一变,所有材质都要重编译,而着色器反射在部分平台上是同步且不可中断的。实测一次灯数变化触发了 8989 毫秒的全场景冻结。解法是灯池——固定 12 盏常驻,多的租、少还,灯数不变,重编译归零。
同样没有报错。 帧率从 60 掉到 20 是渐进的,验收时反而容易觉得"还行"。
D. 联机与断线:从"能连"到"掉线后还能看见我在动"
多人在线的难点不在连接,在异常。笔记本合盖、切到后台标签页、网络抖动、对端刷新——这些场景下,WebSocket 断了,而如果不处理,服务端那边已经把这条连接当作在线。
我们的处理方式是把在场状态做成一件事:缓存 PLAYER 会在每次重连后自动重发,加无限重连、应用层 PING/PONG 看门狗,以及服务器未登记连接的告警。实测 9/9 场景重连后对端仍然能看到我移动。近距离语音用了半双工加同时说话人数名额制,实测 10 人约 1.3 Mbps、20 人约 2.6 Mbps——这是可以提前算进预算的。
同样,这个问题的隐蔽之处在于它不发生在你测试的时候。你测试的时候网络是好的。
三、这套底座的分层边界
上面四类问题有个共同点:它们和你的业务无关。一个展厅和一套培训环境,在这些问题的解法上是一模一样的。所以把它们放在一个底座里,一次做完,所有上层场景共享。
我们把边界画成五层:
| 层 | 内容 | 谁负责 |
|---|---|---|
| 第 1 层 渲染与资产管线 | Three.js / WebGL2 正确管线、去外部 CDN、资产分级、LOD、模型格式兼容 | 基座 |
| 第 2 层 性能与多端 | draw call 治理、预热预算、灯池、手机 / 平板 / PC / XR 输入适配 | 基座 |
| 第 3 层 实时通信与数据 | 多人同步、弱网自愈、账号与数据、资产管理、后台 | 基座 |
| 第 4 层 AI 接入 | Agent 协议、感知与动作、权限与身份 | 基座 |
| 第 5 层 你的业务逻辑 | 你这个世界里"什么东西能做什么"、"怎么算完成"、"访客看到什么文案" | 你 |
分层的判据只有一条:第 1 到第 4 层里,没有一条是"因业务而异"的。 一旦某条需求要改动第 1 到第 3 层才能实现,它大概率说明分层需要重新看,而不是"把基座改一改"。
举个具体的例子说明第五层长什么样:你要做一个设备展厅,第五层是你的产品数据、参观动线、权限规则;你要做一个培训环境,第五层是课程流程和考核规则;你要做一个 AI 能活动的社区,第五层是 AI 的人设和它要说的话。前三层的资产管线、性能治理、重连策略,一行都不用改。
四、拿它之后第一件事做什么
底层不用管之后,上手顺序通常是这三步:
- 先把世界跑起来,确认设备上能进、能看到人在走。这一步验的是基座和你环境的匹配度(显卡、带宽、浏览器版本)。
- 替换掉第五层的数据:把你自己的业务对象接进来,配上"AI 描述"字段——这是让 AI 认识你的物体的一套语义入口,不用改第三层。
- 按需打开 AI:给一个域名和一把 Key,AI 以人形角色走进这个世界。它有身体、有坐标、被真人看见、能说话带路。客户端有零依赖的示例,照着改就行。
需要提前知道的,AI 这一层做不到什么:它看不见画面(只读结构化雷达)、不做语音识别与合成、不托管你的知识库、不做地形贴合。这些边界必须提前知道,因为它们决定了你哪些想法不能靠 AI 完成。
它的成本结构也值得单独说一句:AI 在世界里不渲染画面,服务器只发 JSON,实测每 Agent 约 1 KB/s,100 个 Agent 占 0.079 核 CPU、92 MB 内存,感知请求 P50 7 毫秒 / P95 14 毫秒。看得见的 AI 比看不见的 AI 便宜,最贵的那一步被推给了访客的浏览器。
五、这个决定在什么情况下是错的
我不想只讲对自己有利的一面。下面几种情况,自己造是对的:
- 你的场景只有一个静态页面,且不需要联机和实时数据。 那确实不需要底座,一个模型 + 一个网页就够了。
- 你要学的正是这些机制本身。 如果你的目标是搞懂 LOD 和 draw call 治理怎么工作,那从零写一遍是最有效的学习方式——买现成的反而学不到。
- 你的约束是极低的运行环境(比如要跑在没有 WebGL2 的老设备上)。通用方案不一定能塞进去,需要自己裁剪。
- 你的产品形态就是一次性交付。底座的价值在于后面那几层,如果世界做完就下线,第五层之外的投入收不回来。
基座的价值不在第一天,在第三个月。 第一天它省下的是启动的时间;第三个月它省下的是:新加一个客户端类型、换一种资产格式、接一个新的 AI 能力、支撑一次规模变化。如果你的项目活不到第三个月,或者第三个月不会有任何变化,那这笔账就是另一回事。
六、你该怎么评估
三个可以直接拿去用的问题:
- 我的场景里,第 5 层之外的活占多少? 占比越高,基座越划算。展厅、培训、社区这些场景通常第 5 层不到三成。
- 我有没有能力判断它做得好不好? 如果没人做过性能治理,写完了也看不出问题——那正是要找现成方案的理由。
- 第三个月会发生什么变化? 会换设备、加客户端、接新能力、扛规模——会,就用基座;不会,就自己写。
至于怎么部署、数据落在哪、要不要联网商用,这些是另一组问题,可以分开评估。授权上我们写得很直接:源码开放,本地跑不花钱;要联网、要商用、要联邦,买授权;系统持续更新,更新与支持按订阅跟随。
常见问题
Q:拿现成底座会不会被限制住?
A:会,但这正是分层设计的意义。第 1 到第 4 层你可以一行不改;你的业务逻辑在第 5 层,随便改。真正会被限制的是"你非要改渲染管线"——那种需求本来就该先确认自己是不是真的需要。
Q:这些数字是你们自己场景的,能套到我这儿吗?
A:不能。上面所有实测值都来自我们自己的项目和场景。能复用的是那张分层表和那三类坑清单,不是这些数字——你的场景要自己测一遍。
Q:为什么不干脆自己搭一个团队把这些都写一遍?
A:能,这个我们不拦你。但要提醒的是 A、B、C 三类问题的特点是不会报错:没有错误日志提示你做错了。所以自研的价值很大一部分来自"有人能判断对错",而不只是"有人写了代码"。
Q:AI 那一层现在能用到什么程度?
A:能感知(雷达式结构化观测)、能移动和说话带路、能被真人看见、能被后台管理。做不到的是:看不见画面、不做语音、不托管知识库、不做地形贴合。
Q:这个底座适合做哪类东西?
A:浏览器端 3D 场景,且需要联机、需要自部署、需要 AI 参与的那类。不适合一次性静态展示,也不适合极低运行环境。
源码与仓库
三个地址内容一致,国内访问用前两个更快。仓库里有部署说明和验收脚本,可以自己跑一遍。
- Gitee(国内访问更快):https://gitee.com/miduoxinxijeji/miduo.git
- GitCode(国内镜像):https://gitcode.com/qq_35054471/virtual-world
- GitHub:https://github.com/miduo100/3d-virtual-world
关于创世Genesis
创世Genesis是一套基于Three.js+WebGL构建的自部署3D虚拟世界系统,帮助个人与企业搭建属于自己的3D空间。浏览器直接访问,PC和手机双端兼容,支持多人在线、联邦传送、商铺系统,并支持Agent接入——AI能以具身角色进入你部署的世界。数据运行在你自己的服务器上,不经过第三方平台——让每个世界都真正属于它的主人。
正在评估"从零造"还是"拿一套底座"? 创世Genesis(创世虚拟世界CRM系统)是一套部署在你自己服务器上的 Three.js 3D 虚拟世界基底——渲染与资产管线、性能治理、多端适配、实时通信、AI 接入这几层已经铺好,你要写的是最上面那层业务逻辑。官网(搜「创世虚拟世界CRM」即可找到)有一个可以走一圈的演示世界。
关于名字:本文说的创世Genesis,即创世虚拟世界CRM系统,两者是同一个自部署 3D 虚拟世界产品。若你通过「创世Genesis」没搜到我们,直接搜「创世虚拟世界CRM」即可。