篇目 30 · 讲座精读

细分要换来的是一笔固定的数据账:换掉 DX11 收不住的分数图案,再把它搬上 compute

Adaptive Tessellation and Subdivision · DX11 的分数细分因子分得均匀却收不住:每加一个点,中点就在 0.5 与 2/3 之间来回。讲者先夹紧平行四边形把整块图案换掉(同档细分少 1/3 三角形、能从 1 个三角形平滑过渡),再把它搬上 compute 做自适应(2D 每级只剩 1/8、3D 只剩 1/16),最后在多趟帧上兑出约 3 倍。讲义 87 页全篇没有讲者备注,凡需口播才能确定处一律写「讲义未给」

出处:SIGGRAPH 2026 Advances in Real-Time Rendering in Games(Part II)· 讲座讲义 · 87 页 讲者 John Hable(Meta,台账口径;标题页只署名 John Hable)· 21 张幻灯片原样引用(源 slide 0–86) 许可分两层:① 版面与插图非 CC(All Rights Reserved)· 逐件署名 · 标注残留风险;② 示例代码 MIT,仅覆盖 p7/p83 的 WebGPU demo 精读执笔 · 浅墨(qianmo)
14 章一级章节(按拆解点切)
1 式公式照讲义原样给出,不补推导
21 张配图(原文 21 / 自绘 0)
8 条边界与反例(独立成节)

图-段配对表 · 本稿 21 张

图角色档归属支撑的论断层次状态
图 1-1E§1动机一:细分曲面能换到什么(Catmull-Clark 低模到高模、位移、干净的 LOD 过渡)①②③讲义 slide 1 · 原样引用
图 1-2E§1动机二:三角网格的数据成本(拓扑 12 B/tri、顶点约 64 B/vert、原始约 44 B/tri)①②④讲义 slide 2 · 原样引用
图 1-3E§1动机三:固定的磁盘成本读数(Monkey 2K 高度图 1.19 MB ≈ 5.45M 三角形)①②④讲义 slide 5 · 原样引用
图 2-1E§2全篇议程:先细分三角形、再细分网格、最后细分曲面(并声明示例为 MIT 许可)①②③讲义 slide 7 · 原样引用
图 2-2E§2硬要求:分数因子不 popping、三边独立,并点名打破 DX11 的对称与单一内部因子①②③讲义 slide 10 · 原样引用
图 3-1E§3从一条边开始:每条边一个 float 因子,DX11 范围 [1,64]①②③讲义 slide 11 · 原样引用
图 4-1E§4DX11 线段的两难:分布均匀却稳定性极低,简单算法偏斜但位移下更稳①②③讲义 slide 19 · 原样引用
图 4-2E§4为什么不收敛:每个八度里中点走 0.5 到 2/3 再回 0.5,上下互推①②④讲义 slide 20 · 原样引用
图 4-3E§4DX11 三角形拆成 6 区(triforce),丢外侧条带吸收各边差异①②③讲义 slide 21 · 原样引用
图 5-1E§5夹紧平行四边形与 gap:取横纵 1D 点的最大 gap,u = min(u, (1-gap)-v)①②④讲义 slide 31 · 原样引用
图 6-1E§6低效图案对照:同 2 的幂细分下 6 区降到 4 区,少 1/3 三角形①②④讲义 slide 35 · 原样引用
图 6-2E§6最少三角形对照:DX11 分数偶数最少 6 个,夹紧法可从 1 个平滑过渡①②③讲义 slide 38 · 原样引用
图 7-1E§72D 规则:每级线段翻倍、误差降到四分之一,每级效率只剩 1/8①②③讲义 slide 42 · 原样引用
图 7-2E§73D 规则:每级三角形翻 4 倍、误差降到四分之一,每级效率只剩 1/16①②③讲义 slide 43 · 原样引用
图 7-3E§7自适应的回报:46.5k 对 62.6k,相近细度要约 560.1k①②④讲义 slide 45 · 原样引用
图 8-1E§8多趟帧:DX11 同趟生成兼消费的常量内存,与每帧多趟的冲突①②③讲义 slide 50 · 原样引用
图 9-1E§9Catmull-Clark 三条规则(面点、边点、顶点点)与稳定、线性、2-ring 本地性①②③讲义 slide 53 · 原样引用
图 10-1E§10Feature-adaptive 收缩:不规则量每级线性增长,远优于 4× 膨胀①②③讲义 slide 59 · 原样引用
图 11-1E§11区域与图元:1/4/16/12 四档,不用 quadtree①②③讲义 slide 72 · 原样引用
图 12-1E§12结果:Monkey 507 verts/968 tris,固定 61,952 对自适应 30,526①②④讲义 slide 74 · 原样引用
图 12-2E§12多趟成本:单光照趟 0.36 对 0.50 ms,光照加 4 道阴影 0.81 对 2.51 ms①②④讲义 slide 78 · 原样引用
角色档按 20 号票的裁决:E 类(承载可核对数值或作为唯一证据)禁止自绘,故本篇 21 件证据全部引用讲义原页;本篇 S 类图为 0,S 类配额为 0,自绘 0 张。
许可分两层:① 版面与插图——全 87 页页脚逐页标注 All Rights Reserved,全文无 Creative Commons 声明 → 按分区非 CC 口径处理:逐件登记、逐图署名(图号 + slide 号 + 出处 + 版权 + 「未修改引用」),并标注残留风险(讲义未授权转载,条款以官方发布为准),不得写成 CC 或可自由转载。② 示例代码——MIT,只覆盖 p7/p83 所指随讲义发布的 WebGPU demo 与示例代码,不覆盖讲义版面与插图本身。
开篇要接住的那个问题 讲义开篇页内文字(英文原样引用 · 无课程页 Abstract 可引)

"Adaptive Tessellation and Subdivision John Hable Subdivision Surfaces ● Catmull-Clark Subdivision [Catmull & Clark] ● Geris's Game - 1997 ● From low poly mesh to high poly smooth surface ○ Displacement ● Clean LOD transition"

这一篇要讲清的五件事
  • 要换掉的是整套图案,不止一个因子数值:DX11 的分数因子分布均匀却收不住(讲义 slide 19–21),讲者在讲义 slide 10 就点名要打破「对称」与「单一内部因子」两条约束;第 3 到第 6 章都在回应这两条。
  • 第一步把平行四边形夹成三角形:取横纵两条 1D 点序列的最大 gap,用 u = min(u, (1 - gap) - v) 夹紧(讲义 slide 31);同档 2 的幂细分下比 DX11 少 1/3 三角形,并能从 1 个三角形平滑过渡(讲义 slide 35、38)。
  • 第二步把整套搬到 compute,理由是一笔算术:2D 每级只剩 1/8 效率、3D 只剩 1/16(讲义 slide 42、43),预算必须挪到看得见的地方;同一模型下固定 62.6k 对自适应 46.5k,拉到相近细度要约 560.1k(讲义 slide 45)。
  • 账在多趟帧上兑现:自适应只 tessellate 一次,OpenSubdiv 每趟都要完整跑 Catmull-Clark;单光照趟每 1M 三角形 0.36 对 0.50 ms,光照加 4 道阴影 0.81 对 2.51 ms,约 3 倍(讲义 slide 78)。
  • 无讲者备注是全篇最大的口径约束:动机、路线取舍、参数选择、测试场景、作者评价一律写「讲义未给」;性能与横比口径分三处边界,见第 12 章。

1细分要换来的是一笔固定的数据账

 细分要换来的是一笔固定的数据账

开篇先把账本摆上桌。讲义从细分曲面的用处讲起(讲义 slide 1):Catmull-Clark 细分(Catmull-Clark Subdivision)把低模网格推成高模的光滑曲面,位移(displacement)挂在曲面上,LOD 之间还能拿到干净的过渡(clean LOD transition);页面上并列写着 Geri's Game 与 1997 这个年份,把这条脉络的起点标了出来。这一页列出的几件事里,低模到高模与位移讲的是做法,干净 LOD 过渡讲的是结果。

细分曲面的用处页
图 1-1 E 类·证据 · 讲义 slide 1 · 原样引用 怎么读 ①指认:页面只有标题与四个项目符号,没有公式与读数,四个符号依次是 Catmull-Clark 细分、Geri's Game 1997、低模到高模的光滑曲面(含位移)、干净的 LOD 过渡。②读法(怎么读):把四个符号当成一组动机清单看,前两项交代来路,后两项交代它能换到什么;本页没有数值,数值在第 1 章后续几页里。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

账的另一半在三角网格这一侧(讲义 slide 2)。高分辨率三角网格的成本被拆成三段:拓扑按每个三角形 12 字节算,来自三个索引、每个 4 字节;顶点按每个约 64 字节算,分项是位置 3 个 float 共 12 字节、法线 3 个 float 共 12 字节、切线/翻转 4 个 float 共 16 字节、UV 2 个 float 共 8 字节、颜色 4 个 float 共 16 字节;合成原始数据的口径是每个三角形约 44 字节,其中 12 字节给连通性、32 字节给顶点。讲者在这一页给了一个换算前提:1 个顶点对应 2 个三角形(1 vert = 2 tris)。把这三段连起来看,真正大的那份落在顶点属性上,拓扑那一份反而最轻。

三角网格的数据成本页
图 1-2 E 类·证据 · 讲义 slide 2 · 原样引用 怎么读 ①指认:页面按「拓扑/顶点/原始数据」三级列出字节数,顶点那一级又按属性逐条拆到 float 个数。②读法(怎么读):先记住 12 与 64 这两个量纲端点,再看 44 这个合计数怎么由 12 加 32 得到,并把「1 vert = 2 tris」这个前提一并记住,后文讲义 slide 5 的三角形数与此处属不同层级。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

压缩这一侧另有一组现成读数(讲义 slide 3)。虚拟化几何(virtualized geometry)以 Nanite 为代表,磁盘上每个 Nanite 三角形 5.6 字节;DGF(Block-based Geometry Supercompression)为硬件光线追踪设计,每个三角形 2.3 字节,额外属性要另算成本;Draco(GLTF)的效果被记成「高度依赖设置」;讲者最后给了一条任意基线(arbitrary baseline),每个三角形 5 字节。这一页的作用是把「磁盘上能把一个三角形压到多小」这个问题报个价,单个三角形的下限落在 2.3 到 5.6 字节之间。

讲者在把两边的账合起来之前,先把位移的账摊开(讲义 slide 4)。细分曲面加偏移位移这套做法里,无限光滑度在磁盘空间这一项上接近免费,讲者紧接着补上一句:内存与性能不免费。8 位位移对真实表面往往就够用;Suzanne(Blender Monkey)这个模型被记成以多分辨率位移的方式建模(讲义 slide 4)。这一段把成本的重心从磁盘挪到了运行时的内存与性能上,第 7 章那套自适应规则要回答的就是这部分账。

