GAMES101: Rasterization

本文系统解析光栅化技术,涵盖三角形光栅化、视口变换及屏幕显示原理(CRT/LCD/LED)。深入探讨反走样方法,结合信号处理与傅里叶变换分析走样成因,并详解MSAA、FXAA、TAA等抗锯齿技术,以及深度缓冲与超分辨率的应用。(Generated by DeepSeek r1)

光栅化

什么是光栅化

Raster 是德语中的屏幕(Screen),光栅化就是将变换后的标准正方形显示在屏幕上的过程。

屏幕

屏幕可以理解为二维的像素阵列。

像素 Pixel 是 Picture Element 的缩写,我们暂时认为像素是屏幕显示的最小单位,内部有一个由红蓝绿混合而成的、统一的颜色。

屏幕空间由许多的像素构成,像素的坐标由两个整数构成,从 $(0, 0)$ 开始到 $(\mathrm{width} - 1, \mathrm{height} - 1)$,坐标为 $(x, y)$ 的像素的中心为 $(x + 0.5, y + 0.5)$。

转换目标

暂时不考虑 Z 轴,我们需要将 $[-1, 1]^2$ 的平面变换到 $[0, \mathrm{width}] \times [0, \mathrm{height}]$,该矩阵称为视口变换(viewport)。
$$
M_{\mathrm{viewport}} = \begin{bmatrix}
\frac{\mathrm{width}}{2} & 0 & 0 & \frac{\mathrm{width}}{2} \
0 & \frac{\mathrm{height}}{2} & 0 & \frac{\mathrm{height}}{2} \
0 & 0 & 1 & 0 \
0 & 0 & 0 & 1
\end{bmatrix}
$$

光栅显示设备

阴极射线管 Cathode Ray Tube

通过调整 XY 两轴的偏转电压使得发射极电子打在荧幕的特定位置,以此成像。

  • 示波器 Oscilloscope
  • 早期电视

隔行扫描技术:在划分好的行中,每次加载图像只读取一半的行(奇数行或偶数行)。

液晶显示器 Liquid Crystal Display

显示存储在内存中的画面信息,应用在现代电子设备上。

  • 低分辨率,计算器等
  • 高分辨率,手机等

工作原理

每一个像素上,前后有两个偏振化方向垂直的光栅,中间充满液晶。自然光经过第一个光栅后,直接穿过第二个光栅的光强为 $0$。在激活状态下,液晶会改变光线的振动方向,使其穿过第二个光栅的光强增大。

屏幕截图 2025-02-04 165438

屏幕截图 2025-02-04 165446

发光二极管 Light Emitting Diode

二极管有预先设计好的颜色,只有发光与不发光两种状态。

使用 Bayer pattern 设计的屏幕,绿色元件的个数会更多(R : G : B = 1 : 2 : 1),这是因为人眼对绿色更为敏感,绿色的调整会使得画面更加自然

image-20250204172811424

三角形的光栅化

最重要的步骤:判断像素和三角形的内外关系

采样

对于离散的一系列点,求函数在这些点上的值。

定义
$$
\mathrm{inside}(t, x, y) = \begin{cases}
1 & (x, y) \in \triangle t\
0 & \mathrm{otherwise}
\end{cases}
$$
那么显示一个三角形可以转化为

for(int x = xmin; x < xmax; x++)
for(int y = ymin; y < ymax; y++)
    image[x][y] = inside(tri, x + 0.5, y + 0.5);

根据向量知识,$\mathrm{insdie}$ 可以转化为 $(x, y)$ 和 $t$ 的三条边做方向判断,如果同在左边/右边就为 $1$。

$[\mathrm{xmin}, \mathrm{xmax}] \times [\mathrm{ymin}, \mathrm{ymax}]$ 称为轴对齐的包围盒(Axis-Aligned Bounding Box),在包围盒外的部分不可能受到该三角形影响。

其他的加速方法:Increment Triangle Traversal,计算每行的最左端最右端,对于窄长的三角形较适用。

引发的严重问题:采样率过低(走样),产生锯齿

image-20250204172853630

反走样

信号处理理论

采样在图形学中无处不在:图片(按位置采样)、视频(按位置 + 按时间采样)

采样会产生瑕疵 Artifacts:锯齿、摩尔纹、视错觉(Wagon Wheel Illusion)

原因:信号变化的频率太快,导致采样的速度跟不上

模糊操作

在采样之前,先对原始图片做模糊处理(又称滤波)。

如果先采样再模糊,称为 blurred-aliasing。

image-20250206201628005

傅里叶变换

傅里叶变换是将任意函数 $f(x)$ 表示为频率不同的正弦函数的积分:
$$
F(\omega) = \int{-\infty}^{\infty} f(x) e^{- 2 \pi i \omega x} \mathrm{d}x
$$
同时也可以得到
$$
f(x) = \int
{-\infty}^{\infty} F(\omega) e^{2 \pi i \omega x} \mathrm{d} \omega
$$

