屏幕与像素

光栅显示器把图像存为规则像素阵列。课程采用屏幕左下角为原点、像素坐标为整数索引的约定;像素 (x,y)(x,y) 的中心位于

(x+0.5,y+0.5).(x+0.5, y+0.5).

视口变换已经把规范设备坐标映射到屏幕范围,光栅化 Rasterization 要继续回答:每个图元覆盖哪些像素,以及这些像素应携带什么属性。帧缓冲为每个像素保存颜色,还可以配套保存深度、模板等辅助信息。

三角形

多边形网格通常最终分解为三角形。三角形有几项适合硬件处理的性质:

  • 三个不共线顶点唯一确定一个平面,图元一定是平的。
  • 任意多边形都可以三角化。
  • 内外判断简单,重心坐标能稳定插值顶点属性。
  • 三角形的边和顶点数量固定,便于并行流水处理。

在图元没有跨越投影奇异面、也尚未被视锥裁剪时,三角形经过模型、视图和投影后,屏幕上的边仍是直线,形状仍是三角形。视锥裁剪可能把它变成三角形、四边形或完全丢弃,四边形还要重新三角化。对最终图元的像素中心采样指示函数,就能得到最基本的覆盖结果。

二维采样

采样 Sampling 是在离散位置读取连续函数。定义三角形的指示函数