固定磁盘成本这一页给出了全篇唯一一个端到端的读数(讲义 slide 5)。细分数据被记成一笔固定成本;基线估计按每个三角形 5 字节存,讲者补注实际数字会随技术高低浮动。Monkey(Blender 的 Suzanne)用一张 2K 高度图、无损 JPEG,UV 覆盖 64.9%,最终读数是 1.19 MB 承载约 5.45M 个三角形,换算关系写成 1 texel = 2 三角形。这组数字要把层级分清:1.19 MB 与 5.45M 是位移之后的目标密度,后文讲义 slide 74 那组 507 verts/968 tris 说的是源网格,两者不能当成同一件事引用。

固定的磁盘成本读数页
图 1-3 E 类·证据 · 讲义 slide 5 · 原样引用 怎么读 ①指认:页面把「细分数据是固定成本」「基线 5 字节/三角形」「Monkey 的 2K 高度图与 1.19 MB」并列,读数是 1.19 MB 对约 5.45M 三角形。②读法(怎么读):先抓 64.9% UV 覆盖这个前提,再读 1 texel = 2 三角形这条换算,最后把 1.19 MB 理解成磁盘口径,与显存口径区分开。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

这份账还有几条 caveat 要一起看(讲义 slide 6)。位移会带来损失,来源列了两条:重采样与 8 位量化。着色技术那一栏铺得很长,标准平铺、三平面映射(triplanar mapping)、六边形平铺(hex tiling)、细节纹理、分层与混合、全程序化着色器都在其中。最后一条限制写得最硬:不支持拓扑变化,悬垂(overhangs)与折叠(folds)都在排除之列。这三条把这项技术的适用范围框住,也解释了为什么后面讨论形变与边环时,重点总落在「平面内怎么摆点」上。

为什么取每个三角形 5 字节作基线,讲义只给了这条估计与「实际会浮动」的注脚,取这个值的理由讲义未给。这套账面向什么项目、什么硬件,讲义在本篇这几页里也没有交代,相关取舍讲义未给。能把这篇与某个具体作品绑起来的信息,标题页只署名 John Hable,正文里没有出现单位字样;本篇按分区台账的口径记为 Meta,这是台账口径,与讲义原话不同。

这一章能核对的点数得出来四条。细分能换到的东西是低模到高模的光滑曲面、位移与干净的 LOD 过渡(讲义 slide 1)。高分辨率三角网格的原始数据约 44 字节每三角形,前提是 1 顶点对 2 三角形(讲义 slide 2)。压缩现状一组读数是 Nanite 5.6 字节、DGF 2.3 字节、任意基线 5 字节,都按每个三角形计(讲义 slide 3)。位移后的固定磁盘成本读数是 1.19 MB 对约 5.45M 三角形,UV 覆盖 64.9%,1 texel 对 2 三角形(讲义 slide 5)。这几条合起来说清了一件事:源数据可以很小,画面可以很细,代价被压到磁盘与运行时两头。下一章接着这份账,讲者把要打破的两条约束写在开场。

2开篇就写明要打破 DX11 的两条约束

上一章的账落到磁盘与运行时两头,这一章把整篇的路线图与承诺摆出来(讲义 slide 7)。

讲者先给议程。三段依次是:细分一个三角形,其中包含对 DX11 硬件细分的深入剖析,然后是夹紧平行四边形细分;细分一个网格,做法是自适应的、用 compute;细分一张曲面,同样用 compute(讲义 slide 7)。页面末尾附了一句,完整解释、动画图示与 MIT 许可的 WebGPU 示例都在那里。把三段与后文对上,第一段对应第 3 到第 6 章,第二段对应第 7、8 章,第三段对应第 9 到第 11 章,路线在图上一眼能分。

全篇议程页
图 2-1 E 类·证据 · 讲义 slide 7 · 原样引用 怎么读 ①指认:页面把议程分成三段,先在三角形上做细分(含 DX11 硬件细分剖析与夹紧平行四边形),再自适应地用 compute 细分网格,最后用 compute 细分曲面,页脚附一句示例为 MIT 许可。②读法(怎么读):把三段当成后文十二章的分区图,第一段对应第 3 到第 6 章,第二段对应第 7、8 章,第三段对应第 9 到第 11 章;末尾那行 MIT 只指示例代码,不指版面与插图。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

许可要分两层读(讲义 slide 7、讲义 slide 83)。讲义 slide 7 这句 MIT 指的是随讲义发布的 WebGPU 示例与示例代码,讲义 slide 83 的原话把它说得更明确:All code is MIT licensed。讲义版面与插图本身不在这条许可里,全 87 页页脚逐页标注 All Rights Reserved,全文没有 Creative Commons 声明。因此本批 21 件图按非 CC 口径逐件署名,引用时带上源 slide 号、出处、版权与「未修改引用」声明,不得写成可自由转载。

进入三角形之前,讲者补了一段历史(讲义 slide 9)。DX11 风格的细分可以追到 Xbox 360(2005),根子在 Pixar 的 Reyes:把图元切成微三角形(micro-tris);《战争机器 2》(Gears of War 2)与《光环:致远星》(Halo: Reach)是带细分出货的作品,Activision 的《使命召唤:幽灵》(Call of Duty: Ghosts)用过细分与 Catmull-Clark 细分(讲义 slide 9)。这段把「硬件细分有二十年历史」这句话落到具体年份与作品上,后面要做的事因此接在一条有年头的线上。四个条目各带一个出处或作品名,年份与作品摆在那里,说明这套做法在大作里已经跑过,后面第 6 章那三条优势与第 8 章那组对手读数,都是在一条有二十年积累的赛道上做比较。

讲义 slide 8 是 Part 1 的分隔页,页面上只有一行 Part 1: The Triangle,没有别的内容(讲义 slide 8)。同样的分隔页还出现在讲义 slide 40 与讲义 slide 52,前者开网格那一段,后者开曲面那一段。三处分隔页一摆,整篇的骨架就清楚了:三角形、网格、曲面各占一段,第一段篇幅最长,一共用了第 3 到第 6 章四章。三段顺序是把难点从局部往全局推,先在单个三角形上把点摆对,再把摆法搬到整张网格上做自适应,最后处理曲面的解析求值;第一段落在 DX11 硬件细分与夹紧平行四边形上,后两段归到 compute(讲义 slide 7)。这套拆法的动机讲义未给。

硬要求写在讲义 slide 10,也是这一章要记住的一页(讲义 slide 10)。第一条是分数细分因子(fractional tessellation factors)带来的不 popping;第二条是三条边彼此独立;第三条起列「与 DX11 细分的几处不同」,讲者在这里点名要打破两条约束:DX11 的细分是对称的,这篇要偏离这条约束;DX11 另有一个内部细分因子,而这篇的内部图案由各边的细分因子隐式定义(讲义 slide 10)。后面对 DX11 的所有改造,都可以回到这两条上来核对。

两条要打破的约束落在形状与效率两头:对称这条约束限制图案能长成什么样,单一内部因子这条约束限制内部的密度怎么分布(讲义 slide 10)。第 6 章讲义 slide 36 会把后一条约束的后果摊开,说明单一内部因子在细长三角形上必然让行与列有一侧欠细分或过细分。「不 popping」这条硬要求与「分数」两字写在同一条(讲义 slide 10);讲义 slide 12 把按 2 的幂跳档的做法记成很强的 pop,两处对照着看,因子带上小数位的作用就是让图案在相邻档位之间连续变化。第 3 章会把这条要求放到一条线段上验证。

细分的硬要求页
图 2-2 E 类·证据 · 讲义 slide 10 · 原样引用 怎么读 ①指认:页面上两条硬要求是分数细分因子不 popping、三条边彼此独立,下面列「与 DX11 的几处不同」,点名对称与单一内部因子两条要打破。②读法(怎么读):先记两条硬要求,再看两条要打破的约束,后文第 4 章讲不收敛、第 6 章讲三种优势,都是围绕这几条展开。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

为什么要把对称与单一内部因子这两条约束打破,讲义 slide 10 只写下要打破这件事,动机讲义未给。为什么把示例基线定成原生 WebGPU,讲义 slide 40 才点出「Vanilla WebGPU, no extensions」,这一选择在三角形这一段里还没有出现,相关理由讲义未给。对称这条约束被打破之后会引出什么后果,讲义也没有在这几页预告。

这一章能核对的要点有四条。三段议程是先细分三角形、再自适应地用 compute 细分网格、最后用 compute 细分曲面(讲义 slide 7)。许可分两层,版面与插图是全 87 页 All Rights Reserved、逐件署名,示例代码是 MIT 且只覆盖随讲义发布的 WebGPU 示例(讲义 slide 7、讲义 slide 83)。DX11 风格的细分可追到 Xbox 360(2005),源头是 Pixar 的 Reyes(讲义 slide 9)。硬要求是分数因子不 popping、三边独立,并明确打破 DX11 的对称与单一内部因子两条约束(讲义 slide 10)。下一章从一条线段开始,把这三条硬要求拆到一维。

3细分的所有难题在一条线段上已经全部出现

上一章把两条要打破的约束写在开场,这一章退回最简的对象,讲者说细分三角形之前得先弄懂细分一条线(讲义 slide 11)。

讲者先声明入口:在细分一个三角形之前,得先弄懂怎么细分一条线。每条边带一个 float 型细分因子,DX11 的范围是 [1,64],这一页还写了两句断言:分数因子带来的不 popping,以及这条线的图案就是最终图案,接下来要把这条线推出来(讲义 slide 11)。把镜头收到一条线段上,形状只有一维,因子的取值与点的位置关系都能直接读出来,第 4、5 章的争论也都发生在同一条线上。

从一条边开始页
图 3-1 E 类·证据 · 讲义 slide 11 · 原样引用 怎么读 ①指认:页面先说明细分三角形之前要先弄懂细分一条线,每条边带一个 float 细分因子,DX11 范围是 [1,64],并声明这条线的图案就是最终图案。②读法(怎么读):先抓「每条边一个 float 因子」这个数据形状,再记住 [1,64] 这个范围,后文因子 3、10.3 这些读数都落在同一条线上。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

最简的想法是按 2 的幂分段(讲义 slide 12)。讲者在这一页给出序列 1、2、4、8、16、32、64,评语是这会产生很强的 pop,并追了一句问题:怎么在层级之间过渡。这一页把最省事的方案摆出来又否掉,落点在「强 pop」这一个词上。问题的形状是:因子在两个整数档之间取值时,图案要不要跟着动、动多少;下一段那条「一次一个点」的改法,就是对这个问题的第一条回答。