这个过程中函数从实域变换到频域

对图像做傅里叶变换可以得到二维图像,中心表示低频率、外围表示高频率,亮度表示信息的多少。

出现轴线的原因:平铺图像导致在边界有剧烈的信息变化,对应高频信号。

image-20250206205527691

频率分析

在采样频率过低时,我们的采样结果很难反应实际的变化情况:

image1.png

这个时候就会产生走样。

滤波

滤波实质上是去除函数的特定频率。在傅里叶变换的图像上,可以按半径区分信号。

高通滤波

只保留高频信号的处理方法。

在图像的边界上,信号发生剧烈的变化,对应变换后的高频信号,所以在滤波之后只剩下了图像的内容边界。

image-20250206205816808

低通滤波

只保留低频信号的处理方法。

只剩下低频信息后,边界的内容(细节)被删除,画面看起来变模糊了。

image-20250206210135423

带通滤波

通过舍弃一部分高频和一部分低频信号,我们留下了一些不太明显的边界特征。

与加法卷积的联系

滤波等于卷积:通过与一个滤波数组做加法卷积,我们可以将原信号处理成另一个信号。

image-20250206232634784

直接给出结论:

对实域的卷积等价于对频域的乘积,对实域的乘积等价于对频域的卷积。

借助该结论我们可以使用两种方法完成滤波:

  1. 直接在实域上将图像和滤波器卷积
  2. 将图像和滤波器做傅里叶变换,函数直接相乘,再将结果做傅里叶逆变换(类似 FFT 的思路)

image-20250206233239806

采样

从卷积的角度理解,采样实际上和滤波一样,都可以做乘法得到。

不过采样的直观做法是将实域与只在离散的点上为 $1$、其余位置为 $0$ 的函数直接相乘,这样的函数称为冲激函数

反映在频率上,因为冲激函数在频域上仍然是冲激函数,所以频域上的卷积表现为原始信号频谱的重复。

这也解释了走样的原因:采样不够快会导致频谱的重复间隔太小,产生了混叠

image-20250206234831395

模糊操作的可行性

通过学习,我们已经知道了模糊操作等于高通滤波,丢弃的高频信号就相当于去掉了频域上函数的两端,这样采样之后就不会发生混叠了。

image-20250206235642375

实践中的反走样

Multisample Antialiasing (MSAA)

近似的反走样方法。

假设每一个像素被划分成了更小的区域(如 $4 \times 4$),对每个区域的中心分别求出是否被覆盖,然后计算每个像素的覆盖率。

之后进行一个简单的采样,每个像素的覆盖率就是采样的结果。需要注意的是,MSAA 完成的是模糊步骤。

通过不同的划分方案、点的复用等可以降低实际计算的点数。

Fast Aproximate Antialiasing (FXAA)

与采样无关的后期处理方法。

通过找到生成图像中的边界,将有锯齿的部分替换成没有锯齿的结果,来减少锯齿。

Temporal Antialiasing (TAA)

与时间相关的处理方法。

每一帧生成时计算像素内不同位置的被覆盖情况,并复用前几帧的位置信息来计算覆盖率。

可以理解成将 MSAA 一帧所需的计算量分布在时间上连续的几帧。(处理静态图像时效果较好)

超分辨率

和抗锯齿不太一样,是指将低分辨率的图转换为高分辨率。

可以理解成采样的分辨率低于图像的分辨率产生的走样。

DLSS:通过深度学习,补全丢失的细节。

深度缓冲

如何将多个物体显示在屏幕上,同时正确地体现遮挡关系?

Painter's Algorithm

一个简单的思路是,将物体按从远到近的顺序显示,像素由最后一个遮盖的投影决定。

在一些情况下,这个算法非常自然,油画也会使用这种思路来作画。

但是在处理相互遮挡的关系时,或者距离和顺序不好判定时,该算法可能发生错误。

需要 $O(N \log N)$ 时间对物体排序。

image-20250207234916752

Z-Buffer

既然对于每个物体不一定有渲染偏序,我们可以将其拆分,改为对每个像素储存一对信息,表示最浅的深度和对应的颜色。

这样在渲染时可以直接通过深度决定是否要覆盖当前颜色,同时生成了颜色图和深度图。

image-20250207235501080

for(triangle T : vecT)
for(auto [x, y, z, rgb] : T)
    if(isNear(z, zbuffer[x][y])) // z < zbuffer for left-hand coord, z > zbuffer for right-hand
        framebuffer[x][y] = rgb,
        zbuffer[x][y] = z;
    else continue; // do nothing

在认为单个三角形的处理时间为大致相近的常数,那么时间复杂度为 $O(N)$。

通过在 GPU 硬件中做并行计算,我们可以进一步加速渲染,因此这是一个非常重要的算法。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