学习目标
- 能解释 High-Quality Antialiased Rasterization 如何用几何 coverage、sample positions 和 sample mask 表达部分覆盖,而不是把二值边缘简单 blur
- 能区分 analytic coverage、multisample antialiasing 与 resolve,并说明 subpixel precision、深度/模板测试和透明合成怎样影响结果
- 能调节 AntialiasedRasterizationLab 的 sample count、edge phase 与 resolve 空间,判断质量收益是否值得额外带宽和混合成本
先把“边缘变平滑”拆成覆盖与合成
GPU Gems 2 Chapter 21 的 High-Quality Antialiased Rasterization 讨论一个容易被一句“开 MSAA”掩盖的问题:一个屏幕像素到底有多少面积被三角形覆盖?如果光栅化阶段只输出一个 0/1 命中,斜线和细三角形就会在像素网格上跳变;如果保留部分覆盖的证据,后续才能用稳定的颜色、深度和透明规则合成边缘。
先打开实验,固定 edge phase,依次切换 2×、4×、8× sample。观察 covered sample 数和 coverage 的变化;再打开 gamma-space resolve,比较最终 output value。实验的重点不是追求一个永远更高的 sample count,而是看见三个独立变量:几何覆盖怎样被测量,覆盖怎样进入 mask,以及 mask 怎样参与最终颜色。
Antialiased rasterization 实验
调整 sample count、边缘相位和 resolve 空间,观察 coverage、带宽与边缘亮度如何互相牵制。
本章主题 High-Quality Antialiased Rasterization 的核心是把几何边界的部分覆盖变成可验证的数据通路:coverage 描述“覆盖多少”,sample mask 描述“哪些样本覆盖”,resolve 决定“怎样合成”。
↡在像素或样本区域内估计 primitive 覆盖面积或覆盖比例的边缘表示;它的值通常位于 0 和 1 之间。
↡在像素网格上计算几何边界与部分覆盖样本,并将结果用于减少离散边缘锯齿的光栅化过程。
1. coverage 是几何量,不是颜色滤镜
一个像素可以看成面积为 1 的小方形。若三角形在其中覆盖面积 A,最简单的面积近似是
coverage=1A=A,0≤coverage≤1.
真实实现未必显式求多边形与像素的精确交集:它可能使用边方程、子像素采样点、保守光栅化规则或预先计算的边缘距离。但无论选择哪种估计,都必须明确像素中心、sample position、边界包含规则和固定点精度。否则几何边缘在相邻像素间移动时,coverage 会发生不应有的跳变。
↡把几何坐标量化到像素内部的更细网格所提供的位置精度;精度不足会让边缘移动出现 stair-step 和闪烁。
analytic coverage 可以直接对边界与像素边界的交叠进行估计,优点是 coverage 随边缘位置连续,且不必为每个 sample 执行完整 fragment shading。它的难点是要处理顶点顺序、退化边、共享边、三角形顶点落在像素边界上的 tie-break,以及深度/模板测试的语义。对于很薄的几何,保守估计可能保护可见性但变得偏宽,激进估计可能锐利却漏掉部分覆盖;验收时应分别记录边缘位置误差和漏/多覆盖情况。
2. multisample antialiasing:样本位置与 mask
↡在一个像素内放置多个 sample position,分别执行覆盖、深度或模板判定,并在最终阶段组合样本结果的抗锯齿方法。
↡按位记录一个像素内哪些 sample position 通过几何与测试的覆盖判定;它是 coverage 的离散表示。
对于 N 个样本,最直接的离散 coverage 是
coverageMSAA=Npopcount(mask).
但这条公式只表达面积的粗略近似。样本位置的分布、旋转模式、固定样本模式,以及它们和几何边缘的相对相位,都会影响薄三角形、斜线和移动物体的稳定性。2×、4×、8× 不是只改变一个质量旋钮:它们同时改变 sample storage、depth/stencil 读写、resolve 工作量和带宽预算。
MSAA 常见的优化是让同一个 primitive 的多个 sample 共享 fragment shader 的颜色,只把 coverage、depth 或 stencil 保留到 sample 粒度。这样它不像全分辨率 supersampling 那样为每个样本都重算完整颜色,但也不能因此把所有样本当成一个二值像素。纹理 alpha test、discard、深度冲突和透明几何可能让 sample mask 与颜色记录产生不同生命周期,必须在 API 和 render target 规格中写清楚。
3. resolve:预乘、颜色空间与透明边缘
↡把多个 sample 的颜色、alpha 或 coverage 按权重组合成一个像素结果的阶段;正确顺序会影响边缘亮度和透明合成。
若每个 sample 有颜色 Ci 和覆盖权重 wi,一个简化的预乘 resolve 可以写成
Cout=i∑wiCipremultiplied,Aout=i∑wiAi.
工程上还要回答:颜色是否已预乘、权重是否来自 sample mask、透明物体是否需要按深度排序、resolve 是在 linear-light 还是 gamma-encoded 空间执行,以及最终编码何时发生。直接平均 sRGB 数值会让中间亮度偏暗或偏亮;先把非预乘颜色与 coverage 相乘的顺序错误,则会在边缘产生 halo。
4. 质量、成本与可验证的实现边界
抗锯齿质量至少要用三类输入验收:长斜线检验 coverage 的均匀性,细三角形和 alpha-tested 纹理检验 sample mask 的稳定性,透明叠加与高对比边检验 premultiplied linear resolve。每一类都应在静止、亚像素平移、旋转和不同深度排序下记录最大边缘误差,而不是只比较一张平均截图。
性能方面,应把成本拆为 sample storage、per-sample depth/stencil、fragment shading、resolve bandwidth 和透明排序。增大 sample count 可能改善几何边缘,却不一定改善 shader aliasing;解析 coverage 可能节省颜色采样,却会增加 edge math 和特殊几何路径。发布决策要把画质阈值、目标 GPU、render target 格式、分辨率和帧预算放在同一个 benchmark 中。
三步实验:从 coverage 到发布预算
每一步只改变一个变量,记录 primitive edge、sample pattern、mask、resolve 空间和 GPU 时间。若视觉结果和数值记录冲突,优先回到 sample-level reference,不要用后处理锐化掩盖 coverage 或颜色空间错误。
⚡分步1 / 3
第一步:建立 coverage reference
使用固定三角形边缘,在像素网格上移动 edge phase。比较二值命中、解析 coverage 和 sample-count 近似,记录共享边、半像素平移与退化三角形的结果。
本章小结
- antialiased rasterization 应在几何阶段表达部分覆盖;coverage 是连续面积语义,sample mask 是它在离散 sample positions 上的近似。
- subpixel precision、边界包含规则、winding 和 sample pattern 会直接影响移动边缘的稳定性;它们必须进入 reference 与回归测试。
- multisample antialiasing 可以共享 fragment color,却仍需保留 sample-level coverage、深度或模板信息;它不是全分辨率颜色 supersampling 的同义词。
- resolve 要明确 premultiplied alpha、coverage 权重和 linear-light 顺序,避免 gamma 平均与透明 halo。
- 质量预算应按 geometry edge、shader aliasing、透明合成和 GPU bandwidth 分解;sample count 只有在命中目标失败维度时才值得增加。
练习
问题 1|计算 sample coverage。 一个像素使用 4× MSAA,sample mask 为 1011。在只关心几何覆盖、每个 sample 权重相同的前提下,coverage 是多少?它和精确面积 coverage 有什么关系?
mask 有 3 个 bit 为 1,因此 coverageMSAA=3/4=0.75。它是由固定 sample
positions 得到的离散近似,不一定等于三角形与像素的精确交叠面积;改变 sample
pattern 或边缘相位,近似误差也会改变。
问题 2|定位透明 halo。 MSAA 边缘的 mask 正确,但透明物体边缘在深色背景上出现亮边。你会检查哪些 resolve 条件?
先确认每个 sample 的颜色是否已按 alpha/coverage 预乘,再检查 resolve 是否在
linear-light 空间执行、无覆盖 sample 的 RGB
是否被错误带入,以及透明物体的深度排序和背景合成顺序。用固定 sample buffer
对比 reference resolve,可以把 mask 问题与颜色合成问题分开。
问题 3|选择 4× 还是 analytic coverage。 目标设备的 8× MSAA 带宽超预算,但主要伪影是远处细三角形的几何闪烁;纹理本身已使用 mip。如何设计下一轮实验?
先用 2×、4× 与 analytic coverage 在相同 sample
pattern、分辨率和相机运动下比较边缘位置误差、mask 时序跳变和完整 GPU
时间。若解析路径能稳定表达几何面积,同时不破坏深度/透明语义,可以把它用于几何边缘,把有限
MSAA 留给仍需 sample-level 数据的材质;最终以目标 GPU 的带宽、resolve
与实现复杂度共同决定,而不是只看静态截图。
名词解释
本章出现的专业名词,用大白话再讲一遍。
- coverage
- antialiased rasterization
- subpixel precision
- multisample antialiasing
- sample mask
- resolve