篇目 31 · 讲座精读

SLIM:把一片 UGC 世界从 5940 万三角形压到百万级

SLIM · 同一份引擎与同一批用户生成内容要跑八个平台,高端算力约是低端的 800 倍,世界还一直在变,「离线 cook 再冻住」这条路走不通。这一场把 cook 搬进云端,把优化单元从一块资产放大到整片世界,再让每个客户端按预算自己挑细节:描述符只带引用不带字节,归一化后哈希做跨游戏去重,世界转码器去内部面、建多级 LOD,运行时按「每加一字节消除的可见误差」打分。同一场景同一相机下实例 −97%、三角形 −98%、draw call −74%、显存 −33%,是单个演示场景的读数;讲者给的平台级指标不可复现

讲者 Sergey Makeev(Roblox)· 21 张原样引用(源 slide 0–63) 出处 SIGGRAPH 2026 Advances in Real-Time Rendering in Games 许可:非 CC(逐页页脚 © 2026 SIGGRAPH … All Rights Reserved.,无 CC 声明、无代码许可)· 逐件登记、逐图署名 · 未修改 精读执笔 · 浅墨
14 章一级章节(按拆解点切)
0 式讲义未给公式,本稿不补推导
21 张配图(原文 21 / 自绘 0)
6 条边界与反例(独立成节)

图-段配对表 · 本稿 21 张

图角色档归属支撑的论断层次状态
图 1-1E§1平台体量:每天 120 万网格、八个平台、约 800 倍算力跨度、20 年 700+ PB①②③讲义 slide 5 · 原样引用
图 2-1E§2演示场景基线:约 17.2 万实例、5940 万三角形、约 3500 draw call①②③讲义 slide 6 · 原样引用
图 2-2E§2三根支柱与三档读数:5940 万 → 桌面 470 万 / 平板 240 万 / 手机 110 万①②③讲义 slide 9 · 原样引用
图 3-1E§3取件协议:资产 ID + 精确版本 + 有序格式清单(BC1→ETC2→原始)①②③讲义 slide 14 · 原样引用
图 3-2E§3未命中路径:入队转码任务、抓精确源版本、产出新 ACR 后落缓存①②③讲义 slide 16 · 原样引用
图 4-1E§4生产量级:约 1200 万请求/秒、960 台转码器、约 16.8 万 GHz、8.3 TB RAM①②④讲义 slide 19 · 原样引用
图 4-2E§4ACR 定义与两条版本轴:源版本 vs ACR 格式版本①②③讲义 slide 20 · 原样引用
图 5-1E§5纹理管线演进:PNG 客户端解码 → 云端块压缩 → PBR → 拆分 ACR/RDO → KTX2①②③讲义 slide 24 · 原样引用
图 5-2E§5网格管线演进:2016 文本格式 → 2021 导入期 LOD → Draco → 渐进流①②③讲义 slide 25 · 原样引用
图 5-3E§5阶段结论与吞吐:27K/24K ACR/分、136M+/h 取用,及「一次只见一块资产」①②④讲义 slide 26 · 原样引用
图 6-1E§6SLIM 定义:把同一套转码机具用到活世界的选定区域①②③讲义 slide 29 · 原样引用
图 6-2E§6SLIM 描述符:只带引用不带字节;自动边界选择仍是 work in progress①②③讲义 slide 30 · 原样引用
图 7-1E§7归一化后哈希:剥掉子树顺序/命名/浮点噪声,等价模型逐字节相同①②④讲义 slide 32 · 原样引用
图 8-1E§8世界转码器动作:60 源网格 → 1 几何块、13 源材质 → 1 运行时材质①②③讲义 slide 34 · 原样引用
图 8-2E§8去内部面:BVH + 面积布点射线,任一射线逃出即保留①②③讲义 slide 41 · 原样引用
图 9-1E§9自研网格简化:不用半边结构,QEM + 面积损失罚项;出处 Liu, Zhang & Yuksel 2025①②③讲义 slide 43 · 原样引用
图 10-1E§10运行时双预算:三角形目标 + 固定 GPU 字节池,按可见误差/字节打分①②④讲义 slide 47 · 原样引用
图 10-2E§10结果表:实例 −97%、三角形 −98%、draw call −74%、显存 −33%①②④讲义 slide 48 · 原样引用
图 11-1E§11动态 SLIM 切分:服务端可变模型 + 客户端不可变制品 + 参数快照①②③讲义 slide 57 · 原样引用
图 11-2E§11网络复制预算:本地已算零开销、不可靠无重传、五次惯性化①②③讲义 slide 58 · 原样引用
图 12-1E§12诚实边界:四类收益锐减场景,回退是让优化保持正确的机制①②③讲义 slide 60 · 原样引用
角色档按 20 号票的裁决:E 类(承载可核对数值或作为唯一证据)禁止自绘,故本篇 21 件证据全部引用讲义原页(幻灯区切片位图带);本篇 S 类图为 0,S 类配额为 0,自绘 0 张。
许可:全 64 页页脚逐页标注 © 2026 SIGGRAPH Advances in Real-Time Rendering in Games course. All Rights Reserved.(右侧并带 ROBLOX 字标),全文无 Creative Commons 声明,亦无代码许可(无 MIT / open source / GitHub),→ 按分区非 CC 口径处理:逐件登记、逐图署名(图号 + slide 号 + 出处 + 版权行 + 「未修改引用」),并标注残留风险(讲义未授权转载,条款以官方发布为准),不得写成 CC 或可自由转载。讲义 slide 43 只给出算法论文出处(Liu, Zhang & Yuksel 2025),不是代码许可。
开篇要接住的那个问题 讲者开篇(英文原样引用 · 讲义 slide 0)

"Hello, everyone. My name is Sergey Makeev, and I'm a Senior Technical Director at Roblox. Today I'll talk about scaling user-generated 3D worlds: why rendering on Roblox is a hard problem and how we approached it. I'll give you some context about the platform, show you a demo, and then dig into how it all works."

这一篇要讲清的五件事
  • 先抹掉常规假设:Roblox 是平台,涵盖引擎、云服务、内容系统与社区;一个渲染器要接住没有单一美术方向、没有固定内容预算、没有已知硬件目标的用户生成内容(讲义 slide 2)。世界由服务端持有的活数据模型驱动,「静态」只是假设(讲义 slide 3)。
  • 三根支柱:资产转码器保留稳定版本化的源、按需派生运行时形态(讲义 slide 10–26);SLIM(Scalable Lightweight Interactive Models)世界转码器把同一套契约用到世界的选定区域(讲义 slide 29–44);运行时编排让每个客户端在两份固定预算上挑细节(讲义 slide 45–48)。
  • 一句话结论:发布冻结的是源,不冻结优化。编码器或 LOD 算法变好,二十年老内容在下一次请求里自动升级,创作者不必重做(讲义 slide 26)。
  • 收益读数要带口径:实例 −97%、三角形 −98%、draw call −74%、显存 −33% 是同一场景、同一相机的引擎内实时抓帧,绑定单个 kitbash 演示场景,不可外推(讲义 slide 48)。
  • 诚实的边界:结构频繁变动、一次性唯一几何、严格低延迟、过度聚合四类场景收益锐减;未来工作按讲者原话是研究方向,不是已发布功能(讲义 slide 60、62)。

1先把常规假设抹掉:Roblox 的平台前提

 先把常规假设抹掉:Roblox 的平台前提

开篇先把讲台立稳。讲者自报姓名与职位:Sergey Makeev,Roblox 的高级技术总监(Senior Technical Director)。这场讲的是用户生成三维世界的规模化渲染,两件事并排:为什么在 Roblox 上做渲染是件难事,以及他们怎么应对(讲义 slide 0)。随后他放了一段混剪多个 Roblox 游戏的视频,并请观众记住一条:视频里每个游戏都跑在同一份引擎上,同一版代码与内容必须在他们支持的全部设备上都跑得好,这个跨度是 Roblox 渲染难做的很大一块(讲义 slide 1)。

接下来讲者给 Roblox 划界。单一游戏、单一虚拟世界、可以对外授权的引擎,这三个说法都不足以概括它;Roblox 指的是平台本身,由引擎、云服务、内容系统,以及建立其上的创作者与玩家社区组成(讲义 slide 2)。视频里看到的一切都是用户生成的:创作者做世界、化身、服装与工具,平台负责把它们投递到主机、PC、手机、平板、VR 头显,甚至智能电视。对一个渲染工程师来说,这份定位抹掉了平时赖以立足的三条假设,没有单一美术方向、没有固定内容预算、没有已知硬件目标,渲染器只能去接住创作者接下来做的任何东西。