改法是每次加一个点(讲义 slide 13)。从 4 到 8 这一档,依次加入第 5、6、7、8 个点,每次只加一个;讲者在这一页补了一句,这样得到的图案与前一页完全一样。按点递进与按幂跳档,在恰好落在 2 的幂上时是同一张图,差别只发生在两次跳档之间。

点的进入方式被单独讲了两页(讲义 slide 14、讲义 slide 15)。加一个点时,让它从上一个点的位置滑进来,新点在图上标成红色;其余点全部锁死,动的只有那个支点;滑到位的点会停在与原来相同的位置。这套做法带来的是分布偏斜。用因子 3 举例,得到的是两小段加一大段,绿的两段短、红的那段长。偏斜是这套稳定做法的直接后果,第 4 章会把它与 DX11 的均匀分布对照。

再往后是分布调整(讲义 slide 16、讲义 slide 17)。规则是按新加入的点调整分布,例子取因子 10.3,得到 11 段,其中 10 段长度为 1.0,另有一段长度为 0.3 处于滑动中;这套算法在 2 的幂处仍落在与原来完全相同的位置,同时比单点滑入这种做法的分布更均匀。这个 0.3 是滑动段,它随因子增长而增厚,到了整数档位就并进 1.0 那一列。

把这几页连起来读,推导的骨架是:先按 2 的幂给出档位,再把档位之间的跳变成逐点进入;点从上一个点的位置滑进来,落点与跳档时的位置一致;再把落点分布按新加入的点重排,得到更均匀的间距;最后一步取镜像并把最小因子定在 2。四步各有代价,前两步让分布偏斜,后两步把偏斜调轻。讲义 slide 14 与讲义 slide 15 的页内文字相同,差别只在讲义 slide 15 多出一段关于因子 3 的说明,把「两小段加一大段」这个具体形状点了出来(讲义 slide 14、讲义 slide 15)。讲义 slide 16 与讲义 slide 17 同样成对,讲的都是因子 10.3 那 11 段的分布与它在 2 的幂处落回原位这件事(讲义 slide 16、讲义 slide 17)。

最后一页把图案定了下来(讲义 slide 18)。做法是取上一版图案做镜像,最小细分因子取 2,中点常开;讲者在页面上点名,这套做法就是 DX11 的分数偶数细分(fractional-even tessellation)。到这里,后面所有比较的对象确定了:一边是这条线上均匀却会来回的点,另一边是可以改成稳定间距的点。

这条一维图案的分量在于它是后面一切比较的底座。因子从 1 到 64 的连续变化、档位之间的落点、滑入时点的次序,都会在三角形那一层原样出现(讲义 slide 11)。讲者把「三角形之前先说线」这件事单独写成一句引导语,第 4 章讲不收敛、第 5 章讲修线段,全都在这条线上做。

为什么这条一维图案就能代表三角面的最终图案,讲义 slide 11 只断言「这就是最终图案」,其间的理由讲义未给。为什么把最小因子取在 2、让中点常开,讲义 slide 18 把它作为 DX11 分数偶数的定义给出,取这个值的取舍讲义未给。这一段推导讲义给的是步骤与例子,讲者当场的取舍口播讲义未给。

这一章能核对的读数有五条。细分三角形之前要先处理一条线,每条边一个 float 因子,DX11 范围 [1,64](讲义 slide 11)。按 2 的幂跳档会产生很强的 pop(讲义 slide 12)。每次加一个点、其余点锁死,落地位置与原来相同,代价是分布偏斜(讲义 slide 13、讲义 slide 14)。因子 3 得到两小段加一大段;因子 10.3 得到 11 段,10 段为 1.0、滑动段为 0.3,且在 2 的幂处落回原位(讲义 slide 15、讲义 slide 16)。取镜像图案、最小因子 2、中点常开,得到的就是 DX11 分数偶数细分(讲义 slide 18)。下一章把这条线的稳定性问题摊开。

4DX11 的分数因子为什么不收敛

上一章把 DX11 分数偶数这条线的图案定下来,这一章报它的账:分得均匀,却极不稳定(讲义 slide 19)。

讲者在讲义 slide 19 把两种算法并排(讲义 slide 19)。DX11 的线段分布很均匀,代价是稳定性极低;简单那种算法分布偏斜,点却稳定,位移下锯齿更少。这一页给出的是一对交换项:均匀与稳定不能同时拿到,位移会把这笔账放大。

DX11 线段的两难页
图 4-1 E 类·证据 · 讲义 slide 19 · 原样引用 怎么读 ①指认:页面把两种算法并排,DX11 的分布很均匀但稳定性极低,简单算法分布偏斜但点在位移下更稳定、锯齿更少。②读法(怎么读):把「均匀」与「稳定」当成一对互相拉扯的量看,第 5 章修线段的两步就是在这两个目标之间换位。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

不收敛这件事在讲义 slide 20 被拆成一句可记的读数(讲义 slide 20)。每加一个点,位于它上方的点被推上、下方的点被推下;每个八度里,中点走 0.5 到 2/3 再回到 0.5;左图是第一八度,动画网格展示四个八度,区间分别是 2→4、4→8、8→16、16→32。中点在 0.5 与 2/3 之间来回,上下两点互相推,这里就是「收不住」的具体形状。这四个八度由讲义点名,再往上还有更高的档位,页面上没有继续列;中点在每个八度里都走同一段来回,八度越密、来回的频率越高。6 这个区域数也是第 6 章那条「少 1/3」的减数来源,4 与 6 的比在这一段先记下(讲义 slide 21)。

为什么 DX11 不收敛页
图 4-2 E 类·证据 · 讲义 slide 20 · 原样引用 怎么读 ①指认:页面说明每次加点时上方的点被推上、下方的点被推下,每个八度里中点走 0.5 到 2/3 再回到 0.5,左图是第一八度,动画网格展示 2→4、4→8、8→16、16→32 四个八度。②读法(怎么读):先把中点的那三个位置按顺序记住,再对照四个八度的区间,不收敛这件事落在「中点来回」与「上下互推」两点上。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

三角形这一层,DX11 的造法在讲义 slide 21(讲义 slide 21)。做法是把三角形拆成 6 个区域,名字叫 triforce-tessellation;随后丢弃外侧条带,好让每条边各自不同。6 这个区域数是后面比较的基准,第 6 章会把它与夹紧法的 4 区放在同一档细分上对照。

DX11 三角形 6 区拆法页
图 4-3 E 类·证据 · 讲义 slide 21 · 原样引用 怎么读 ①指认:页面回答 DX11 怎么造一个三角形,把它拆成 6 个区域,做法叫 triforce-tessellation,并丢弃外侧条带以让每条边各自不同。②读法(怎么读):先数 6 这个区域数,再看「丢外侧条带」这一步放在哪,第 6 章把它与夹紧法的 4 区对照读出 1/3 的差。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

各边的独立性另占几页(讲义 slide 22、讲义 slide 23、讲义 slide 24)。边的细分因子与内部因子是两套:把一条边单独降到 0 再拉回,由 gap-matching 条带吸收这份差异,内部不再重排;内部因子单独驱动内部密度,边固定不动,只有内部在长;到讲义 slide 24,讲者把成品状态列清楚,DX11 就是分数偶数,每条边可以带不同因子,内部也可以变,末尾抛出「改进的想法」(Ideas for improvement?)。「条带吸收差异、内部不重排」这条性质说明 DX11 的调整方式是局部的,差异被压在外圈那一条带上,整张内部图案不跟着动。

把一条边单独降到 0 再拉回这个动作,是把边因子与内部因子分家的一次演示(讲义 slide 22)。差异由 gap-matching 条带吸收,内部不重排,说明 DX11 的边与内部各自维护各自的密度,两者之间用一条条带做接口。讲义 slide 23 把内部那一侧单独拿出来,边固定不动,只有内部在长,这为第 6 章讨论「单一内部因子够不够用」留下了对象(讲义 slide 23)。讲义 slide 24 把成品状态收在一页:分数偶数、每边可带不同因子、内部可动,末尾一句是「改进的想法」(讲义 slide 24)。这一句是整段剖析的出口,第 5 章的两步修法就是对它的回答。

主线到这里就完整了:DX11 的分数因子分布均匀,代价是稳定性低;加点时中点在 0.5 与 2/3 之间来回,上下互相推移;三角形按 6 区拆,差异由外圈条带吸收。这三条合起来解释了为什么后面要换掉图案,而不只是换一个因子数值。

为什么这套不收敛的图案不能直接用在他们的场景里,讲义 slide 19 到 24 只给出性质与一个「改进的想法」的提问,讲者当场的判断讲义未给。DX11 的 6 区拆法为什么必须丢外侧条带、丢掉之后各边的差异具体怎么吸收,讲义 slide 21 与讲义 slide 22 给了做法与效果,更细的取舍与推导讲义未给。哪一类模型或测试场景最能暴露这份不收敛,讲义在这几页没有给出,测试场景讲义未给。DX11 这套图案当初为什么这样定、外圈条带按什么标准取宽,讲义未给。

这一章的结论可以逐条核对。均匀分布与高稳定性是一对交换项,DX11 选了前者,简单算法选了后者,后者的点稳定、位移下锯齿更少(讲义 slide 19)。每个八度里中点走 0.5 到 2/3 再回到 0.5,上下点被互相推移,共四个八度(讲义 slide 20)。DX11 把三角形拆成 6 区并丢弃外侧条带,让各边可以不同(讲义 slide 21)。边的因子与内部因子两套独立,单边降到 0 再拉回由条带吸收差异、内部不重排,内部因子单独驱动内部密度(讲义 slide 22、讲义 slide 23)。下一章接住「改进」这个词,先把一维侧退回稳定,再把平行四边形夹成三角形。

5先修线段,再把平行四边形夹成三角形

上一章的收口留了一句「改进的想法」,这一章按顺序给出两步修法,先修一维那侧(讲义 slide 25)。

修法第一步是退回稳定间距(讲义 slide 25)。做法是回到「一次加一个点」那种稳当间距,把稳定性提上来;讲义在这一页紧接着写明代价:分布会退回偏斜的状态。这一步的性质是一次交换,用一点均匀度换回稳定。

两页补充让分布不至于太难看(讲义 slide 26、讲义 slide 27)。第一处是插入次序,让奇数点先于偶数点插入以改善平衡,段数不变但没那么偏,讲者在页面上点了一句「看第 3 列」。第二处是滑入速度,旧算法里红点看着像突然冒出来,讲者注明它在技术上是连续的,新做法是让多个点一起慢慢滑入,不再一次一个快速滑入,页面上把同时移动的红点标了出来。

