曲线的实现原理依然是类似贝塞尔,即起点、终点、控制点定义的二次贝塞尔曲线。但是和传统栅格化不同的是,把这三个点连成三角形喂给 GPU,借助硬件自动插值的 UV 坐标,只需一行判断 uv.x² < uv.y ,每个像素就能精确判定自己在不在曲线内侧,将其转化成 GPU 擅长的并行算术,从而加速渲染。
曲线的实现原理依然是类似贝塞尔,即起点、终点、控制点定义的二次贝塞尔曲线。但是和传统栅格化不同的是,把这三个点连成三角形喂给 GPU,借助硬件自动插值的 UV 坐标,只需一行判断 uv.x² < uv.y ,每个像素就能精确判定自己在不在曲线内侧,将其转化成 GPU 擅长的并行算术,从而加速渲染。
本文主题是在 WebGPU 中快速渲染 TTF 字体。作者为博客动画渲染器在 WebGPU 上实现了基于 Loop-Blinn 的字体绘制:先对字形做耳切三角剖分,再在曲线处附加三点三角形,用片元着色器按 UV 做 y 与 x² 比较以 discard,从而在 GPU 上得到高分辨率、清晰的字形轮廓。文首动态图即用该管线渲染。
文章以 TrueType(.ttf)为讲解与实现对象,认为弄清它即可覆盖相关格式。字形由路径与二次曲线组成:每条曲线有起止点与控制点;路径顺时针表示填充、逆时针表示镂空,可用有向面积判断方向。作者跳过繁琐文件编码,在 CPU 侧解析后剖分网格,并在 WebGPU 上对曲线三角形做 Loop-Blinn 着色,面向高分辨率动态图形场景。
文中说明 OpenType(.otf)与 TrueType 结构几乎相同,因此解析与渲染思路可直接沿用 TTF 的字形—路径—二次曲线模型。作者未单独展开 OTF 细节,而是将其视为与 TTF 等价的输入来源之一。
Web Open Font Format(.woff / .woff2)在文中被描述为对 TrueType、OpenType 的压缩封装。理解底层 TTF 字形与曲线数据后,即可在解压后沿用同一套解析与 WebGPU 渲染流程,无需另建一套格式逻辑。
Loop 与 Blinn 提出的分辨率无关曲线渲染方法是本文核心。将二次样条的起点、终点、控制点围成三角形,利用 GPU 对 UV 的硬件插值,使曲线在参数空间变为 y=x²;片元只需比较 uv.x² 与 uv.y 即可判定内外并 discard。结合字形耳切网格与内外侧曲线三角形,即可在 WebGPU 上高效画出清晰字体,避免逐像素求最近点或昂贵解析解。
本文指出 TTF 字形中的每条曲线由起点、终点与控制点三点定义,这类曲线即二次样条。Loop 与 Blinn 的方法把这三点构成的三角形映射到 UV 空间,使样条在片元侧等价于 y=x²,从而用一次比较即可判定像素是否在曲线内侧,实现 GPU 上快速、分辨率无关的曲线填充。
文中用 lerp(在 t∈[0,1] 上对两端点做线性混合)来说明二次样条的构造:先对起点–控制点、控制点–终点各做一次插值,再对中间结果再插值一次,即可得到样条上的点。该方法便于在 CPU 上描出曲线形状,但因片元彼此独立,无法直接用于 GPU 填充。
文章将“用三次 lerp 组合求二次样条上一点”的过程称为 Casteljau 算法。它适合按参数 t 追踪曲线轮廓,却不能高效判断任意像素是否落在曲线内部;作者因此改用 Loop–Blinn 的三角映射与 UV 判定,以适配 GPU 的片元着色模型。
为渲染完整字符,作者先用耳切算法将字形路径三角化成平面网格,并调整顶点以免与后续曲线三角形重叠;这些三角形做平坦着色,再在拐角处叠加按二次样条规则着色的三角形,从而拼出带圆滑轮廓的字形。
文中指出 Loop-Blinn 相关工作曾由微软于 2005 年申请专利(US7564459B2),并于本文撰写当年 3 月到期。专利过期使作者可以在 WebGPU 字体渲染中公开采用该技术,无需再受该专利约束。
作者正在开发的 Web 动画库,用于在本博客中直接渲染动效;文中顶部 GIF、路径顺逆时针面积判断等示例均与该库相关,并给出 GitHub 源码链接,读者可借此复现文中的字体与动画技术。
可左右滑动查看