世界的心脏是数据模型(data model)。它是一棵活的对象树:对象、属性、脚本,以及对资产的引用;讲者给的类比是三维世界里的 HTML DOM(讲义 slide 3)。游戏服务端持有仿真并持续更新这棵树,脚本与物理随时能改动任何东西,每个客户端只收到它需要的那部分。他们自家的编辑器 Roblox Studio 用的是同一套数据模型与同一份引擎代码,上面再叠协作式多人编辑。这件事的分量在于:在 Roblox 上,「静态」只是假设,从来不是保证,凡依赖离线优化或一次性烘焙的常规手法都被排除在外;一个典型的 Roblox 世界一直在变,从不到达稳定态。

把镜头换到内容投递这一侧(讲义 slide 4)。创作者点一下「发布」,新版本立刻在所有设备可用;玩家不装 build、不等补丁,加入一个 Roblox 游戏更接近打开一个网页。玩家进来时,服务端开始复制这份活的数据模型,网格、纹理与音频另从 CDN 到达,而这一切发生的同时世界还在变:仿真在跑,资产随玩家走动流进流出。这里同样没有稳态,也没有一个可以说「世界到此定稿」的时刻。

体量把上面两条前提压得更实(讲义 slide 5)。每天创作者上传约 120 万块网格与 160 万张图片;随便哪一天,约 26% 的头部 1000 款游戏会推一版更新,直达数以百万计的玩家。这些内容都得跨八个平台跑通,而高端设备的算力约是低端设备的 800 倍。二十年积攒下来的内容超过 700 PB,其中很多还要跑在它诞生时并不存在的设备上。于是也没有「内容完工」这一步:新内容不断进来,老内容必须继续能用,硬件目标一直在动。

平台体量页
图 1-1 E 类·证据 · 讲义 slide 5 · 原样引用 怎么读 ①指认:页面把每日上传量、平台跨度、头部游戏更新比例与内容存量并列,讲者备注里给的是约数(约 120 万网格、160 万图片、约 800 倍算力跨度、约 26%、700+ PB),页内表体的精确排版由位图 OCR 读出。②读法(怎么读):先记住这一页是体量页而非性能页,四个读数分别对应上传速率、硬件跨度、内容更新节奏与存量;再把它与本章 p2 的三条假设接起来读,它们共同解释「内容完工」这一步为何不存在。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

这一页的读数需要口径限定。120 万网格/日、160 万图片/日、约 800 倍算力跨度、26% 头部游戏更新、20 年 700+ PB 全部是讲者所述的平台级指标,页内表体由幻灯片位图 OCR 读出(讲义 slide 5(OCR)),既无论文也无受控实验,不可复现,也不能当作某个可搬走的基准数。

讲者在开场视频里特意请观众带着一个前提去看:视频里每个游戏都跑在同一份引擎上,同一版代码与同一批内容要在他们支持的全部设备上跑得好。这条约束贯穿全篇,也解释了后面为什么要把优化推迟到运行时:没有哪一次提前的、面向某个目标的决定能一直有效,因为目标本身由创作者与玩家随时改写。

把 p2 到 p5 连起来,本章能核对的结论有三条。Roblox 作为平台,把美术方向、内容预算、硬件目标这三条假设一并交给创作者随机决定(讲义 slide 2)。世界由服务端持有的活数据模型驱动,「静态」不成立,凡依赖离线烘焙的手法都被排除(讲义 slide 3、4)。体量一侧的读数是每天约 120 万网格与 160 万图片上传、八个平台、约 800 倍算力跨度、20 年 700+ PB,均属讲者所述平台级指标(讲义 slide 5(OCR))。下一章把这份体量落进一个具体场景,看一帧要花多少三角形。

2一帧 5940 万三角形的 UGC 世界与三根支柱

上一章把体量摆在前台,这一章把它落进一个具体场景(讲义 slide 6)。讲者先自嘲:他是图形工程师,不是美术,但这个演示是按很多创作者的做法搭出来的,从目录里拿几千个资产做 kitbash。它带着这类场景该有的性质:三角形与纹理密度不均、小物件成堆、重叠几何很多。单个资产各自都没问题,可几十万个凑在一起就成了一个低效场景。这个场景大约有 17.2 万个数据模型实例;朴素渲染一帧是 5940 万个三角形与约 3500 次 draw call。讲者给的判词很直:这贵到连桌面都渲不动,而它必须跑在一台 100 美元的手机上。

演示场景基线页
图 2-1 E 类·证据 · 讲义 slide 6 · 原样引用 怎么读 ①指认:页面是一张 UGC 场景的渲染图加三组读数,讲者备注给的是约数(约 17.2 万实例、5940 万三角形、约 3500 draw call),幻灯区表体的精确数 172,531 实例与 3,526 draw call 为 OCR 读出。②读法(怎么读):把三个读数当成「朴素口径」的起点记下来,后文所有收益读数都以它为基线;精确数字段须以 OCR 口径读、并接受人工过图复核。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

这一页的精确读数同样要标口径:172,531 实例与 3,526 draw call 来自幻灯区位图的 OCR 读出,讲者备注里对应的是约 17.2 万与约 3500(讲义 slide 6(OCR))。两组数说的是同一件事,正文以备注的约数为陈述口径,精确数只作 OCR 补充,不合并成第三个数字。这个场景的构成方式也须记牢:它是单人用目录资产拼出来的 kitbash 场景,后文所有百分比读数都绑定它。

然后就是结果(讲义 slide 7、8)。桌面上一段 4K 的实时视频,用的是他们称为 SLIM 的优化表示;换到手机上放同一场景,数据模型相同、资产相同、引擎相同,没有单独的移动版,唯一的差别是运行时表示(runtime representation)。这一段把整篇的账当场兑了一次:同一个世界,两种表示,两类设备。讲者在这一页没有报新数字,桌面 4K 与手机两段视频的作用是让观众先看到结论,再回头看它是由什么换来的。

三根支柱与三档读数页
图 2-2 E 类·证据 · 讲义 slide 9 · 原样引用 怎么读 ①指认:页面左侧是朴素与三档设备的三角形数,右侧是三根支柱的名字(资产转码器、SLIM 世界转码器、运行时编排),页内表体的精确排版由位图 OCR 读出。②读法(怎么读):先把 5940 万当成朴素基线,再读三档如何逐级下探;三根支柱的顺序就是后文三段的顺序,第 3 到第 5 章讲第一根,第 6 到第 9 章讲第二根,第 10 到第 11 章讲第三根。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

数字在讲义 slide 9 一页上给全。朴素渲染这个场景每帧要约 5900 万个三角形;用上 SLIM 后,桌面降到 470 万,平板 240 万,手机只要 110 万。这一组读数出自幻灯区表体,为 OCR 读出,讲者备注给的对应值是约 5900 万、470 万、240 万、110 万(讲义 slide 9(OCR))。讲者随即给出三根支柱。第一,资产转码器(asset transcoders):把创作者内容保留为稳定、带版本的源数据,需要什么运行时形态就派生什么。第二,SLIM 世界转码器:同一套概念,从一块资产推广到整片世界。第三,运行时编排(runtime orchestration):每个客户端在自己的内存、渲染与网络预算里挑最合适的那一档细节。

把三根支柱与三档读数并排看,能得到这一章的落点。转码器负责按稳定源派生出更轻的形态,世界转码器把这件事从单块资产放大到整片区域,运行时编排负责在每台设备上按预算挑一档。三者分工清楚,也解释了讲者为什么把 SLIM 这个缩写放在演示视频那一页:它在这里指整条流水线的名字,涵盖资产转码、世界转码与运行时编排三处。至于每台设备具体怎么省下三角形、省到什么程度,要等第 10 章把两个预算摆出来才说得清。

本章可核对的结论有三条。演示场景是单人用目录资产拼出的 kitbash 场景,约 17.2 万实例、朴素 5940 万三角形、约 3500 draw call(讲义 slide 6(OCR))。同一场景在桌面 4K 与手机上实时跑通,数据模型、资产、引擎都相同,差别只在运行时表示(讲义 slide 7、8)。SLIM 把每帧三角形降到桌面 470 万、平板 240 万、手机 110 万(讲义 slide 9(OCR)),支撑它的三根支柱分别是资产转码器、SLIM 世界转码器与运行时编排。下一章展开第一根。