1→2 这一档单独处理(讲义 slide 28)。DX11 分数偶数的范围是 [2,64],传 1 进去在技术上可行,但会被夹到 2;这篇改成允许从 1 到 2 的过渡,办法是从两端同时滑入。这一档是低细分的门槛,下一节讲义 slide 33 会把「左边界至少在 2 才启用夹紧」这条条件接在这里。

一维侧修完,进入二维(讲义 slide 29、讲义 slide 30)。起手是两个边因子张出的一个平行四边形,用的仍是那套 1D 加点算法,在 U 与 V 两个方向各跑一遍,然后拼出平行四边形;讲者把利弊列得很短,好处是直,坏处落在形状上,拿到的是平行四边形,与三角形差一步。把它夹成三角形用一条式子:u = min(u, 1 − v);再加一个 gap 项来处理左右边不同的情形,这会产生退化点,讲者注明这是可解的问题,同时点出症结:左右两边被迫用同一个细分因子(讲义 slide 30)。

修法第二步的关键在讲义 slide 31(讲义 slide 31)。横纵两条 1D 点序列各自都对最后一点留出一个 gap,取两者的最大值作 gap,夹紧式随之写成 u = min(u, (1 − gap) − v);讲者在这一页补了一句,这条约束会留下一块开口区域。取 max 的作用是把两个方向里较大的那个间隙当作统一口径,缺口留给下一页的匹配算法去补。

夹紧平行四边形与 gap 页
图 5-1 E 类·证据 · 讲义 slide 31 · 原样引用 怎么读 ①指认:页面先讲「mind the gap」,横向与纵向的 1D 点都对最后一点留出一个 gap,取两者的最大值作 gap,再按 u = min(u, (1 − gap) − v) 夹进三角形,并标出这条约束会留下一块开口区域。②读法(怎么读):先找横纵两条 1D 点序列各自的那个 gap,再看 max 如何参与夹紧式,末尾那句「留出开口区域」接着接到讲义 slide 32 的匹配表。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用
(1) u = min(u, (1 − gap) − v),其中 gap 取横向与纵向 1D 点各自间隙的较大者(讲义原文未编号)

两步的结构可以合起来看:一维侧先退回稳定,二维侧再把平行四边形夹成三角形,两处都留着交换的味道。一维侧用一点均匀度换稳定,二维侧用一条夹紧式换「直的边界」与「可退化」,代价是那次左右两边被迫同因子的症结,以及一块需要另做表去补的开口区域(讲义 slide 25、讲义 slide 30、讲义 slide 31)。离线表这一步把运行期的形状计算换成查表:先向上取最近的 2 的幂再跨接,讲者把细节留在示例代码里(讲义 slide 32)。到这里,从一条线到一个三角形的主体推导就走完了,剩下的是把这条图案接到三角面的边界条件上。

缺口在讲义 slide 32 由一张表补上(讲义 slide 32)。匹配算法的目标是把这块 gap 填掉,做法是离线预计算成一张表、运行期快速查;步骤是先向上取到最近的 2 的幂,再跨接过去;讲者给了一句提示,说细节比较琐碎,细节请看示例代码。

完整图案在讲义 slide 33 定条件(讲义 slide 33)。低细分图案需要在中间多补一个点;夹紧平行四边形只在左边界的细分因子至少为 2 时才生效,当左边界的点正从 1 滑到 2 时它不适用;不满足这个条件时会额外加一个中心点。讲义 slide 34 页名就叫 Full pattern,页面上只有标题与一张图,本页无文字,这一页也没有取图(讲义 slide 34)。讲义 slide 34 给出一张完整图案图,本页无文字,凡需要在讲义 slide 34 上落脚的图案细节,讲义未给。

为什么 gap 取的是横纵两者的最大值、每个方向各留一个 gap 为何不行,讲义 slide 31 给出做法与「留出开口区域」这句注脚,取 max 的确切理由讲义未给。离线表为什么按 25 条 1D 线来组织,讲义只给结构,取这个规模的理由讲义未给。讲义 slide 33 只给出「左边界因子至少 2」这一条门槛,更完整的测试场景设置讲义未给。讲义 slide 34 那张完整图案的具体形状,讲义未给。

这一章的读数可以逐条核对。第一步是退回稳定的「一次加一个点」间距,代价是分布退回偏斜(讲义 slide 25)。补偿有两条,奇数点先插、多个点一起慢滑入(讲义 slide 26、讲义 slide 27)。1→2 的过渡改成从两端滑入,DX11 传 1 会被夹到 2(讲义 slide 28)。二维起手是两个边因子张出的平行四边形,先夹成三角形再补一个 gap 项,夹紧式见式 5-1(讲义 slide 29、讲义 slide 30、讲义 slide 31)。gap 由离线表匹配填补,算法是先向上取最近的 2 的幂再跨接(讲义 slide 32)。夹紧只在左边界因子至少为 2 时生效,否则补一个中心点(讲义 slide 33)。下一章把夹紧法相对 DX11 的三条优势摊开。

6省 1/3 三角形、从 1 个三角形平滑过渡、救细长三角形

上一章把平行四边形夹成三角形并补齐 gap,这一章按三件事报账(讲义 slide 35)。

第一件是低效图案(讲义 slide 35)。在同一档 2 的幂细分下,DX11 分出 6 个规则区域,比需要的多;夹紧平行四边形是 4 个;讲者给的读数是同样细分下少 1/3 三角形,这一页的例子里内外因子都取 16。1/3 这个差值挂在一个前提上,两边的细分档位相同,换档位就不成立。

低效图案对照页
图 6-1 E 类·证据 · 讲义 slide 35 · 原样引用 怎么读 ①指认:页面在内外因子同为 16 的情形下把两种图案并排,DX11 分出 6 个规则区域,夹紧平行四边形是 4 个,同为 2 的幂细分时后者少 1/3 三角形。②读法(怎么读):先固定「内外因子 16」这个前提,再数两边的区域数,1/3 这个差值要在同一细分档位上读。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

第二件是细长三角形(讲义 slide 36)。DX11 只有一个内部因子,结果是横向的内部点数没法多于纵向,行与列必有一侧欠细分或过细分;夹紧平行四边形在这里被记成能从容处理长而细的三角形。这一条说明内部因子单一带来的形状代价,第 2 章那条「内部图案由各边因子隐式定义」在这里换了形状依然成立。

第三件是形变与边环(讲义 slide 37)。形变要的是直的边环,不能有急弯;DX11 的四边形图元混着三角与四边形,拿不到干净的环;夹紧法给的是规则四边形,边环在退化时也能平滑过渡;讲者在页面上写明这就是要明确拒绝旋转对称(rotational symmetry)的原因。拒绝旋转对称与要直边环这两件事被写在同一条因果里。

最少三角形这条单独占一页(讲义 slide 38)。DX11 分数偶数的最少三角形数是 6,单是把它打开就会带来可观的三角形增量;分数奇数可以从 1 个三角形起步,代价是更多的不稳定;夹紧平行四边形能从 1 个三角形一路平滑过渡。把两条合起来读,DX11 在「最少 6 个」与「从 1 个起步但更不稳」之间二选一,夹紧法把过渡起点压到 1 个三角形。

最少三角形对照页
图 6-2 E 类·证据 · 讲义 slide 38 · 原样引用 怎么读 ①指认:页面给出 DX11 分数偶数最少 6 个三角形、开启即带来可观的三角形增量,分数奇数可从 1 个三角形起步但更不稳定;夹紧法能从 1 个三角形一路平滑过渡。②读法(怎么读):把「最少三角形」与「稳定性」当成一对交换项看,DX11 两条分支各占一边,夹紧法这一列把过渡起点压到 1 个三角形。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

实现落在表上(讲义 slide 39)。所有东西都存成表:25 条互不相同的 1D 线,每条线对每个位置存一个起始 t 与结束 t;夹紧平行四边形表按左边界与底边索引,是 25×25;gap 表按左边界与右边界索引,也是 25×25;三样合计表体积 1.6 MB(讲义 slide 39)。这 1.6 MB 的口径要说清,它指的是 25 条 1D 线加两张 25×25 表的合计,第 8 章讲义 slide 51 那组 2.5/8.6/30.2 MB 是另一套口径,两者不要合到一起。

把这一章的三条优势与第 2 章那三条硬要求对上:少 1/3 三角形回应的是效率,从 1 个三角形平滑过渡与能处理细长三角形回应的是形状,直边环与规则四边形回应的是形变(讲义 slide 10、讲义 slide 35、讲义 slide 36、讲义 slide 37、讲义 slide 38)。三处证据落在同一档 2 的幂细分这个前提上,比较能成立的条件是两边细分档位相同。实现这一页把整条推导固化成数据:25 条 1D 线各存一条线上的起止 t,夹紧表与 gap 表各按两条边索引(讲义 slide 39)。把形状写成表的代价是体积,1.6 MB 是这套结构的成本读数,也是它能在运行期快速查的前提。这三条优势的写法都带着对照项:低效图案对的是 DX11 的 6 区,细长三角形对的是单一内部因子,最少三角形对的是 DX11 分数偶数的 6 个起步值(讲义 slide 35、讲义 slide 36、讲义 slide 38)。三条都在回应第 2 章那句「内部图案由各边因子隐式定义」,把它落成可数的区域数与三角形数。

为什么表的规模按 25 条线组织、25 这个数字怎么来的,讲义只给了结构,取这个规模的取舍讲义未给。左边界因子达到 2 才启用夹紧这条门槛,讲义 slide 33 给了条件,为什么取 2 讲义未给。这三条优势在什么模型、什么相机距离上测出来,讲义在这几页没有交代测试场景,测试场景讲义未给。作者对这三条优势的排序与评价,讲义未给。这三条优势在什么档位区间内成立得最充分,讲义也没有给出范围;实现这一页也没有说明表是在 CPU 侧还是 GPU 侧组织,这些细节讲义未给。

这一章的结论可以逐条核对。同为 2 的幂细分、内外因子同为 16 时,DX11 是 6 个规则区域、夹紧法是 4 个,后者少 1/3 三角形(讲义 slide 35)。DX11 只有一个内部因子,行与列必有一侧欠细分或过细分,夹紧法能处理细长三角形(讲义 slide 36)。形变要直边环,DX11 拿不到干净的环,夹紧法给规则四边形并能平滑退化,这也是明确拒绝旋转对称的原因(讲义 slide 37)。DX11 分数偶数最少 6 个三角形,分数奇数可从 1 个起步但更不稳,夹紧法能从 1 个三角形平滑过渡(讲义 slide 38)。实现是 25 条 1D 线与两张 25×25 表,合计 1.6 MB(讲义 slide 39)。到这里,三角形这一段的三条要求与三条优势都已对上,第 7 章把对象放大到网格,用 compute 做自适应细分。