inside(T,x,y)={1,(x,y) 在三角形内,0,其他.\operatorname{inside}(T,x,y)= \begin{cases} 1,&(x,y)\text{ 在三角形内},\\ 0,&\text{其他}. \end{cases}

逐个像素在中心位置求值,相当于对一个连续二维函数采样:

pixel[x,y]=inside(T,x+0.5,y+0.5).\operatorname{pixel}[x,y] =\operatorname{inside}(T,x+0.5,y+0.5).

把三角形光栅化理解为二维采样

这个方法产生的是二值覆盖,每个像素只有完全亮或完全暗两种状态。边界的真实面积信息被丢弃,因此斜边会出现阶梯状锯齿,后续需要抗锯齿处理。

内部测试

设三角形顶点按逆时针排列为 A,B,CA,B,C,测试点为 PP。依次检查

(BA)×(PA),(CB)×(PB),(AC)×(PC).(B-A)\times(P-A), \quad (C-B)\times(P-B), \quad (A-C)\times(P-C).

对逆时针三角形,若三个二维叉积的 zz 分量都大于等于零,PP 位于三条有向边的左侧或边界上,也就位于闭三角形内。若顶点顺序为顺时针,符号会整体反转。

等号对应边界点。点恰好落在公共边上时,两个相邻三角形都可能接受或都可能拒绝该样本。实际光栅器会采用一致的边界规则,例如 top-left rule,让共享边只归属于其中一个三角形,避免裂缝和重复覆盖。

遍历范围

没有必要测试整张屏幕。先计算三个顶点在 x,yx,y 方向的最小值和最大值,得到轴对齐包围盒,只遍历其中的像素。对狭长或特殊方向的三角形,还可以逐扫描线求左右交点,进一步减少无效测试。

边函数在相邻像素上的变化量固定,因此光栅器可以增量更新三个边函数,而不必在每个像素重新做完整叉积。这种规则计算非常适合 GPU 上的大规模并行执行。

背面剔除

封闭网格中,朝向远离相机的三角形通常不可见。背面剔除 Back-Face Culling 可利用投影后的屏幕空间有向面积

A2=(BA)×(CA)A_2=(B-A)\times(C-A)

的符号判断正反面,并在光栅化前剔除背面。剔除能节省大量片元工作,但不适用于双面材质、开口薄片或需要从内部观察的物体。负尺度变换会翻转顶点绕序,也要同步调整正面约定。

显示设备

早期阴极射线管让电子束按扫描线扫过荧光屏,模拟电视通过连续信号调制亮度,数字系统则从帧缓冲读出像素。现代 LCD 使用背光和液晶层控制透光率,OLED 或 LED 像素可以主动发光;电子墨水通过带电颜料颗粒维持显示,静态功耗很低。

“像素是均匀方块”只是算法模型。真实显示器由具有空间结构的 RGB 子像素组成,采样位置、发光面积和重建方式都会影响最终边缘。高分辨率屏幕能减轻离散感,却不能从原理上消除采样误差。

采样误差

采样把连续函数只保留在一组离散位置上的值。光栅化在像素中心采样空间信号,相机传感器在规则感光单元上采样图像,视频则按帧率采样时间信号。只要采样频率不足,原信号中不同的变化就可能产生相同样本,形成 混叠 Aliasing,重建时无法区分。

常见伪影都来自这种信息混叠:

  • 锯齿:斜边或高频纹理在像素网格上呈阶梯状。
  • 摩尔纹:两组细密重复结构相互干涉,产生原图中不存在的低频条纹。
  • 车轮倒转:时间采样过稀,相邻帧中的辐条被匹配到错误位置,形成反向运动错觉。

两组近似周期的细密纹理采样后折叠成粗大的摩尔纹

单纯提高分辨率可以推迟问题出现,但只要信号中仍有更高频率,就不能彻底避免混叠。

频域

傅里叶变换 Fourier Transform 把空间域或时间域信号分解为不同频率的正弦与余弦:

F(ω)=f(x)eiωxdx,f(x)=12πF(ω)eiωxdω.F(\omega)=\int_{-\infty}^{\infty}f(x)e^{-i\omega x}\,dx, \qquad f(x)=\frac{1}{2\pi}\int_{-\infty}^{\infty}F(\omega)e^{i\omega x}\,d\omega.

缓慢变化的亮度属于低频,边缘、细纹理和噪声含有较多高频。把二维 Fourier 频谱的零频移到图像中心后,可以按以下规律阅读:

  • 中心亮点是直流分量,反映整幅图的平均亮度;
  • 越靠近中心,表示变化越缓慢;越靠外,表示变化越快;
  • 某方向上的纹理变化会把能量推向对应频率方向。例如竖直条纹主要沿 xx 变化,频谱能量沿水平轴展开;
  • 尖锐边缘同时含有很多频率,所以频谱会出现跨越较宽范围的亮线。

原图的平滑区域集中在频谱中心,边缘与纹理把能量扩展到外围

在频域中只保留中心附近,相当于 低通滤波 Low-Pass Filtering,图像会变模糊;只保留外围高频,相当于 高通滤波 High-Pass Filtering,平缓区域消失,主要留下边缘;保留一圈中间频率就是 带通滤波 Band-Pass Filtering,会突出某一尺度的轮廓与纹理。频域遮罩的形状决定保留哪些方向和尺度。

低通保留频谱中心,高通保留外围,带通突出中间频率对应的纹理尺度

设采样间隔为 TT,规则采样位置可以写成周期冲激列

sT(x)=k=δ(xkT).s_T(x) = \sum_{k=-\infty}^{\infty} \delta(x-kT).

它只在 x=kTx=kT 处保留信号,因此采样后的广义函数是

fs(x)=f(x)sT(x)=kf(kT)δ(xkT).f_s(x)=f(x)s_T(x) = \sum_k f(kT)\delta(x-kT).

冲激列的傅里叶变换仍是冲激列。令角采样频率

ωs=2πT,\omega_s=\frac{2\pi}{T},

ST(ω)=2πTk=δ(ωkωs).S_T(\omega) = \frac{2\pi}{T} \sum_{k=-\infty}^{\infty} \delta(\omega-k\omega_s).

空间域相乘对应频域卷积,所以

Fs(ω)=12π[FST](ω)=1Tk=F(ωkωs).\begin{aligned} F_s(\omega) &= \frac1{2\pi} [F*S_T](\omega)\\ &= \frac1T \sum_{k=-\infty}^{\infty} F(\omega-k\omega_s). \end{aligned}

这条式子给出了采样的核心结果:原频谱以 ωs\omega_s 为间隔被周期复制。采样值里没有保存“某段频率来自第几个副本”的标签,一旦副本重叠,就无法唯一拆回原频谱。

奈奎斯特率

若原信号带限到 ωωmax|\omega|\le\omega_{\max},每个频谱副本宽度为 2ωmax2\omega_{\max}。相邻副本不重叠需要

ωs>2ωmax.\omega_s>2\omega_{\max}.

用普通频率 f=ω/(2π)f=\omega/(2\pi) 表示,就是

fs>2fmax.f_s>2f_{\max}.

这就是 奈奎斯特采样条件 Nyquist Sampling Criterion。它也能从离散样本直接看出:频率 fff+kfsf+kf_s 的复指数在第 nn 个样本上分别为

ei2πfnTei2π(f+kfs)nT=ei2πfnTei2πkn,e^{i2\pi fnT} \quad\text{和}\quad e^{i2\pi(f+kf_s)nT} = e^{i2\pi fnT}e^{i2\pi kn},

ei2πkn=1e^{i2\pi kn}=1。两种连续频率给出完全相同的样本,重建系统只能把高频错误解释成较低频率。

真实图像的锐利边缘不严格带限,理论上包含无限高频,因此有限采样率无法满足全部频率。实际系统要在采样前主动限制频带,把无法表达的细节转化为正确的区域平均。

卷积

滤波常写成信号与卷积核的 卷积 Convolution

(fg)(x)=f(τ)g(xτ)dτ.(f*g)(x)=\int_{-\infty}^{\infty}f(\tau)g(x-\tau)\,d\tau.

离散图像中,卷积核在每个位置滑动,每个输出像素是当前邻域与核的逐项乘积之和。卷积定理说明

F{fg}=F{f}F{g},\mathcal F\{f*g\}=\mathcal F\{f\}\,\mathcal F\{g\},

空间域卷积对应频域逐点相乘,滤波器频谱决定保留的频率

所以空间域的卷积等价于频域逐频率相乘。核频谱接近零的频率会被删除,接近一的频率基本保留;空间域看似简单的邻域平均,在频域中就是选择性衰减频率。

最简单的低通滤波器是 盒式滤波 Box Filtering。宽度为 ww 的一维归一化 box kernel 为

hw(x)={1w,xw/2,0,其他.h_w(x) = \begin{cases} \frac1w,&|x|\le w/2,\\ 0,&\text{其他}. \end{cases}

它的 Fourier 变换为

Hw(ω)=1ww/2w/2eiωxdx=sin(ωw/2)ωw/2.\begin{aligned} H_w(\omega) &= \frac1w \int_{-w/2}^{w/2} e^{-i\omega x}\,\mathrm dx\\ &= \frac{ \sin(\omega w/2) }{ \omega w/2 }. \end{aligned}

ω=0\omega=0 时右式形式上为 0/00/0,按极限定义 Hw(0)=1H_w(0)=1,这也符合归一化核保持常量信号的性质。空间域的 box 变成频域的 sinc。ww 增大时,sinc 主瓣变窄,保留的低频范围更小,图像更模糊;ww 减小时主瓣变宽,能通过更多高频。sinc 旁瓣说明 box filter 的阻带抑制并不理想,部分高频仍会泄漏,负旁瓣还会翻转相应频率分量的相位。单个非负 box 核对阶跃做移动平均不会产生过冲;常见 ringing 更直接来自频域硬截断所对应的振荡空间核。

空间 box 核越宽,频域 sinc 主瓣越窄;旁瓣仍会通过部分频率

对一个像素覆盖区域求平均,可以近似该像素对连续三角形的面积积分。

设像素区域为 PP,定义归一化盒式核

hP(x)=1P1P(x).h_P(\mathbf x) = \frac1{|P|} \mathbf 1_P(\mathbf x).

在像素中心 x0\mathbf x_0 查询卷积结果:

(fhP)(x0)=1PPf(x0τ)dτ.(f*h_P)(\mathbf x_0) = \frac1{|P|} \int_P f(\mathbf x_0-\boldsymbol\tau) \mathrm d\boldsymbol\tau.

它正是像素 footprint 内的平均。若 ff 是纯色三角形的指示函数,结果就是三角形与像素交叠面积占像素面积的比例。这样,频域低通和空间域覆盖率是同一个操作的两种解释。

预滤波

抗锯齿 Antialiasing 的核心是 预滤波 Prefiltering:先低通滤波,再稀疏采样。滤波把超过像素网格可表达范围的高频压低,使频谱复制后不再严重重叠。

抗锯齿先限制频带,再执行采样

若先在像素中心采样,再对已经出现锯齿的图像做模糊,错误频率已与真实低频混在一起。后处理只能让锯齿变软,无法恢复正确的像素覆盖。

原因可以从频谱复制式直接看出:采样之后,相邻副本已经在同一频率位置相加。后续低通只能保留或削弱这个和,无法判断其中哪部分属于原信号、哪部分来自折叠的高频。

抗锯齿必须在采样前限制频带;采样后再模糊,只能掩盖已经发生的混叠。

覆盖率

理想的 覆盖率 Coverage 可写成三角形指示函数在像素区域 PP 上的平均:

CP=1PPinside(T,x,y)dxdy.C_P=\frac{1}{|P|}\int_P\operatorname{inside}(T,x,y)\,dx\,dy.

对纯色三角形,CPC_P 就是像素被三角形覆盖的面积比例。边界像素得到 0011 之间的值,于是显示器发出的平均能量更接近连续图形,而不再只有全黑与全亮。

精确计算每个像素与三角形的交叠面积代价较高,通常通过多次采样估计。

超采样

超采样 Supersampling 在一个像素内布置 NN 个子样本,先分别判断覆盖,再求平均:

CP1Ni=1Ninside(T,xi,yi).C_P\approx\frac{1}{N}\sum_{i=1}^{N} \operatorname{inside}(T,x_i,y_i).

单点采样只看像素中心,超采样用多个子样本估计像素覆盖率

这相当于用有限求积点近似像素区域上的积分。规则 2×22\times24×44\times4 网格易于实现,但仍可能与规则纹理形成相关误差;分层抖动把像素划成子区域后各取一个随机点,既保持覆盖均匀,也减少规则对齐。样本越多,面积估计越稳定,计算、带宽和存储开销也越高。

SSAA Supersample Anti-Aliasing 对每个子样本执行完整着色。MSAA Multisample Anti-Aliasing 主要增加几何覆盖与深度样本,尽量共享像素级着色结果,因此更适合处理几何边缘,但不能自动解决着色器或纹理内部的高频混叠。FXAA 等后处理方法根据最终图像寻找高对比边缘,成本较低但可能模糊细节;TAA 复用多帧的抖动样本,依赖准确的运动信息;超分辨率方法利用重建模型从低分辨率样本估计高分辨率结果。它们处理的误差来源和代价并不相同。

多重采样还要区分每样本存储与最终的解析 resolve。每个子样本可以分别保存颜色 CiC_i、深度 did_i 和覆盖或 alpha aia_i;深度测试在样本级完成,之后再统一解析颜色,例如不透明样本可写成

Cresolve=1Ni=1NCi,Aresolve=1Ni=1Nai.C_{\mathrm{resolve}} =\frac{1}{N}\sum_{i=1}^{N}C_i, \qquad A_{\mathrm{resolve}} =\frac{1}{N}\sum_{i=1}^{N}a_i.

透明表面应先在每个样本上按正确的前后顺序完成 透明混合 Alpha Blending,再 resolve。视觉上,源颜色按 alpha 与目标颜色加权,覆盖边界因此得到连续的半透明过渡;把覆盖率直接乘到已经解析的 framebuffer,或把多个样本先平均后再混合,会丢失样本级遮挡信息。source-over 混合也不满足交换律,顺序错误会重复衰减背景,边缘容易出现黑边。对单个不透明前景覆盖不透明背景的特例,把 coverage 当作 alpha 可以近似成立,但不能推广到多层透明或不同深度的样本。

Straight alpha 把 RGB 与 alpha 分开存储。源像素 (Cs,as)(C_s,a_s) 覆盖目标 (Cd,ad)(C_d,a_d) 时,source-over 为

Co=asCs+(1as)adCdao,ao=as+(1as)ad,ao>0.C_o=\frac{a_sC_s+(1-a_s)a_dC_d}{a_o}, \qquad a_o=a_s+(1-a_s)a_d, \quad a_o>0.

Premultiplied alpha 存储 C~=aC\widetilde C=aC,对应公式为

C~o=C~s+(1as)C~d,ao=as+(1as)ad.\widetilde C_o =\widetilde C_s+(1-a_s)\widetilde C_d, \qquad a_o=a_s+(1-a_s)a_d.

两种表示必须使用匹配的混合因子。Straight alpha 在透明边缘插值时容易把无效 RGB 带入结果;premultiplied alpha 要求 a=0a=0C~=0\widetilde C=0。若未预乘通道已归一化到 0C10\le C\le1,还可推出 0C~a0\le\widetilde C\le a;HDR 线性颜色可能大于 1,此时没有后一上界。预乘表示更适合过滤和逐样本 resolve,但透明层的混合顺序仍会影响结果。