3可变世界里的稳定输入:内容平台取代离线 cook

上一章把三根支柱的名字立起来,这一章展开第一根(讲义 slide 10)。分隔页把资产转码器的想法压成一句话:保留源,派生运行时形态。为什么需要它,p11 给了动机:Roblox 世界从不安静下来,实例来来去去,脚本改属性,物理挪东西,这不是边角情形而是常态;他们没法把世界冻住再跑离线构建或烘焙。讲者在此处补了一句限定,世界一直在变,并不等于所有东西一直在变,后面这句限定会变成整套机制的地基。

接下去是这块地基本身(讲义 slide 12)。活的数据模型可变,它引用的资产不可变。一条资产引用指向唯一一个精确且不可变的版本:确定的纹理字节、确定的网格数据。创作者编辑资产时,系统生成一个新版本,旧版本底下的字节永远不会被改动。于是世界尽管一直在变,资产引用仍然提供稳定的输入,后面所有机制都站在这上面。

稳定归稳定,固定格式这件事并不成立(讲义 slide 13)。资产被创建的时候,谁也不知道它将来会被什么设备取用;压缩格式随平台而变,编码器一直在改进,新平台不断加入,他们自家的格式在内容发布很久之后还在演进。一套永久编码无法服务所有设备。他们也不要求创作者重发老内容,既有内容必须自动前向兼容,这件事听上去最初几乎做不到。

答案在 Roblox 的内容平台(content platform)(讲义 slide 14)。讲者走了一遍取件请求:客户端从数据模型里取一条资产引用,发出资产 ID、精确版本,以及一份它认识的格式清单。这个例子请求的是一张纹理,先 BC1,再 ETC2,最后回到原始源。次序有意义,第一项是首选,其余是兜底。内容平台把这份 ID、版本与格式解析成真正的内容字节。

内容平台取件请求页
图 3-1 E 类·证据 · 讲义 slide 14 · 原样引用 怎么读 ①指认:页面画的是客户端到内容平台的请求流程,请求体三项分别是资产 ID、精确版本与有序格式清单,例子里是 BC1 优先、ETC2 次之、原始源兜底。②读法(怎么读):把「有序」两个字读重,清单的次序决定首选与兜底;再把它与本章的「稳定源、可变格式」接起来,这份清单回应的是「一套永久编码不够用」这件事。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

命中是最省的一条路(讲义 slide 15)。所要形态已经存在,平台回一个 CDN URL,客户端直接下载,什么都不用重建,问同一件事的每个客户端拿到同一个结果。未命中的路要长一些(讲义 slide 16):创作者当初只传了源,运行时格式是派生出来的;想要的表示不在,平台就提交一个转码任务,任务进队列,转码器取走,抓来那个精确的源版本处理,这个例子里是生成 mipmap 并压缩纹理,结果作为该资产的一个新表示发布。此后它就是缓存内容,后续请求一律复用。这段工作是异步的,所以未命中这条路还需要一条安全的回退。

未命中路径页
图 3-2 E 类·证据 · 讲义 slide 16 · 原样引用 怎么读 ①指认:页面画的是缓存未命中时的流程,关键节点是提交任务、进队列、转码器取走、抓精确源版本、产出新表示并落缓存。②读法(怎么读):与图 3-1 成对读,图 3-1 是命中侧的一步到位,这一页是未命中侧的异步补课;重点在最后几步,结果一旦产出就退化成普通缓存内容。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

客户端不会等转码跑完(讲义 slide 17)。首选格式缺失就试清单里的下一个;优先级更低但已经就绪的格式先用着,首选同时继续在云里生成;一个都没就绪,服务端回一句「没准备好,稍后再试」,客户端就照做。讲者在这里点出关键:回退属于内容契约的一部分,它让新格式可以出现而不必卡住游戏。讲义 slide 18 把整幅图景收拢,传统的资产 cook 没有凭空消失,它挪进了内容平台内部,对用户不可见、按需运行;一份稳定的源产出任意多的运行时形态,每个结果都被缓存、被共享。

这份契约的力气在于它把「新格式上线」与「游戏能不能跑」解耦了。首选格式还在云端排队时,客户端已经用兜底格式把画面撑起来;一个都没就绪也只是收到一句稍后重试,并不构成会话的中断。讲者把这条路径称为安全的,安全指的是它不会因为格式演进而掐断正在进行的游戏。

本章可核对的结论有三条。资产引用指向唯一确定且不可变的版本,这是整条链路的地基(讲义 slide 12)。取件请求由资产 ID、精确版本与有序格式清单三件组成,首位优先、其余兜底(讲义 slide 14)。未命中时平台入队转码任务、抓精确源版本、产出新表示并落缓存,客户端不等转码,回退属于内容契约(讲义 slide 15、16、17)。下一章给这些派生形态起名字,并把系统的生产量级摆出来。

4生产量级与 ACR:两条版本轴

上一章讲清取件的两条路,这一章把系统的名字与量级补齐。讲义 slide 19 先说那幅图被简化过,真实系统还管审核、权限、本地化、负载均衡等一大堆事。然后是量级:在生产规模上,它每秒服务约 1200 万次请求;转码器机队有 960 台服务器,合计约 16.8 万 GHz 的 CPU 算力与 8.3 TB 内存。这三个读数都是讲者所述的平台级指标,页内表体由位图 OCR 读出(讲义 slide 19(OCR)),无论文与受控实验,不可复现,也不代表某个可搬走的基准。

生产量级页
图 4-1 E 类·证据 · 讲义 slide 19 · 原样引用 怎么读 ①指认:页面是一张机队与请求量的规模图,讲者备注给的是约数(约 1200 万请求/秒、960 台、约 16.8 万 GHz、8.3 TB),页内表体的精确排版由位图 OCR 读出。②读法(怎么读):把这些数读成运营指标而不是实验结果,它们说明这套转码体系承担的真实负荷,不构成任何可复现的性能对照;同页还说明图被简化,未画出审核、权限、本地化与负载均衡。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

派生的形态到这里有了正式名字(讲义 slide 20)。每个派生形态称为一个替代内容表示(alternative content representation),缩写 ACR。一个资产 ID 下挂着多个不可变的源版本,每个源版本产出许多 ACR:纹理编码、网格 LOD、遮挡数据等等。这里要记住两条互相独立的版本轴,创作者编辑资产,得到一个新的源版本(source version);转码器代码变化,从同一个源得到一个新的 ACR 格式版本(ACR format version)。ACR 走内容寻址、被缓存、被去重;源是永久的,每一个 ACR 都可弃,因为系统随时能重新生成它。

ACR 与两条版本轴页
图 4-2 E 类·证据 · 讲义 slide 20 · 原样引用 怎么读 ①指认:页面把「一个资产 ID、多个源版本、每个源版本多个 ACR」画成两层结构,右侧标出源版本与 ACR 格式版本两条轴。②读法(怎么读):先分清两条轴的触发条件,编辑资产动的是源版本,改转码器代码动的是 ACR 格式版本;再读「源永久、ACR 可弃」这条不对称,它解释了平台为何能回收旧格式。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

由此多出一条很有用的性质(讲义 slide 21):新旧引擎版本可以共存,即便资产格式变了。每个引擎版本只请求它认识的格式,平台从同一个源服务不同的 ACR,没有全局转换也没有协同升级;当老客户端不再请求某个旧格式,平台直接回收它。再往下是执行位置的自由(讲义 slide 22):同一份输入无论在哪里跑都产出同一份结果,于是执行地点变成一个部署选择。在云里,转码器产出的结果与数百万玩家共享;同一份转码器也能跑在 Studio 或客户端上,生成即时的本地预览;还能跑在游戏服务端,处理游戏局内现场生成的内容。决定放在哪里的是延迟、算力、复用与信任,代码本身不决定这件事。

两个真实例子把这条自由落到画面上(讲义 slide 23)。上面那段视频是 Cube4D,他们那个在运行中的游戏里生成内容的生成式 AI 模型:玩家描述一个物件,模型在游戏会话里直接产出网格、纹理与脚本;这种情况下转码发生在游戏服务端,结果可以只服务本局、可以发布到平台、也可以被玩家否掉丢弃。右边那段视频是 Roblox 妆面,玩家直接编辑的一层分层纹理,它会触发两个转码任务:一个本地任务给即时的、只有该玩家可见的预览,一个云端任务做安全检查、更好的压缩与跨游戏共享。两处走的是同一份契约,工作只是跑在需要它的地方。