72D 每级 1/8、3D 每级 1/16:自适应的回报

上一章把三角形层面的账收在讲义 slide 39:25 条 1D 线加两张 25×25 表,合计 1.6 MB,夹紧平行四边形在同一个 2 的幂细分下比 DX11 少 1/3 三角形,还能从一个三角形平滑过渡。讲义 slide 40 起对象换成整张网格,Part 2 的分隔页把这一部分的定位压成三行:完全 compute 的自适应细分(Full Compute Adaptive Tessellation),先给每条边选细分因子,再把结果细分进「大而平的缓冲」(large, flat buffers);参考基线是原生 WebGPU,不带任何扩展(Vanilla WebGPU, no extensions)。页面最后一行把路线选择留成问句(Algorithm options?)。为什么在若干候选里这样定、为什么以原生 WebGPU 作基线,讲义未给。回看第 2 章讲义 slide 7 的三段议程,Part 1 讲三角形、Part 2 讲网格、Part 3 讲曲面,本章正落在中间那一段。

动手前,讲者先把已有的计算式细分路线摆了一遍(讲义 slide 41)。Nanite Tessellation [Karis 2026] 用整数因子加嵌套切分,因子变化时图案会 pop,只有当三角形误差落到亚像素时才看不出来,做法与 Reyes 的思路相近;Concurrent Binary Trees 与最长边二分 [Dupuy 2020]、[Deliot et al. 2021] 走递归级联切分,边与边之间存在依赖。作者在这一页把目标收成三条:分数因子(fractional)、边互相独立(independent edges)、不 pop。这三条与第 2 章讲义 slide 10 写下的硬要求接在同一条线上,讲义 slide 10 要分数因子不 popping、三边互不影响,并且明确要偏离 DX11 的「对称」与「单一内部因子」两条约束;Part 1 已在三角形层面兑现,Part 2 要确认它在一整张网格上仍然成立。

两条既有路线各自卡在一处。Nanite 那条的因子按档跳,图案跟着跳,作者给的缓解条件是把三角形误差压到亚像素以下;CBT 与最长边二分那条把切分做成递归级联,一条边的切分要看邻居边。作者的三条目标要同时绕过这两处:因子取分数值、三条边各算各的、结果不 pop。这三条也是第 2 章讲义 slide 10 那两句约束在网格尺度上的复述。

讲义 slide 42 给出这套自适应在 2D 里的第一笔账(图 7-1)。2D 中每升一级,线段数变成 2 倍,误差降到 1/4;用 2 倍线段换 1/4 误差,每一级的效率就只剩上一级的 1/8。作者在同一页写了一句总结,说前期收益很大,随后回报迅速递减(Huge early gains, rapidly diminishing returns)。把 1/8 反过来读,要让误差再降一级,成本要按 8 倍往上翻,细分越深,多出来的那一级越难回本。这条比值是后面推自适应回报的起点,页面没有模型,也没有任何测量读数。

2D 效率规则:每级 1/8
图 7-1 E 类·证据 · 讲义 slide 42 · 原样引用 怎么读 ①指认:2D 效率规则页,把「每级线段 2 倍、误差 1/4」与「每级效率只剩上一级的 1/8」并排放,页脚写着前期收益大、随后迅速递减。②读法(怎么读):当作一条算术规则的说明来读,页面上没有模型也没有读数,它是本章推自适应回报的起点。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

3D 那边衰减更快(讲义 slide 43,图 7-2)。每级的误差同样降到 1/4,但每级的三角形数是 4 倍,而 2D 只翻 2 倍;1/4 误差换 4 倍成本,每级效率落到 1/16。作者写了一句,收益比 2D 吃得更快(Gains diminish even faster than 2x)。把两页并排看,能读出这套方案的处境:细分越细,边际收益掉得越狠,把预算花在看不见的地方代价不成比例。Part 2 要把细分搬到 compute 上做自适应,来处就在这里。

3D 效率规则:每级 1/16
图 7-2 E 类·证据 · 讲义 slide 43 · 原样引用 怎么读 ①指认:3D 效率规则页,误差每级同样降 1/4,成本换成一级的三角形 4 倍,页脚写收益比 2D 衰减更快。②读法(怎么读):与图 7-1 成对读,两页只差「每级成本翻 2 倍还是 4 倍」这一处,效率就从 1/8 掉到 1/16。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

真实网格里的多边形并不匀(讲义 slide 44)。讲者用一个最简例子:三个初始四边形。固定细分会把薄的和小的四边形过细分,把大的欠细分;同一页左图是自适应,右图是固定。两张图摆在一起,等于把「同样的细分预算,按面积与屏占比分还是按网格均匀分」这个问题直接摊开。这个例子为什么只用三个四边形、评估用的模型与场景是什么,讲义未给。

回报落在讲义 slide 45 的对比上(图 7-3)。上图是固定细分,62.6k 三角形;中间是自适应,46.5k 三角形却给出更细的细分,大三角形被更激进地细分,小三角形与离屏三角形更保守。作者还给了另一个数:要达到相近的细分尺寸,需要约 560.1k 三角形。这三个读数出自同一个模型,模型名要到讲义 slide 74 才出现(Monkey,Blender Suzanne,507 顶点/968 源三角形),讲义 slide 45 页内没有写模型;「相近细分尺寸」用什么口径量、测试场景如何设置,讲义未给。

自适应的回报:46.5k 对 62.6k
图 7-3 E 类·证据 · 讲义 slide 45 · 原样引用 怎么读 ①指认:自适应对固定的对比页,上图固定 62.6k,中间自适应 46.5k,正文另给「相近细度约 560.1k」。②读法(怎么读):三个读数要带模型这一层读,讲义 slide 45 页内没写模型名,模型要到讲义 slide 74 才出现;口径与测试场景讲义未给。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

把讲义 slide 44 的例子与讲义 slide 45 的读数放在一起,能看出自适应把预算挪到了哪里:大的三角形多分,小的与离屏的少分,固定那一份按网格均匀铺开。讲义 slide 42 到 45 补上的就是这套做法的收益这一半。

本章可核对的结论有三条。2D 每升一级线段 2 倍、误差 1/4,每级效率 1/8(讲义 slide 42);3D 每升一级三角形 4 倍、误差仍是 1/4,每级效率 1/16,衰减比 2D 更快(讲义 slide 43);同一模型下固定细分 62.6k 对自适应 46.5k,而拉到相近细度要约 560.1k(讲义 slide 45)。三条合起来把「预算该往哪里挪」讲成了算术,接下来第 8 章要看把这件事落成工程时要付哪些账。

8工程面的四件事:内存、缝、因子与多趟帧

上一章把自适应的收益讲成了算术,每级效率只有 1/8 或 1/16,预算要花在看得见的地方。讲义 slide 46 到 51 换成工程面,把这件事落成内存、焊接、因子选择与多趟帧四件事,另外还带上溢出的处置。这四件事都不改动上面的算术,它们决定的是这套算术在真实引擎里能不能落地。

内存先摆出来(讲义 slide 46)。作者按 16M 三角形与 16M 顶点两个上限设计缓冲:Indices 每三角形 3 个 u32,Positions 与 Normals 各是每顶点 3 个 f32,这三项各 192 MB;Barycentrics 每顶点 1 个 u32,按 2×16 打包,64 MB;最后一项 Src Tri Index 页内没给尺寸。作者给的上限读数是约 704 MB,并自评「还有很大改进空间(mesh shaders!)」,属性插值放在 VS 里做。这里为什么没有改用 mesh shader、704 MB 的分项如何加总,讲义未给;这个约 704 MB 是上限处的设计估算,第 12 章边界 3 再交代一次。

这一页的分项逐项列得很清楚:Indices 按三角形存三条索引,Positions 与 Normals 逐顶点存,Barycentrics 用 1 个 u32 打包两个 16 位值,Src Tri Index 只给了名字。属性插值放在 VS 里做,页内的分项只列了几何、法线与重心这几类量。

焊接是第二件(讲义 slide 47)。页内把缝的来处列成四条:UV 缝、贴图偏导(texture partial derivatives)、圆整误差(roundoff error)、以及材质缝,材质缝举的例子是一面砖墙接到一面混凝土墙。处置是一个统一的后处理:焊位置,四角与边分成两个 pass。作者把这件事归为硬件细分的固有局限(fundamental limitation with hardware tessellation),只给了结论;为什么算固有、两个 pass 各自处理什么、这一步的耗时,页内都没有给。

第三件是因子怎么选(讲义 slide 48)。作者点了两个灵感来源,[Brainerd 2014] 与 [Karis 2026]。[Brainerd 2014] 用线性求值点到中点的距离;本篇改用 Phong 近似,取两端顶点的极限位置与法线,误差取 Phong 中点与线性中点之差;度量上用弧角(arc angle)替代屏幕投影(screen projection)。误差既然是估计出的中点与真实中点的偏差,因子就可以按这个偏差去定;为什么换成 Phong 近似、为什么用弧角替代屏幕投影,讲义未给。

度量口径选在极限位置与法线上,不落在屏幕投影上,等于把误差定义留在三维空间里;这样选的代价与收益,讲义未给。

第四件是数据太多怎么办(讲义 slide 49)。若因子把缓冲撑爆,目标是「不崩」,作者用的评语是「够用即可」(Good enough)。处置办法是先丢细分因子,知道会超就先丢;页面还写了「还有很大改进空间」,可以减到一半或四分之一,也就是把缓冲再压一半或四分之三。溢出阈值取多少、何时判断、测试场景是什么,讲义未给。

溢出的处置顺序是先丢细分因子,把不崩这条底线放在前面,「够用即可」这句评语说明作者没有在这条路上追求精度。丢哪些因子、按什么次序丢,讲义未给。

多趟帧把这份账放大(讲义 slide 50,图 8-1)。DX11 的细分在同一趟里既生成又消费,页面称其优雅之处是常量内存,与细分尺寸无关;代价是换成多趟时每趟都要算一遍。多数引擎每帧要跑多趟:Pre-Pass、GBuffer、Motion Vectors、Shadow Depth。本篇的办法是把细分后的顶点存一次、焊接,之后每趟复用。这张图打的是动机,页面没有毫秒数,成本读数要到第 12 章才出现;为什么是这几趟、还有没有别的趟,讲义未给。

把讲义 slide 46 到 51 连起来看,这四件事绕着同一个矛盾:自适应的收益来自把三角形用在看得见的地方,而每多一趟渲染、每多一处缝、每多一档因子,都要多付一份固定的存储或内存。作者在这一页给出的统一应对是「建一次、复用多次」,第 12 章的每趟成本读数就是这个应对的兑现。