这套机制能长期跑下去,靠的是 p21 与 p22 给出的两条性质。旧格式的退场是被动的,平台等老客户端不再请求它才回收,无需一次全局切换;执行位置的选择是主动的,云端、编辑器、游戏服务端三处跑同一份代码,把结果留在需要它的地方。两条性质都建立在同一个前提上:处理是确定性的,输入是稳定且带版本的。

本章可核对的结论有三条。ACR 是派生形态的正式名字,一个资产 ID 挂多个源版本、每个源版本产出多个 ACR,源永久而 ACR 可弃(讲义 slide 20)。生产量级为每秒约 1200 万请求、960 台转码器、约 16.8 万 GHz 算力与 8.3 TB 内存,全部是讲者所述平台级指标(讲义 slide 19(OCR))。同一份输入无论在哪跑都产出同一份结果,执行位置成为部署选择,决定它的是延迟、算力、复用与信任(讲义 slide 21、22、23)。下一章把两条管线的演进史摆出来,看这套机制如何吃到二十年的老内容。

5纹理与网格的两条时间线:发布冻结的是源

上一章给派生形态起了名字,这一章用两条时间线证明这套机制的收益落在哪里。先看纹理(讲义 slide 24)。早期每个客户端下载 PNG、解码、生成 mipmap,再在运行时建一张未压缩的 RGBA 纹理;能用,但每个客户端都要付这份成本。约 2013 年他们开始用一台临时凑的云端纹理转换器产出 GPU 原生、块压缩的纹理,那台转换器只处理纹理、只支持少数几种硬编码格式。2019 年上了 PBR 材质,几层纹理必须一起处理,因为生成 mipmap 时法线贴图会影响粗糙度,这一步把他们推进了转码器时代。有了转码器,2025 年他们把纹理拆成多个 ACR,可以从 CDN 渐进流式拉取,同年还上线了率失真优化(rate-distortion optimization),明显压低了纹理下载体积。今天转码器用现代编码器产出 KTX2 纹理,并支持渐进式纹理流。而源从未变过:二十年前上传的一张纹理,这些改进全都自动拿到。

纹理管线演进页
图 5-1 E 类·证据 · 讲义 slide 24 · 原样引用 怎么读 ①指认:页面是一条纹理管线的时间线,节点从早期 PNG 客户端解码、约 2013 云端块压缩、2019 PBR 分层一起处理、2025 拆分 ACR 与渐进流,到今天出 KTX2。②读法(怎么读):沿时间线看「处理搬到了哪一侧」,压力一路从客户端挪到云端转码器;末尾那句「源从未变过」是全章要记住的话。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

网格走了一条相似的路,中段还绕了个小弯(讲义 slide 25)。2016 年起用的是简单的文本格式,每个客户端在加载时解析这些文本文件。2017 年他们开始在导入阶段生成二进制文件,这是上传前的客户端处理步骤。到 2021 年,导入还支持换肤网格并自动生成 LOD,但这些处理都发生在上传之前,实际上改写了源资产的定义。问题在这里冒出来:每做一次改进就多出一种网格格式,因为老网格改不动;峰值时引擎同时支持十种不同的网格格式,包括最初那套文本格式。LOD 也吃了同一个亏,它只在导入时生成一次,后来更好的算法与修好的 bug 都惠及不到既有资产。转到转码器之后就不一样了:他们上线 Draco 压缩压低下载体积,又把最新的网格简化器接进转码器,于是每一块既有网格都拿到了更好的 LOD,没人需要重传任何东西;现在他们还在上面叠渐进式网格流。

网格管线演进页
图 5-2 E 类·证据 · 讲义 slide 25 · 原样引用 怎么读 ①指认:页面是一条网格管线时间线,节点含 2016 文本格式、2017 导入时转二进制、2021 换肤与自动 LOD、Draco 压缩与渐进式网格流;页内还标出峰值同时支持十种网格格式。②读法(怎么读):重点看 2021 那一段,处理发生在上传前就等于改了源的定义,这里解释了「每改进一次就多一种格式」的来处;再接 Draco 与简化器上线的转折读。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

讲义 slide 26 给出这段历史的结论:发布冻结的是源,不冻结优化。每当他们做出更好的编码器或更好的 LOD 算法,老内容在下一次请求里就拿到全部改进;他们改善二十年的内容,不请任何人重做。这套东西跑在很大的规模上:每分钟约产出 2.7 万个纹理 ACR 与 2.4 万个网格 ACR,每小时有超过 1.36 亿个 ACR 从 CDN 取用。这三个读数是讲者所述的平台级指标,页内表体由位图 OCR 读出(讲义 slide 26(OCR)),不可复现。同一页还给出资产转码器的一条硬上限:它一次只看得见一块资产;一个由数百万块各自最优的资产组成的世界,渲染起来仍然太贵。

阶段结论与吞吐页
图 5-3 E 类·证据 · 讲义 slide 26 · 原样引用 怎么读 ①指认:页面把阶段结论「发布冻结源、不冻结优化」与三档吞吐读数并排,讲者备注给的是约数(约 2.7 万、2.4 万、超过 1.36 亿),页内表体由位图 OCR 读出。②读法(怎么读):三档吞吐是运营指标,读它来说明规模而非性能;页脚那条「一次只见一块资产」的硬上限是下一章的引子,它逼出「优化单元必须长大」的结论。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

这段历史里有一处代价讲者没有回避:早期每个客户端都要自己解 PNG、生成 mipmap、建未压缩纹理,这份成本在每一台设备上重复支付;等到处理搬到云端,客户端只剩下载与使用。二十年的老内容之所以能一路跟进,靠的是源与派生形态被彻底分开,这处分开在下一章会被推得更远,从一块资产推到整片世界。

本章可核对的结论有三条。纹理与网格的管线各自演进,每一次改进都曾多出新格式,峰值时引擎同时支持十种网格格式(讲义 slide 24、25)。转码器时代让老内容随下一次请求自动拿到编码器与 LOD 算法的改进,源始终不变(讲义 slide 26)。吞吐读数为每分钟约 2.7 万纹理 ACR 与 2.4 万网格 ACR、每小时超过 1.36 亿次 ACR 取用,均属讲者所述平台级指标(讲义 slide 26(OCR));而资产转码器一次只见一块资产,这条硬上限把问题推到整片世界上。

6从一块资产到整片世界:SLIM 与描述符

上一章收在资产转码器的硬上限上,这一章把优化单元放大(讲义 slide 27,本页另有 [time check 21:00] 标记)。p28 把理由说得很平实:Roblox 世界由许多小的、可复用的部件搭成。一块立方体可能已经是最优的,一百万块就不是。资产转码器只看单块网格,它不知道这些立方体组成了这栋楼,看不见它们的相对重要性、看不见它们的尺度、也看不见夹在它们之间的隐藏表面。只有看整幅构图,那些优化才成为可能:合并几何与材质、去掉隐藏表面、为聚合体建 LOD。于是结论落在一句话上,优化单元必须长大,从一块资产长到整片世界。

这也是第二根支柱的定位(讲义 slide 29)。讲者说转码契约从来就不是真为资产而设:它要的是一份稳定、带版本的输入与确定性的处理,产出的是内容寻址、可缓存、可复用的结果,资产只是第一个工作负载。SLIM 是 Scalable Lightweight Interactive Models 的缩写,它把同一套机具用到一片活世界的选定区域上。源数据模型保持权威且可编辑;世界转码器取这片区域的一个渲染视图,派生出更轻的运行时形态;客户端像用任何别的 ACR 一样用它们。在此之前还有一步,把活的可变数据模型翻成一份稳定的转码输入。

SLIM 定义页
图 6-1 E 类·证据 · 讲义 slide 29 · 原样引用 怎么读 ①指认:页面给出 SLIM 的全称与定位,并画出「源数据模型保持权威、世界转码器派生更轻形态、客户端当普通 ACR 使用」这条链路。②读法(怎么读):把 SLIM 读成转码契约的第二次应用而不是新机制,资产是第一份工作负载,世界是第二份;「选定区域」四个字提示它是有边界的,不是对全世界一次算完。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

那份输入就是 SLIM 描述符(SLIM descriptor)(讲义 slide 30)。它由服务端创建,因为服务端持有完整的数据模型、看得见整片世界。今天的具体做法是:创作者把数据模型里的一棵子树标记为可 SLIM 化;自动边界选择仍在推进中,他们在探索自动分段等思路。描述符只存转码器做渲染需要的东西,几何与材质引用、变换、颜色。资产负载留在描述符外面,描述符只带引用,从不带真正的字节。活世界变化时,服务端更新描述符,客户端消费派生的 SLIM 输出。这里还附了一条好性质:客户端不再需要为了渲染而持有整份数据模型,它的数据模型视图可以明显缩小,省内存、提性能、降网络带宽。

SLIM 描述符页
图 6-2 E 类·证据 · 讲义 slide 30 · 原样引用 怎么读 ①指认:页面画的是描述符的字段构成,含几何与材质引用、变换、颜色,并标出「描述符只存引用、资产负载在外」;同页注明自动边界选择仍在推进。②读法(怎么读):先抓住「只带引用不带字节」这条,它是描述符能保持小而稳定的原因;再记下「自动边界选择仍是 work in progress」,当前靠创作者手动标记子树,不要读成已全自动。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

把 p28 到 p30 三页连起来,能看出这套设计的两条边界。一条是空间的边界,SLIM 作用在世界里被选定的区域,并非一次算完整个世界;另一条是内容的边界,描述符只装渲染需要的引用与变换,资产字节留在外面,由既有的资产转码链路独立供给。两条边界把 SLIM 与「把整片场景烘成一个大静态模型」这类做法区分开,也解释了它为何能用「选定区域」四个字来限定作用范围。

本章可核对的结论有三条。优化单元必须从一块资产长大到整片世界,因为单块资产的最优凑不成整片场景的最优(讲义 slide 28)。转码契约要的是稳定版本化输入、确定性处理与内容寻址复用,SLIM 把同一套机具用到活世界的选定区域,源数据模型保持权威可编辑(讲义 slide 29)。SLIM 描述符由服务端创建,只存几何与材质引用、变换与颜色,只带引用不带字节;自动边界选择仍在推进中,当前靠创作者手动标记子树(讲义 slide 30)。下一章讲这份描述符怎么拿到一个稳定的身份。

7内容寻址与归一化后哈希

上一章讲描述符怎么被造出来,这一章讲它怎么拿到一个稳定的身份(讲义 slide 31)。普通的资产有资产 ID 与版本;SLIM 描述符从不被显式发布,所以它没有 ID。代替方案是让内容本身定义身份:对描述符的字节做哈希,这个哈希就是地址。如果哈希已经存在,就复用这份描述符以及由它派生的一切;如果是新的,服务端上传一次,此后平台负责转码并缓存结果。内容寻址的好处在描述符被上传之前就显现:重复内容在提交阶段就被认出来,于是同一个模型可以跨不同的游戏会话复用,甚至跨不同创作者做的不同游戏复用。

这里有一个必须守住的前提(讲义 slide 32):屏幕上看起来一样的模型,必须产出逐字节相同的描述符,否则整套去重机制就会散架。这就是他们先归一化、再哈希的原因。两个模型可以用差别很大的数据模型子树来表示同一个物件:子节点顺序不同、实例命名不同、变换里带着浮点噪声。直接对原始数据做哈希,每一种差异都会变成一个不同的身份。于是他们剥掉所有对渲染没有影响的东西:把属于运行时参数的状态因子化出来(变换、颜色、材质),量化浮点,把实例与属性排成规范次序,其余一律丢弃。归一化之后,等价模型产出相同的字节与相同的哈希,这个哈希就成为地址。

归一化后哈希页
图 7-1 E 类·证据 · 讲义 slide 32 · 原样引用 怎么读 ①指认:页面画出归一化前后的两组描述符,标出被剥离的三类差异(子树顺序、实例命名、变换里的浮点噪声),并给出一个哈希地址前缀(由幻灯区位图 OCR 读出)。②读法(怎么读):先接受「屏幕上一样就必须字节一样」这条前提,再看剥离动作如何把多种写法收敛到一个地址;哈希前缀属 OCR 读数,须人工过图核对字符。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

讲义 slide 33 用那台 van 把这套流程从头走了一遍。服务端取来活数据模型的子树,抽出渲染状态,归一化结构,因子化出参数,去掉一切不影响画面的东西;归一化后的字节给出 SLIM 地址。别处一台等价的 van,名字、变换、来历都不同,也会解析到同一个地址。到此他们把一个活世界里的局部变成了稳定、可复用的输入,接下来该让它变成可渲染的东西。哈希地址的示例前缀由讲义 slide 32 的幻灯区位图给出(讲义 slide 32(OCR)),须人工过图核对字符。

归一化这一步还解释了这套设计为什么敢把地址交给内容本身。资产之所以能有 ID 与版本,是因为有人在上层替它记账;SLIM 描述符随时由数据模型重算,没有这样一层登记,只能让内容自己给出身份。剥掉子树顺序、命名与浮点噪声之后留下的,是真正决定画面的那些字段;只要这些字段一致,两个模型的地址就一致,去重与复用随之成立,不依赖任何外部台账。

用那台 van 能看清去重的实际落点:同一台 van 在不同玩家的世界里各自被摆过、被改名过、被脚本挪过,只要归一化后剩下的渲染字段一致,它们就收敛到同一个地址,平台只转码一次。讲者把这一步称为内容寻址在上传前就抓住重复,它的直接后果是跨游戏复用,间接后果是内容平台不必为每个副本各存一份派生形态。

本章可核对的结论有三条。SLIM 描述符没有显式 ID,身份由描述符字节的哈希充当地址,内容寻址在上传前就抓到重复,可跨会话与跨游戏复用(讲义 slide 31)。去重的前提是等价模型产出逐字节相同的描述符,因此要先剥离子树顺序、命名与浮点噪声,量化浮点并规范排序(讲义 slide 32)。van 的流程是提取渲染状态、归一化、因子化参数、去掉与画面无关的内容,再由字节得到 SLIM 地址,别处的等价 van 解析到同一地址(讲义 slide 33)。下一章跟着这台 van 走进世界转码器。

8世界转码器:烘焙变换、按材质聚合、去内部面

上一章把一片活世界翻成了稳定、可复用的输入,这一章看世界转码器把它变成可渲染的形态(讲义 slide 34)。它做的事分几步:把每个部件翻成模型空间里的可渲染几何;按兼容的材质与 shader 状态给几何分组,合并成更大的块;去掉藏在内部的表面;为聚合体建起若干级细节。每一级都记下自己的字节数与几何误差。产出的是一组多档 SLIM ACR,一档对应一个保真度级别。转码器不面向任何具体设备;到了运行时,每台设备按相机视锥、屏幕尺寸,以及自己的性能与内存预算去挑一档。同一页还给出远近三档的具体做法:近处逐材质用原始贴图渲染,远处把材质合成一个运行时材质、把小尺寸贴图打进纹理数组,于是整台 van 一次 draw call 画完,更远则用纯色替掉贴图。这台 van 上,60 块源网格合成 1 个几何块,13 份源材质合成 1 个运行时材质。

世界转码器动作页
图 8-1 E 类·证据 · 讲义 slide 34 · 原样引用 怎么读 ①指认:页面把转码器的动作逐条列出(翻成模型空间几何、按材质与 shader 状态分组合并、去内部面、建多级 LOD、记录误差与字节),并标出 van 上 60→1 与 13→1 两组数。②读法(怎么读):把这一页读成整条链路的总目,后面 p37 到 p44 是它的逐步展开;两组数绑定 van 这一个模型,换模型会变。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

讲义 slide 35 到 p40 是那六步图,讲者逐页把 van 推过整条流水线。描述符那一步已经讲过,要点是它始终很小:变换、颜色、资产引用,从不带负载,这让每一个输入都是显式且可复现的。接着是取资产数据(讲义 slide 36)。讲义 slide 37 特意点出一件事:世界转码器是沙盒化的游戏引擎代码,并非为每一种 Roblox 格式另写一套实现,它跑的是与运行时相同的代码。这段代码校验描述符,遍历实例,收集去重后的资产 ID,再把每一个解析到精确的源版本;它先查共享的本地磁盘缓存,缺的从 CDN 取,可能是源资产也可能是某个资产 ACR,然后全部装进内存。描述符很小,可它依赖的每一项都精确而显式。

再往下是搭聚合体(讲义 slide 38、39)。第一步把每个部件的位置、旋转、缩放烘进一份共享的模型空间,这一步涂掉了原本的物体边界,让网格简化器可以跨整幅构图工作。随后按兼容的材质与 shader 状态分组、合并,只有在平台上限逼着时才开新批,例如撞到 16 位索引缓冲上限。这里还有一句必须记住的限定:聚合并不等于把一切都变成静态。对骨骼网格,他们把输入骨架合并成一份共享骨架,保留蒙皮权重与骨骼影响;对静态网格,他们给每块输入网格加一根虚拟骨。所以聚合之后依然能转动一个轮子或打开一扇门。讲者的经验法则是,优化结构,同时保住它与活数据模型之间的映射。