多趟帧:DX11 常量内存的代价
图 8-1 E 类·证据 · 讲义 slide 50 · 原样引用 怎么读 ①指认:多趟帧的动机页,左边是 DX11 同趟生成兼消费带来的常量内存,右边列出多数引擎每帧要跑的多趟,以及「存一次、每趟复用」的处置。②读法(怎么读):把它读成第 12 章每趟成本读数的来处,页面上只有多趟清单与处置,没有毫秒数。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

最后是大表(讲义 slide 51)。对每个夹紧平行四边形组合(25×25)预计算一整张表,尺寸随最大因子变化:64 时 2.5 MB,128 时 8.6 MB,256 时 30.2 MB。页面还写了「解析版也实现过,但表更快」,并留了一条 TODO,要预计算 meshlets。表为什么比解析快、meshlets 预计算怎么做,讲义未给。这组口径与讲义 slide 39 的 1.6 MB 属于两件事,前者是单档随因子膨胀的整表,后者是 25 条 1D 线加两张 25×25 表的合计,第 12 章边界 8 再把两处分开。

讲义 slide 46 与讲义 slide 40 的缓冲口径是同一条:Part 2 定的是「大而平的缓冲」,这一页把它拆成逐项的大小。两个上限各 16M,页内没有说明这些缓冲是一趟用满还是分帧复用,也没有给出这套缓冲在某个实际模型下的占用量,讲义未给。

本章可核对的结论有四条。内存上限约 704 MB,分项为 192/192/192/64 MB,末项未给尺寸(讲义 slide 46);焊接的四个来处是 UV 缝、贴图偏导、圆整误差、材质缝(讲义 slide 47);因子用两端极限位置的 Phong 近似,按弧角度量(讲义 slide 48);整表随最大因子为 2.5/8.6/30.2 MB(讲义 slide 51)。四件事里,多趟帧的处置要在第 12 章被兑现成一组每趟成本读数,下一章起进 Part 3,把同样的 compute 思路用到曲面上。

9Catmull-Clark 全程解析:双三次与半锐折痕

上一章收到多趟帧那件事上,处置办法是把几何存一次、每趟复用;讲义 slide 52 起进入 Part 3,对象从网格换成曲面,分隔页的副标题写着「也用 compute」(Subdividing a Surface, also with compute)。把 Part 3 与 Part 2 并排看,两者的输入不同。Part 2 输入的是一张已经定好的网格,要解决的是怎么按屏幕与误差去分配三角形;Part 3 输入的是美术做的低模,要先解决这张网格本身从哪来,细分出光滑曲面之后按同一套 compute 思路求值。两部分都用 compute,是这一整篇的骨架。

讲义 slide 52 的分隔页交代背景:Catmull-Clark 是 Geri's Game(1997)以来的电影标准,美术做低模、渲染时细分;位移在这套流程里是层级位移(hierarchical displacement),位移量取相对细分曲面的增量(delta vs. the subdivision surface),工具一侧列了 ZBrush、Mudbox、Blender。这套作者流程把「模型」与「细节」分成两层,低模管形状,位移管表面起伏。为什么要自制这套求值而不用现成工具,讲义未给。

规则本身在讲义 slide 53 上(图 9-1)。每一级做三件事:算面点(Face Points)、算边点(Edge Points)、算顶点点(Vertex points)。作者写了两条性质:这套算法稳定且良态(stable and well-behaved);它是线性的,每个细分后的点都是 2 poly ring 内点的线性组合,也就是当前 poly 加上周围一圈。这条 2-ring 本地性决定了后面 compute 里每个线程要取多大邻域,因为一个点只依赖固定的邻居范围,就可以并行地成批算出来。

三条规则按固定顺序套用,面点先定,边点要用到相邻两个面点,顶点点再用到周围的面点与边点。三条都是对邻居取加权平均,权重固定,因此在规则处可以一次算完,不必沿着网格反复迭代。作者把「稳定」与「线性」写成两条性质,后面能把它塞进 compute 就靠这两条。

Catmull-Clark 三条规则
图 9-1 E 类·证据 · 讲义 slide 53 · 原样引用 怎么读 ①指认:Catmull-Clark 的三步规则页,面点、边点、顶点点三条并排,下面两条性质是稳定与线性。②读法(怎么读):重点落在 2 poly ring 这条本地性上,它圈定了每个细分点依赖的范围,也决定后面 compute 的访存半径。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

半锐折痕(semisharp creases)补上倒角(讲义 slide 54)。原生 Catmull-Clark 处理不好尖锐倒角,半锐权重的做法是先按锐规则走 N 级,再混合到平滑;这条做法被广泛采用 [DeRose et al. 1998]。折痕要解决的问题是:模型上有的边要保留硬边,例如桌面棱角,有的边要完全光滑,半锐权重给的是一根可调的中间档。N 怎么取、按什么标准取,讲义未给。

规则四边形可以直接当双三次 B 样条(bicubic B-splines)求(讲义 slide 55)。规则 4×4 控制网格能在任意 (u,v) 处解析求值,位置与法线都求。2D 双三次基是可分的(separable),等于 1D 三次基用两次:先在 v 方向求 4 列,再用一条 u 方向曲线穿过这些结果。作者在这一页明确写了「无需递归」(No recursion needed!),并限定它只在规则 poly 上成立。可分的意义在于把一次 2D 求值拆成 4 次 1D 求值加 1 次 1D 求值,省掉递归下降,这也是后面能在 compute 里逐点解析求的前提。

4×4 的控制网格对应一层 1D 三次基的四个控制点,先在 v 方向对四列各求一次一维曲线,得到四个中间点,再沿 u 方向求第五条一维曲线,结果就是曲面在该 (u,v) 上的位置。可分这条性质把二维求值拆成一维求值的组合,每一步只涉及四个控制点,计算量固定,便于并行。

半锐折痕不破坏解析性(讲义 slide 56)。沿用同一条 1D 三次基,折痕只是换一次基 [Nießner et al. 2012b]:控制点上一个 4×4 矩阵,矩阵由半锐权重推出。遇到多条锐边或一个锐角,就把那个邻域按不规则处理。换基这个说法把折痕纳进了同一套可分求值里,代价是每个带折痕的规则 patch 要多做一次 4×4 变换。

折痕被限制在一条线上(讲义 slide 57)。求值仍可分:4 条 v 方向样条,再用一条 u 方向穿过结果。x = 0 那条线是唯一允许放半锐折痕的地方,折痕在那里只是 1D 三次基的一次换基 [Nießner et al. 2012b],别处保持普通双三次。作者没有说明为什么只允许一条、为什么必须落在 x = 0,讲义未给。把折痕限制在一处,换来的是别处可以一律按最省的双三次处理。

讲义 slide 58 把前面几页收成一块积木:带 1 条可选半锐折痕的规则四边形,是整个算法的基本积木(primary building block)。作者在同一页写下问题:把整张细分曲面分解成规则网格(至多 1 条半锐折痕),并对偏离规则网格的罕见情况做特殊处理。这里已经把整章的工作切成两半,前半是规则的解析积木,后半是那部分不合群的顶点怎么安放。

作者把问题写成两句,等于给后面定了序:先按规则网格去分解,规则处走讲义 slide 55 到 57 的可分求值;遇到偏离规则网格的情形再单独处理。规则部分与不规则部分怎么衔接,是下一章要处理的事。

讲义 slide 55 到 57 三页合起来是同一个求值模板:控制点 4×4、可分求值、至多一条折痕落在 x = 0。规则区之外怎么处理不在这三页里,页内把它留成讲义 slide 58 的第二句问题。

本章可核对的结论有四条。Catmull-Clark 每级三步是面点、边点、顶点点,且线性、2-ring 本地、稳定(讲义 slide 53);规则 4×4 控制网格可按可分双三次解析求位置与法线,无需递归(讲义 slide 55);折痕只是一次换基,一个 4×4 矩阵由半锐权重推出,多条锐边或锐角按不规则处理(讲义 slide 56);折痕只允许出现在 x = 0 线上(讲义 slide 57)。这块解析积木备好之后,下一章把它铺满整张网格。

10Feature-adaptive 收缩与 compute 重算 patch

上一章把解析求值收在「带 1 条可选半锐折痕的规则四边形」这块积木上,并把问题留成两条:怎么把整张曲面分解成规则网格,怎么处理偏离规则网格的罕见情况。讲义 slide 59 起给出分解办法,讲义 slide 67 起给出本篇的 compute 做法,中间讲义 slide 61 到 66 用一个不规则顶点把细分一步走完一遍。

分解靠 feature-adaptive subdivision(讲义 slide 59,图 10-1)。只有贴着不规则顶点的四边形保持不规则,新产生的四边形按构造就是规则的,不规则数量每一级线性增长,比 4 倍膨胀好得多。作者在这一页留了一句「2012 年是 Catmull-Clark 细分的好年景」,指向同年的两项工作。线性增长是这套方案的关键读数,页内把它与 4 倍膨胀并提。

作者把线性增长与 4 倍膨胀对照,页内写的是「远优于 4× 膨胀」;这一条与讲义 slide 66 的「收缩到足够小」是同一件事的两端。

Feature-adaptive 收缩
图 10-1 E 类·证据 · 讲义 slide 59 · 原样引用 怎么读 ①指认:feature-adaptive 收缩页,只有贴不规则顶点的四边形保持不规则,新四边形按构造规则,不规则量每级线性增长。②读法(怎么读):把它与 4 倍膨胀对照读,线性增长这一条决定了后面能把不规则区收缩到「足够小」。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

讲义 slide 60 摆出另一条路线:feature-adaptive subdivision 配 DX11 硬件细分 [Brainerd et al. 2016],patch 存成 quadtree,形变走 stencil 表 [OpenSubdiv];问题拆成两步,先由 DX11 硬件细分,再由 Domain Shader 求值细分后的点;形变之后用 compute 生成 patch 数据,位置与法线在 Domain Shader 里求,同样依赖大表。这一页的路线的定位要说清楚:本篇最终方案是讲义 slide 67 到 73 的 compute 版,讲义 slide 60 的 DX11 quadtree 路线与它并列出现,二者之间的取舍理由,讲义未给。这条路线与第 8 章的多趟账放在一起看,能看出 DX11 那条路每趟都要重跑的形状。

一个细分步的过程在讲义 slide 61 到 64 上逐帧展开。起点是控制笼(control cage):一个不规则顶点,周围五个四边形(讲义 slide 61)。随后四个阶段依次是:每个面生成一个面点,取该面四角的平均(讲义 slide 62);每条边生成一个边点,取该边与它两侧两个新面点的平均(讲义 slide 63);最后移动原顶点,用周围的面点与边点(讲义 slide 64)。作者称这是一个自包含的递归式。四步的顺序不能乱,边点要用到面点,顶点点又要用到面点与边点,这也是讲义 slide 68 里每算完一步就来一次 GroupSync 的原因。

四个阶段都只用到局部邻居,面点只用它所在的那一个面,边点只用一条边与两侧面点,顶点点只用周围一圈。有限步的加权平均让这一层递归能在 compute 里按步同步着往前走,每一步的范围都是常数。

继续细分时,每个原始 poly 裂成 4 个,其中 3 个变规则,1 个仍不规则(讲义 slide 65)。内层继续递归(讲义 slide 66):内层点的拓扑与初始拓扑完全相同,不规则区域每级缩小,按作者的说法是指数级变小;缩小到「足够小」就改用线性插值;这一步自包含,不依赖别的顶点。自包含意味着重算一个 patch 不必访问整张网格,只需这一小片数据。阈值「足够小」到底取多少,讲义未给。

本篇的做法在讲义 slide 67 上:一个线程一个 poly,5 个 poly 就开 5 个线程,每线程 6 个初始点;把多个不规则顶点放进同一个组,工作组上限 64 线程;数据在 LDS 里来回倒(ping pong)。为什么把工作组定在 64、为什么不规则顶点要挤在同一组,讲义未给。讲义 slide 68 给出每级的调度形状:算出面点、边点、顶点点、中心点,每一步之后各来一次 GroupSync,最后写 Point Data;每轮迭代从每线程 6 点进、12 点出。6 点进 12 点出这条关系,说明每级细分把每线程负责的点数翻了一倍。

每线程的起点固定成 6 个点,级数往上走时写出的点数翻倍,起点数不变。作者没有写明为什么取 6 点,讲义未给。

讲义 slide 69 讲白 patch 与极限点。不规则点 CS 生成一组「切片」(slices);求一个最终点时先确定它落在哪个规则网格并求值,若落在小不规则区内,就取规则 patch 上的最近点再做插值。只有原始线可以是半锐,需要做一次旋转;旋转的具体规则,讲义未给。讲义 slide 70 收不规则点:任何贴着不规则点的四边形都细分一次,得到一个不规则扇面(irregular fan),别处仍是规则 poly。讲义 slide 71 处理三角形:三角形与它的所有邻居都要细分两次;三角形中点是坏规则点,三角形角点可能不规则,但需要引用二次细分后的相邻 poly。

讲义 slide 61 到 71 这一串是同一个 compute 内核的不同环节:讲义 slide 67 定线程与数据流,讲义 slide 68 定同步与产出,讲义 slide 69 到 71 分三类输入各自怎么走。页内没有给出这套内核的耗时,性能读数要到第 12 章。

本章可核对的结论有五条。只有贴不规则顶点的四边形保持不规则,新四边形按构造规则,不规则量每级线性增长(讲义 slide 59);一个细分步是控制笼、面点、边点、顶点点四阶段,面点取四角平均、边点取边与两侧面点平均、顶点点用周围面点与边点移动(讲义 slide 61 到 64);每个原始 poly 裂成 4 个,3 个规则、1 个仍不规则(讲义 slide 65);compute 里一线程一 poly、每线程 6 点进 12 点出、每级四步各一次 GroupSync(讲义 slide 67、68);三角形及其邻居细分两次(讲义 slide 71)。不规则区收缩到「足够小」之后怎么分类,是下一章的事。

11只有四类区域,不需要 quadtree

上一章把 feature-adaptive 收缩铺满整张网格,并把求值交给按 poly 开的 compute 线程;讲义 slide 72 与讲义 slide 73 把这件事收成一张分类表与一条求值路径。本章的结论是:分类只有四类区域,所以不需要 quadtree,求值时按规则与不规则两条路分开处理。这条结论把前面几章散落的东西合成了一个可以直接写进 shader 的形状。

四类区域在讲义 slide 72 上(图 11-1)。规则四边形是 1 个区域;至少含一个不规则点、但不含三角形的四边形,细分一次得到 4 个区域;贴到至少一个三角形的四边形,细分两次得到 16 个区域;三角形始终把拓扑细分两次,得到 12 个区域。四档数字是页内直接给出的:1 档对应规则四边形,4 档对应恰有一个不规则点的四边形,16 档对应贴到三角形的四边形细分两次,12 档对应三角形把拓扑细分两次。为什么这样分类、为什么四类就够、为什么不需要 quadtree,讲义未给。

四档数字背后是两种处理:规则四边形与含不规则点的四边形都只细分一次,贴到三角形的四边形要细分两次,三角形自己也要细分两次。页内按「有没有不规则点」与「有没有三角形」两件事把四边形与三角形分开处理,于是有四类。为什么选这两件事作判据,讲义未给。

四类区域,不用 quadtree
图 11-1 E 类·证据 · 讲义 slide 72 · 原样引用 怎么读 ①指认:区域分类页,四行分别是规则四边形 1 区、含不规则点 4 区、贴三角形 16 区、三角形 12 区,标题写明不用 quadtree。②读法(怎么读):把这四档当成上界的记账来读,页面上没有说明为什么四类就够,这一层按「讲义未给」对待。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

求值那条路在讲义 slide 73 上。输入是一个三角形 ID 与重心坐标,输出是极限位置与法线;三角形先重映射进子四边形,之后的处理一律按四边形走。这一步重映射把三角形与四边形的两套逻辑并成一套,下游只剩四边形一种情形。规则区域取 16 个控制点做双三次求值,法线解析求。这 16 个控制点与第 9 章讲义 slide 55 的 4×4 控制网格是同一块积木。

重映射这一步把三角形的情况并进四边形,等于把四边形定成这套算法的基本单元;三角形只在输入与邻居关系上存在,求值时先被拆成子四边形。作者在讲义 slide 73 的标题里写「求一个顶点」,说明这一层是逐点求值,与讲义 slide 67 的「一个线程一个 poly」正好接上。

不规则区域的处理更绕:先绕不规则顶点(extraordinary vertex)找出这个点所在的环,取该环的 16 个点,套上折痕再求值,如果落在未知区域就混合到中心极限。为免 pop,结果按细分因子与一条平坦基线混合,低细分时保持平坦。位移在同一个 shader 里做,写入位置与法线;位移量定义在细分曲面之上,与第 9 章讲义 slide 52 的层级位移是同一件事,讲义 slide 73 把它放在这一步一并完成。混合基线的具体系数、未知区域的边界怎么定,讲义未给。

规则区与不规则区这两条路合起来覆盖了四类区域:1 区的规则四边形直接走 16 控制点双三次;4 区与 16 区里出现不规则点的部分走找环、取 16 点、套折痕、混合中心极限;12 区的三角形在前一步已经重映射进子四边形,下游仍按四边形处理。作者把这套分支写进同一个 compute 入口,输入统一为三角形 ID 加重心坐标。

把这一章与讲义 slide 60 那条 DX11 路线并排,能看出「不用 quadtree」这份结论的分量。讲义 slide 60 的做法要把 patch 存成 quadtree,再靠 stencil 表与 Domain Shader 求值,存储与索引都随不规则区走;讲义 slide 72 的分类只有四档,规则四边形根本不需要树结构,含不规则点与含三角形的四边形各自细分固定次数,三角形的块数也是定值。分类一旦定死,compute 就按区域类型分支,不再维护一棵随形变更新的四叉树。分类依据为什么能简化到四档、这套分类与讲义 slide 60 的 quadtree 相比省下多少,讲义未给。

分类表还解释了讲义 slide 59 的收缩为什么能停:不规则区域收缩到「足够小」之后,剩下的规则部分整片走规则区那条路,不再需要逐级维护不规则列表。四类区域是这套收缩的终点形态,也是 compute 里分支的判据。四类之外还有没有别的区域、偏离网格时怎么兜底,讲义未给。

讲义 slide 73 的两条路各有一套输入形状:规则区要凑出 16 个控制点,不规则区要凑出该环的 16 个点,两者点数一样,来源不同。页内没有给出这两条路各自的开销占比,也没有给出逐点求值在一次帧里的调用次数,讲义未给。

本章可核对的结论有三条。区域分类是 1/4/16/12 四档,分别对应规则四边形、含不规则点的四边形、贴三角形的四边形与三角形(讲义 slide 72);求值输入是三角形 ID 加重心坐标,输出是极限位置与法线,三角形先重映射进子四边形(讲义 slide 73);规则区走 16 控制点的双三次与解析法线,不规则区找环、取 16 点、套折痕、再混合到中心极限(讲义 slide 73)。到此 Part 3 的方法部分讲完,第 12 章换成结果与成本账。

12结果与成本账:多趟帧下约 3 倍,以及横比口径

上一章把求值收成四类区域与两条路;本章收口,把结果、成本与横比口径摆清楚,材料来自讲义 slide 74 到 84。结果一侧的首个读数是模型规模:Monkey 是 507 个源顶点、968 个源三角形(讲义 slide 74)。固定细分给 61,952 个三角形,自适应给 30,526 个,作者说实心着色下几乎分不出差别(图 12-1)。

结果:自适应 vs 固定
图 12-1 E 类·证据 · 讲义 slide 74 · 原样引用 怎么读 ①指认:结果页,模型是 Monkey,507 源顶点/968 源三角形,固定 61,952 对自适应 30,526 个三角形,页脚写实心着色几乎不可区分。②读法(怎么读):三个读数要带模型一起读,它与讲义 slide 45 的 62.6k/46.5k 是同一模型在不同相机设置下的两组数。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

讲义 slide 75 把相机推近再对比:网格大部分已经出屏或到了相机后面,自适应把密度从看不见的地方挪到轮廓上,用不到一半的三角形拿到比固定更多的轮廓密度。作者补了一句对美术的判断,说美术擅长按屏幕上的常见尺寸做资产,但总有例外。这句是作者的评价,例外出现时会造成什么后果,讲义未给。

成本一侧先要认清计的是哪一段。讲义 slide 76 的标题写明是 compute cost only,平台是 RTX 3070,两项分别是 subdivision(建控制点)与 tessellation(建拓扑、顶点即位置/法线/重心,以及焊接)。讲义 slide 77 对的是 OpenSubdiv:它用一段很短的 compute 求控制点,再一趟融合的 DX11 细分与渲染,一旦要多趟(GBuffer、阴影等)每趟都要完整跑一遍 Catmull-Clark;自适应的做法是把几何建一次(subdiv 加 tess),之后每趟只光栅化存好的缓冲,在 VS 里插值。讲义 slide 78 给出每趟成本(图 12-2):单光照趟每 1M 三角形是 0.36 对 0.50 ms,光照加 4 道阴影是 0.81 对 2.51 ms,约 3 倍。讲义 slide 79 补一句控制点计算很轻,0.03 到 0.14 ms。