讲义 slide 40 起是去掉永远不进画面的几何。转码器为整个聚合体建一棵 BVH,因为转码期间要做很多次可见性测试(讲义 slide 41)。对聚合体里的每个三角形,他们沿它的面积撒采样点,大三角形拿到更多采样点;从每个采样点朝几个方向射射线,看有没有哪条能逃到开阔空间。规则刻意保守:只要有一条射线逃出去,这个三角形就可能被看见,留下;只有在所有采样都找不到出路时才删掉它。这样能清掉内部与重叠的三角形,又不会在模型上开出可见的洞。

去内部面页
图 8-2 E 类·证据 · 讲义 slide 41 · 原样引用 怎么读 ①指认:页面画出对聚合体建 BVH、按面积布点、从采样点多方向射射线的流程,规则是「任一射线逃出即保留,全部逃不出才删」。②读法(怎么读):把「保守」两个字读重,宁留不误删是这条规则的全部倾向,目的是清掉内部与重叠三角形而不在表面开洞。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

本章可核对的结论有四条。世界转码器把部件翻成模型空间几何、按材质与 shader 状态分组合并、去内部面、为聚合体建多级 LOD,产出多档 SLIM ACR,转码器本身不面向具体设备(讲义 slide 34)。van 上 60 块源网格合成 1 个几何块、13 份源材质合成 1 个运行时材质,近处逐材质、远处合成运行时材质并把小图打进纹理数组,做到一次 draw call(讲义 slide 34)。转码器是与运行时同码的沙盒化引擎代码,先查本地磁盘缓存、缺的从 CDN 取,再全部装入内存(讲义 slide 37)。聚合保留对活数据模型的映射,骨骼合并、静态网格各配一根虚拟骨;去内部面用 BVH 加面积布点射线,任一射线逃出即保留(讲义 slide 39、41)。下一章讲剩下的简化与打包。

9自研网格简化与多档 ACR 打包

上一章把几何聚成一个整体并清掉了内部面,这一章收尾,讲简化与打包(讲义 slide 42)。讲者先用那台 van 给出两级细节的读数:最细的一级约 9,200 个顶点、8,400 个三角形;到第四级降到约 2,600 个顶点、1,600 个三角形。这两个读数是这一个模型的,换一个模型数字会变,引用时须带上模型。

讲义 slide 43 讲简化算法本身。他们得自己写一个,因为用户生成的内容很少给干净的流形拓扑。这个算法显式地存下顶点、边、面之间的关系,不使用传统的半边(half-edge)数据结构;它处理一条边带一个、两个或多个相邻面的情形,并且让本来断开的部分保持断开。二次误差度量(quadric error metric)负责保住原始表面,他们又加了一项面积损失的罚项来改善结果;尖锐折痕以及 UV 或其他顶点属性上的畸变,都会抬高一条边被折叠的代价。每一步简化折叠当前代价最低且有效的边,解出新顶点位置,只更新附近的候选;在属性缝处,他们保留多份属性值而不焊接成一份。结果是拿到一组可用的细节层级,而不要求干净拓扑,因为干净拓扑很少出现。讲者在此页给出一篇论文出处(Liu, Zhang & Yuksel 2025 的《Simplifying Textured Triangle Meshes in the Wild》),该出处由幻灯区位图 OCR 读出(讲义 slide 43(OCR));它是算法的方法来源,不是代码许可,讨论算法细节须回引论文。

简化算法页
图 9-1 E 类·证据 · 讲义 slide 43 · 原样引用 怎么读 ①指认:页面列出简化算法的几个要点(显式存点边面关系、不用半边结构、处理一到多邻面、QEM 保曲面加面积损失罚项、折痕与属性缝抬高折叠代价、属性缝保留多份值),并给出论文出处(OCR)。②读法(怎么读):把这一页读成「为 UGC 定制」的说明,每一条都在回应干净拓扑缺失这一现实;出处是论文而非代码许可,细节须回引论文。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

把简化器接进转码器之后,它的收益方式与第 5 章那条网格时间线一致:算法换一版、参数调一次,既有内容不必重传,下一次请求就用上新结果。简化器输出的一组细节层级,再由讲义 slide 44 的打包步骤配上误差与字节价签。讲义 slide 44 是最后一步,把各细节层级打包成多个 SLIM ACR。每一档装着可渲染的数据,顶点、索引、纹理 ID 与材质映射;再附上运行时在档位之间做选择所需的元数据:几何误差、三角形数、字节数。到这里,世界转码器的输出全部就位,客户端拿到的是一排明码标价的档位。

两级读数也说明了档位之间差在哪里。最细一级承载近处要看的形状,第四级把它压到约四分之一上下的三角形量,留给远处;中间还隔着若干档,供运行时按屏幕覆盖去挑。打包时附上的三项元数据各有分工:几何误差用于与理想档比较,三角形数用于对齐渲染预算,字节数用于在内存池里排序。缺了任何一项,第 10 章那套按「每字节消除的可见误差」打分的规则都跑不起来。

本章可核对的结论有三条。van 的最细一级约 9,200 顶点、8,400 三角形,第四级约 2,600 顶点、1,600 三角形,读数是这一个模型的(讲义 slide 42)。简化算法为 UGC 而写,不用半边结构,显式存点边面关系,QEM 加面积损失罚项,折痕与属性缝抬高折叠代价,属性缝处保留多份值;方法出处为 Liu, Zhang & Yuksel 2025(讲义 slide 43(OCR))。打包后每档 SLIM ACR 带顶点、索引、纹理 ID、材质映射,以及几何误差、三角形数、字节数三项选择元数据(讲义 slide 44)。下一章换到第三根支柱,看客户端怎么花预算。

10运行时编排:两个预算与一笔率失真的账

上一章把档位与它的标价准备好了,这一章进入第三根支柱(讲义 slide 45):运行时编排。转码器造出了保真度档位,接下来由每个客户端决定怎么在自己几份预算上花钱。

讲义 slide 46 把客户端要解的问题拆成两个相连的部分,性能与内存。性能预算管的是每个可见实例能拿到多少细节:可见性与屏幕覆盖定义出理想 LOD,当场景贵到渲不动时,渲染预算把目标往下拉;超过理想档的细节买不到任何东西,因为这个物体根本没盖住足够的像素去显示它。内存预算管的是哪些 LOD 能常驻显存:所有 SLIM 网格共用一份固定的字节预算,每份共享网格只存一份,用不上的档被逐出,缺失但有用的档来竞争剩下的内存。讲者把两句总结并排放:性能决定哪些细节有用,内存决定哪些细节留得住。两者合起来,就定下整个场景能达到的最好可见画质。

两个预算页
图 10-1 E 类·证据 · 讲义 slide 47 · 原样引用 怎么读 ①指认:页面把两份预算并排,渲染预算是三角形目标(桌面 470 万、平板 240 万、手机 110 万,OCR),内存预算是一池固定的 GPU 字节;同页给出按「每加一字节消除的可见误差」打分的升级规则。②读法(怎么读):先分清两份预算管的事不同,渲染预算管哪些细节有用,内存预算管哪些细节留得住;再读那句「场景复杂度改变的是竞争,不是预算本身」。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

讲义 slide 47 把这套说法落到数上。设备能力与画质设置定下两份固定预算。渲染预算是三角形目标,桌面 470 万、平板 240 万、手机 110 万;内存预算是一池固定的 GPU 字节。场景复杂度改变的是这些预算的竞争,预算本身不动。每一帧,可见性与屏幕覆盖给出每个实例的理想 LOD,渲染预算给出实际目标。内存这一侧,他们先逐出高过新目标的档,再对每个有用但缺失的档按其「每加一字节消除的可见误差」打分,把能塞进剩余内存的最高分升级载进来。讲者说这套做法有个熟悉的学名,率失真优化(rate-distortion optimization),把字节花在能消除最多可见误差的地方;同页给出启发出处(Shoham & Gersho 1988,OCR)。

讲义 slide 48 回到那个演示。这张表比较同一场景、同一相机下的几台设备,一列一台。相对朴素基线,他们砍掉最多 97% 的客户端实例、98% 的三角形、74% 的 draw call,GPU 内存降 33%。讲者强调:表里每个数都来自同一个源世界,反映的是不同设备与不同预算;桌面、平板、手机都没有手工版本,一切都是按需生成,每台设备挑自己能做到的最好表示。

这组百分比必须带足限定。它是同一场景、同一相机下的引擎内实时抓帧(讲义 slide 48 原话 Same scene and camera, real-time engine capture),基线是「朴素渲染不作任何优化」这一极端口径,读数的对象是这个 kitbash 演示场景,因此它既不可外推为通用收益,也不能读成相对既有 LOD 或合批方案的增量收益。三档设备的数分别标在各自的列里,百分比由幻灯区位图 OCR 读出(讲义 slide 48(OCR))。

结果表页
图 10-2 E 类·证据 · 讲义 slide 48 · 原样引用 怎么读 ①指认:页面是一张多列结果表,一列一台设备,行是实例、三角形、draw call 与 GPU 内存的削减幅度,逐格数值由位图 OCR 读出。②读法(怎么读):先读页脚「同一场景同一相机、引擎内实时抓帧」这句限定,再读四个百分比;基线为朴素无优化口径,绑定这个演示场景,不可外推、不可当作通用收益。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

本章可核对的结论有三条。客户端每帧解两个相连的问题,性能预算决定哪些细节有用、内存预算决定哪些细节留得住(讲义 slide 46)。两份预算是固定的,渲染预算为桌面 470 万、平板 240 万、手机 110 万的三角形目标,内存预算为一池 GPU 字节;升级按「每加一字节消除的可见误差」打分,即率失真(讲义 slide 47)。相对朴素基线,同一场景同一相机下砍掉最多 97% 实例、98% 三角形、74% draw call,显存降 33%,不可外推(讲义 slide 48(OCR))。下一章看这三档设备各自长什么样,以及世界动起来后怎么办。

11同一个世界的三档设备,与动态 SLIM

上一章给出那张表的骨架,这一章把三档设备一档一档看过去,再进到世界动起来的部分(讲义 slide 49 起)。p49 是朴素基线,每帧 5940 万个三角形。p50 是开着 SLIM 的桌面,画面近乎一样,却只用 470 万个三角形,同场景、同相机;讲者让两幅图来回切换,评语是差异看得见但很小,他们去掉的那些工作对最终画面几乎没有影响。p51 是调试视图:没上色的物体走常规渲染路径,颜色标示每个物体被选中的 SLIM 细节档。这里有一处要留意,选出来的档不构成简单的距离环,近处物体在屏占小或几何误差小时反而拿到更低的档,远处物体可以拿到更高的档,尤其当一份常驻网格同时服务许多可见实例时。可见性、屏幕覆盖、复用、三角形成本、字节成本与全局预算,全都汇进编排器。p49 到 p51 这几页只有画面与备注文字,没有对应插图。

p52 与 p53 是平板,目标 240 万。运行时会优先去掉视觉损失最小的细节,于是场景在约为桌面一半的预算下仍保住轮廓与密度;调试视图里选档更激进,更多物体走 SLIM,但决策仍是全局按价值做的,他们没有扳动某个大的画质开关,每一份常驻档位都还在按「每字节带来的可见收益」竞争。p54 与 p55 是手机,目标 110 万。讲者如实交代,他从未把这个演示做成面向移动端的,手机上他只为截这张图跑过一次;优化形态由平台自动派生,手机挑了自己塞得下的那一档。这一句把定位说清了:手机那条读数是一次性截图的产物,不是一轮移动端调优的结果。

到 p56 为止画面看起来基本是静态的,可 Roblox 世界会动、会演、会变,于是有了动态 SLIM。讲义 slide 57 给出切分方式:服务端持有活的数据模型,实例、属性、变换、颜色、动画状态,以及驱动它们的脚本;客户端持有一份不可变的 SLIM 制品,里面有聚合几何、细节档、材质映射与参数槽。前文往聚合体里插的虚拟骨,以及它与数据模型之间的映射,在这里派上用场:它们让一份不可变的制品能对变换与颜色变化作出反应。服务端对这些参数做紧凑快照并复制给客户端,渲染器把它们施加到 SLIM 模型上;几何全烘在一个聚合体里、一次 draw call 画完,而颜色仍在变、轮子仍在转。

动态 SLIM 切分页
图 11-1 E 类·证据 · 讲义 slide 57 · 原样引用 怎么读 ①指认:页面把职责一分为二,服务端持可变数据模型(实例、属性、变换、颜色、动画状态与脚本),客户端持不可变 SLIM 制品(聚合几何、细节档、材质映射、参数槽),中间由参数快照联通。②读法(怎么读):先认出虚拟骨与映射是把最新状态接回制品的那一环,再读「几何烘成一个聚合、单 draw call 渲染,而颜色与轮子在动」这句结论。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

讲义 slide 58 讲网络这一侧的预算。既然 SLIM 制品里已经装好结构与映射,他们就不必把每条属性更新发给每个客户端。客户端本地已经握有仿真状态的,直接拿来给 SLIM 模型配参数,网络开销为零;客户端没有的模型,服务端才需要复制状态,做法是按重要度排队,并把更新节流在一份固定的网络带宽预算之内。他们还会记录距上次更新过了多久,免得远处的模型永远冻在同一个姿势里;近处的模型更新更频繁,但最终每个 SLIM 模型都会拿到更新。投递刻意做成不可靠,且很简单:没有重传队列,也没有确认,因为一份更新的快照会让所有旧快照作废。在接收端,快照是稀疏到达的,客户端用五次惯性化(quintic inertialization)把它们抹平,把稀疏的网络包还原成平滑的渲染帧率运动;这一处受到 David Bollo 在 GDC 2018 的启发(OCR)。讲义 slide 59 另给一个例子,1,200 个活的动画化身,服务端全程保持权威,客户端只画轻量制品、接收那些屏幕上真正要紧的运动快照。

网络复制预算页
图 11-2 E 类·证据 · 讲义 slide 58 · 原样引用 怎么读 ①指认:页面把复制策略的几条并列(本地已算则零网络开销、按重要度排队并限流、记录距上次更新时长、无重传无确认、五次惯性化抹平稀疏快照)。②读法(怎么读):先抓住「带宽也是预算」这一条与全篇的预算思路一致,再读不可靠投递的理由(更新的快照让旧的作废);惯性化受 David Bollo GDC 2018 启发为 OCR 读出。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

本章可核对的结论有四条。三档设备看的是同一场景同一相机,桌面 470 万、平板 240 万、手机 110 万,桌面与朴素基线近同画面(讲义 slide 49、50)。调试视图显示选档不构成简单距离环,可见性、屏占、复用、三角形与字节成本、全局预算共同决定档位,平板与手机的选档更激进而决策仍按价值(讲义 slide 51、52、53)。手机那条读数为一次性截图,讲者自陈只为截图跑过一次(讲义 slide 54)。动态 SLIM 把服务端的可变数据模型与客户端的不可变制品分开,靠参数快照与虚拟骨驱动;网络投递不可靠、无重传无确认,客户端用五次惯性化抹平稀疏快照(讲义 slide 57、58、59)。下一章收边界与反例。

12边界与反例:SLIM 在哪些地方不划算

整篇讲到这里,剩下的是一份诚实的边界清单(讲义 slide 60)。讲者说 SLIM 在优化聚合体上极其有效,随后自己把话说清:它在何处还能改进,在何处不适合用。

讲义 slide 60 列出四类不划算的场景。结构频繁变动会不断造出新描述符,把系统淹没在重复任务里,这种情形下他们更愿意回退到传统渲染。只用一次的唯一几何仍能从 LOD 与流式加载里得到好处,可去重几乎给不了什么,内存成本涨得很快,可能把用量顶出预算;为了留在限额内,编排器被迫逐出高分辨率档,画质明显掉一截。延迟是个硬问题,即便快照本身没错,对高度动态的仿真也可能到得太晚。聚合本身也有代价,大而稀疏的模型让视锥剔除与遮挡剔除都变得没那么有效。讲者把契约写明:在结构稳定、可复用、这笔交易划算的地方用 SLIM,不划算就回退,回退是让优化保持正确的机制。

边界页
图 12-1 E 类·证据 · 讲义 slide 60 · 原样引用 怎么读 ①指认:页面列出四类不划算场景(结构频繁失效、一次性唯一几何、严格低延迟、过度聚合),并收在「回退是让优化保持正确的机制」这句话上。②读法(怎么读):把它当成与第 10 章收益表配对的反面清单读,收益表说能省多少,这一页说在哪些前提下省不到;四类都是使用前提而非实现缺陷。 来源:SIGGRAPH 2026 Advances · SLIM: Scaling User-Generated 3D Worlds on Roblox · 讲者 Sergey Makeev(Roblox)· 未修改引用