多趟成本:约 3 倍
图 12-2 E 类·证据 · 讲义 slide 78 · 原样引用 怎么读 ①指认:每趟成本页,单位是每 1M 三角形的毫秒数,单光照趟 0.36 对 0.50,光照加 4 道阴影 0.81 对 2.51。②读法(怎么读):先确认口径是 RTX 3070 上的 compute-only、不含渲染,再看「自适应只 tessellate 一次、OpenSubdiv 每趟都做」这条差别。 来源:SIGGRAPH 2026 Advances · Adaptive Tessellation and Subdivision · 讲者 John Hable(Meta)· 未修改引用

对手一侧在讲义 slide 80 到 82。讲义 slide 80 的 Edge-Friend 是统一(uniform)Catmull-Clark 求值器 [Kuth et al. 2023],拓扑隐式,用 mesh 与 amplification shader,法线在 mesh shader 里算,作者用的是 Wei Liao 的实现。讲义 slide 81 的 DV21 是 halfedge 精化规则 [Dupuy & Vanhoey 2021],同样走统一细分;[Dupuy & Deliot 2022] 以 DV21 为前置,所以 DV21 的数可当成本下界。讲义 slide 82 给出单位与比值:单位是每毫秒百万输出三角形;Edge-Friend 比本篇快 1.32 到 1.68 倍,DV21 比本篇慢 1.91 到 2.45 倍。同一页还写测过 NVIDIA RTX Mega Geometry SDK,因为内存不够(最低 10 GB)没测成。

讲义 slide 83 是 Try it!,给出两个 blog 链接,一篇讲带 compute 细分的自适应 Catmull-Clark,一篇讲夹紧平行四边形的图案,并写明所有代码是 MIT 许可;致谢里点了 Natalya Tatarchuk 与 Gregory Mitrano。这里的 MIT 只覆盖随讲义发布的 WebGPU demo 与示例代码,不覆盖讲义版面与 21 件插图。讲义 slide 84 是作者自陈的 Next Steps,属于缺口清单,见边界 6。

边界 1:讲义 slide 76 到 79 的性能读数全部是 RTX 3070 上的 compute-only,不含渲染时间。 讲义 slide 78 的 0.36/0.50 ms 与 0.81/2.51 ms 都标在「每 1M 三角形」的每趟口径上,讲义 slide 79 又明确写了「Not including render time」,所以它们既不能当整帧开销,也不能与讲义 slide 82 的对手数直接相减。测试用的模型、场景设多少三角形,讲义未给。

边界 2:讲义 slide 80 到 82 的对手口径与本篇不同,不可直接横比。 Edge-Friend [Kuth et al. 2023] 与 DV21 [Dupuy & Vanhoey 2021] 都是只算位置的统一细分;本篇跑的是全自适应管线,算位置、算法线并生成拓扑,还把因子锁到固定值(讲义 slide 82)。而且 Edge-Friend 只量了原始位置计算,没量渲染(讲义 slide 80)。1.32 到 1.68 倍与 1.91 到 2.45 倍是在两种任务上相减的结果。RTX Mega Geometry SDK 因内存门槛(最低 10 GB)未测(讲义 slide 82)。

边界 3:讲义 slide 46 的约 704 MB 是缓冲区设计估算,没有实测占用作对照。 它对应 16M 顶点与 16M 三角形两个上限(讲义 slide 46)。分项是 Indices、Positions、Normals 各 192 MB、Barycentrics 64 MB,末项 Src Tri Index 页内没给尺寸,约 704 MB 是页内给的上限口径;作者自评「还有很大改进空间(mesh shaders!)」。把它当成实际显存占用,取决于是否真的填满上限。

边界 4:三角形计数依赖具体模型,引用必须带模型。 讲义 slide 44、45、74、75 的读数都基于 Monkey(Blender Suzanne,507 顶点/968 源三角形,讲义 slide 74);讲义 slide 45 的 62.6k、46.5k 与「相近细分尺寸约 560.1k」是同一模型下的数,而讲义 slide 45 页内没写模型名。另外讲义 slide 5 的「1.19 MB 约 5.45M 三角形」是位移后的目标密度,与讲义 slide 74 的源网格是两个层级,不能当同一件事引。

边界 5:imrod 的 5 倍是定性说明,缺绝对耗时。 讲义 slide 76 写它的成本是 subdiv 的 5 倍,原因是依赖三角形;讲义 slide 79 又说它更高是因为三角形更多、要算的控制点也更多。两页要合起来看,并对照讲义 slide 79 的分项控制点 0.03 到 0.14 ms;作者没有给出 imrod 的绝对耗时或它对应的三角形数,讲义未给。

边界 6:讲义 slide 84 的 Next Steps 是作者自陈缺口,只能按自陈口径引。 清单包括 Visibility Buffer;WebGPU 的每个间接趟都要一趟带 barrier 的 compute 校验趟,渲染 10 个间接 compute 趟就多出 10 个校验趟;把同一条双三次 B-spline patch 上的点批处理,作者自称「没有 shader intrinsics」是自设限制;网格格式上 Usd 与 FBX 久经考验、Obj 有扩展、GLTF 既不支持四边形也不支持半锐折痕。

边界 7:讲义正文有两处笔误,照抄不代改。 讲义 slide 46 第五行写「Src Tri Index (1 1u32 pververt)」,讲义 slide 84 写「Batching point with the on the same bicubic b-spline patch」。两处都保留原样引用,正文不替作者「修正」,也不据此推断原意。

边界 8:两处表体积是不同口径,不能合并。 讲义 slide 39 的 1.6 MB 是 25 条 1D 线与两张 25×25 表的合计;讲义 slide 51 的 2.5/8.6/30.2 MB 是每个夹紧平行四边形组合预计算一整张表、随最大因子(64/128/256)变化的单档口径(讲义 slide 51)。讲义 slide 51 还写了「解析也实现过,但表更快」,为什么表更快,讲义未给。

本章可核对的结论有两条。结果一侧,Monkey 上固定 61,952 对自适应 30,526 个三角形、着色几乎不可区分(讲义 slide 74),多趟帧里单光照趟 0.36 对 0.50 ms、光照加 4 道阴影 0.81 对 2.51 ms、约 3 倍(讲义 slide 78)。口径一侧,讲义 slide 76 到 79 是 RTX 3070 的 compute-only、讲义 slide 80 到 82 的对手是只算位置的统一细分、讲义 slide 46 的约 704 MB 是设计估算,三处都不能与别处直接相减;两处笔误(讲义 slide 46、84)照抄保留。

13贡献块

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

三条贡献与站内互读

一场没有论文的讲座能留下什么,取决于它把哪些东西讲到了别人抄得走的程度。Adaptive Tessellation and Subdivision 留下来的三样都能搬到别的引擎里:一套替换 DX11 细分图案的具体做法(夹紧平行四边形),一份把计算式细分落成工程账的样本,以及一条把 Catmull-Clark 从头到尾做成解析求值的路径。本篇有一条贯穿始终的约束:整份讲义没有讲者备注,凡是需要口播才能成立的取舍,正文一律按「讲义未给」处理,因此这三样贡献都只报「讲义写了什么」,不替作者补动机。

贡献 1:一个可搬走的图案替换。 把 DX11 那条不收敛的分数偶数图案换成夹紧平行四边形:一维侧退回稳定间距、二维侧取横纵最大 gap 夹成三角形,配套 25 条 1D 线加两张 25×25 表、合计 1.6 MB 的实现口径(第 3 到第 6 章,讲义 slide 31/35/38/39)。凡读者想自己重做一套边独立、不 pop 的细分因子,这套做法可以直接照搬。

贡献 2:一份计算式细分的工程账。 内存按 16M verts/16M tris 上限分成 192/192/192/64 MB、合计约 704 MB 的设计估算;焊接的四个来处、用 Phong 近似按弧角选因子、溢出先丢因子,以及多趟帧下「建一次、每趟复用」(第 7、8 章,讲义 slide 46–51),最后在第 12 章兑现成约 3 倍的每趟读数(讲义 slide 78)。

贡献 3:Catmull-Clark 的全解析求值路径。 规则区 4×4 控制网格按可分双三次求值、无需递归;半锐折痕只换一次基;再用 feature-adaptive 收缩把不规则量压成每级线性增长,最后收成 1/4/16/12 四类区域,不用 quadtree(第 9 到第 11 章,讲义 slide 53/55/59/72)。

站内可以接着读的几篇:同一届 SIGGRAPH 2026 Advances(Part II)的篇目 29(Smolder:Real-Time Volumetric Effect Rendering in Glacier and 007 First Light)与本篇同为生产向讲座,前者讲体积效果怎么变成引擎里的通用系统,与本篇「把预算挪到看得见的地方」是同一种取舍;篇目 23(变率光追)、篇目 26(PSSR 升级)、篇目 27(ORCA)也在同一批里,可作生产视角的对照。想直接上手,讲义 slide 83 给了两处 canonical 链接:filmicworlds.com/blog/adaptive-catmull-clark-subdivision-with-compute-tessellation/ 与 filmicworlds.com/blog/compute-tessellation-with-clamped-parallelograms/,配套代码为 MIT。

14原文出处块

原文出处

原文出处与引用口径

出处:SIGGRAPH 2026 · Advances in Real-Time Rendering in Games(Part II)· 讲者 John Hable(Meta,台账口径)· 官方讲义《Adaptive Tessellation and Subdivision》,87 页,720×405 pt(16:9 横版),来源 PDF Adaptive Tessellation and Subdivision_7.pdf

材料:官方讲义 87 页,全篇无讲者备注,页内文字即幻灯片文字(无课程页摘要可引);本篇事实、读数与页码只取自讲义页内文字与分区台账;页码为 PDF 页序(从 0 起),引用写作「讲义 slide N」

许可(分两层):①版面与插图:全 87 页页脚逐页标注 © 2026 SIGGRAPH Advances in Real-Time Rendering in Games course. All Rights Reserved.,全文无 Creative Commons 声明,按分区非 CC 口径处理:21 件图逐件署名(源 slide 号 + 出处 + 版权 + 「未修改引用」),并在构建记录标注残留风险,不得写成 CC 或可自由转载。②示例代码:MIT 许可,只覆盖讲义 slide 7/83 所指「随讲义发布的 WebGPU demo 与示例代码」(讲义 slide 83 原话 All code is MIT licensed),不覆盖讲义版面与插图本身,正文凡讨论代码处单独标 MIT

引用口径:凡需口播才能确定处(动机、路线取舍、参数选择、测试场景、作者评价)一律写「讲义未给」,不推断补故事;讲义笔误照抄,不代改(见第 12 章边界 7)