讲义 slide 61 收出四条经验:保住真源、派生表示,源始终权威、优化形态可弃,算法变好只需重新转码;带上下文与显式契约去优化,归一化、自动发现复用、只在假设成立时聚合,把回退当成契约的一部分;让运行时预算决定细节层级,转码器造选项、客户端把预算花在能买到最多可见画质处;把不可变结构与活状态分开,几何与参数槽放进制品,服务端快照负责让一切继续运动。

讲义 slide 62 列出讲者想推进的方向:更好的 SLIM(更丰富的参数化与部分失效、点云与高斯泼溅与 impostor 这类三角形之外的远处表示、以及「SLIM 由 SLIM 组成」的层级化空间 SLIM);完全分布式的渲染引擎(渲染任务跑在客户端、游戏服务端、机架或云端,同一契约产出可缓存复用的结果,例如为全局光照生成一个 ACR);内容上采样(转码器也能增强,几何、纹理、材质、光照、动画都可借生成式 AI 变好);以及 Roblox Reality 这一混合渲染架构(AI 世界模型需要持久化的空间与语义记忆,可设想一个 SLIM ACR 存放视觉模型输出、或以潜空间表示世界)。讲者把这些界定为研究方向,并说明它们不是已经发布的功能(research directions, not shipping features)。

边界 1:平台级读数全部是讲者所述的平台级指标。 1200 万请求/秒、960 台转码器、约 16.8 万 GHz、8.3 TB RAM、每天约 120 万网格、20 年 700+ PB、每分钟约 2.7 万与 2.4 万 ACR、每小时超过 1.36 亿次取用(讲义 slide 5、19、26),无受控实验、不可复现,页内表体由 OCR 读出。

边界 2:收益读数是同一场景同一相机的引擎内实时抓帧,不可外推。 实例 −97%、三角形 −98%、draw call −74%、显存 −33%(讲义 slide 48)的基线为朴素无优化口径,绑定单个 kitbash 演示场景,不能读成相对既有 LOD 或合批方案的增量收益。

边界 3:不与任何商用方案横比。 SLIM 依赖 Roblox 的数据模型、内容平台、ACR 内容寻址缓存与 CDN,脱离这套基础设施收益无法直接迁移;讲者自陈手机只跑过一次、且只为截图(讲义 slide 54)。

边界 4:讲义 slide 62 的未来工作是研究方向。 四项按原话 research directions, not shipping features 引用,不得写成已落地;讲义 slide 30 的自动边界选择同为 work in progress,当前靠手动标记子树。

边界 5:讲义 slide 43 只给算法论文出处,不是代码许可。 Liu, Zhang & Yuksel 2025 是方法来源(OCR),全篇无 MIT、open source 或 GitHub;版面与 21 件插图页脚为 All Rights Reserved、无 CC 声明,故按非 CC 口径逐件署名并标残留风险。

边界 6:幻灯区无文本层,页内读数全部来自 OCR。 讲义 slide 5、6(172,531 与 3,526)、9、19、26、32、43、47、48 的页内数字一律标「讲义 slide N(OCR)」,须人工过图复核;备注里的约数与 OCR 精确数不合并。

本章可核对的结论有两条。四类不划算场景是结构频繁失效、一次性唯一几何、严格低延迟与过度聚合(讲义 slide 60);平台级读数与收益读数各带各的口径限定,讲义 slide 62 的未来工作按研究方向口径引用,讲义 slide 43 只给论文出处而非代码许可。

13贡献块

这一篇的贡献(精读视角)

三条贡献与站内互读

一场生产向的讲座能留下什么,取决于它把哪些东西讲到了别人抄得走的程度。SLIM 这一篇留下的三样都带明确的依赖前提:一套把离线 cook 搬进云端的资产转码流水线,一份把优化单元从资产放大到世界的做法,以及一层按预算挑选的运行时编排。它还有一条贯穿全篇的口径纪律,平台级读数与单一演示场景的收益读数分列,正文凡出场即带限定,因此这三样贡献都只报「怎么做的」,不替读者把收益外推。

贡献 1:一条把离线 cook 搬进云端的资产转码流水线。 源永远不可变且带版本,运行时形态按需派生、内容寻址、可缓存可去重;ACR 与两条版本轴(源版本、ACR 格式版本)把「新格式上线」与「游戏能不能跑」解耦,老客户端不再请求旧格式时平台直接回收(第 3 到第 5 章,讲义 slide 12/20/26)。想在自己管线里做到「发布冻结源、不冻结优化」的读者,这套契约可以借鉴,前提是自己先有一层内容寻址缓存与按需转码的机队。

贡献 2:把优化单元从一块资产放大到整片世界。 SLIM 描述符只带引用不带字节、归一化后哈希做跨会话跨游戏去重;世界转码器烘焙变换、按材质聚合、用 BVH 加面积布点射线去内部面、建多级 LOD,并把结果按保真度打成多档 ACR(第 6 到第 9 章,讲义 slide 30/32/34/41/43)。这条路径可搬的是思路与契约,不是它的规模读数,也不是那台 van 的具体数值。

贡献 3:一层按预算挑选的运行时编排。 渲染预算是三角形目标、内存预算是一池 GPU 字节,升级按「每加一字节消除的可见误差」打分;动态 SLIM 再把不可变结构与活状态分开,靠参数快照与虚拟骨让制品动起来,网络投递刻意做成不可靠并用五次惯性化抹平稀疏快照(第 10、11 章,讲义 slide 47/57/58)。四个百分比读数只对那个演示场景与那台相机成立(讲义 slide 48)。

站内可以接着读的几篇:同一届 SIGGRAPH 2026 Advances(Part II)的篇目 29(Smolder)与本篇同为生产向讲座,前者讲体积效果怎么变成引擎里的通用系统,与本篇「把预算花在看得见的地方」是同一种取舍;篇目 30(Adaptive Tessellation and Subdivision)把细分搬到 compute 上做自适应,理由是 2D 每级只剩 1/8、3D 只剩 1/16,与本篇「按预算选档」在预算思路上互相呼应;篇目 23(变率光追)、篇目 26(PSSR 升级)、篇目 27(ORCA)也在同一批里,可作生产视角的对照。本篇讲义全篇没有给出代码仓库或开源链接,唯一的算法出处是讲义 slide 43 的论文(Liu, Zhang & Yuksel 2025)。

14原文出处块

原文出处

原文出处与引用口径

出处:SIGGRAPH 2026 · Advances in Real-Time Rendering in Games(Part II)· 讲者 Sergey Makeev(Senior Technical Director, Roblox)· 官方讲义《SLIM: Scaling User-Generated 3D Worlds on Roblox》,64 页,612×792 pt(信纸竖版),来源 PDF 2026-siggraph-advances-slim.pdf

材料:官方讲义 64 页,每页带讲者备注(口播脚本,有文本层);幻灯区无文本层,页内标题与数字由位图 OCR 读出,须人工过图复核;本篇事实、读数与页码取自讲者备注与选页台账;页码为 PDF 页序(从 0 起),引用写作「讲义 slide N」

许可:逐页页脚 © 2026 SIGGRAPH Advances in Real-Time Rendering in Games course. All Rights Reserved.(右侧并带 ROBLOX 字标),全篇无 Creative Commons 声明,亦无代码许可(无 MIT / open source / GitHub);讲义 slide 43 只给出算法论文出处(Liu, Zhang & Yuksel 2025),不是代码许可。故 21 件图按分区非 CC 口径逐件署名(源 slide 号 + 出处 + 版权行 + 「未修改引用」),并在构建记录标注残留风险,不得写成 CC 或可自由转载

引用口径:平台级读数(12M req/s、960 台转码器、168K CPU GHz、8.3 TB RAM、1.2M 网格/日、700+ PB、27K/24K ACR/分、136M+/h)一律标「讲者所述平台级指标」,无受控实验、不可复现;收益读数(实例 −97%、三角形 −98%、draw call −74%、显存 −33%)为同一场景、同一相机的引擎内实时抓帧,不可外推,且不与任何商用方案横比;讲义 slide 62 的四项未来工作按讲者原话(research directions, not shipping features)作研究方向引用,不得写成已落地;幻灯区页内读数一律标「讲义 slide N(OCR)」