第一章
介绍
实时渲染与在计算机上快速制作图像有关。它是计算机图形学中交互性最强的领域。这种反应和渲染的循环以足够快的速度发生,以至于观众看不到单个图像,而是沉浸在一个动态过程中。
图像的显示速率以每秒帧数(FPS)或赫兹(Hz)为单位。在每秒一帧的情况下,几乎没有交互性;用户痛苦地意识到每个新图像的到来。在 6 FPS 左右时,交互性开始增强。视频游戏的目标是 30、60、72 或更高的 FPS;在这些速度下,用户将注意力集中在行动和反应上。
电影放映机以 24 FPS 的速度显示帧,但使用快门系统将每帧显示两到四次以避免闪烁。此刷新率与显示速率分开,以赫兹 (Hz) 表示。照亮框架三次的快门具有 72 Hz 的刷新率。LCD 显示器还将刷新率与显示率分开。
观看图像以 24 FPS 的速度出现在屏幕上可能是可以接受的,但更高的速率对于最小化响应时间很重要。短短 15 毫秒的时间延迟就会减慢并干扰交互。例如,用于虚拟现实的头戴式显示器通常需要 90 FPS 以最大程度地减少延迟。
实时渲染不仅仅是交互性。如果速度是唯一的标准,那么任何快速响应用户命令并在屏幕上绘制任何内容的应用程序都符合条件。实时渲染通常意味着生成三维图像。
交互性和与三维空间的某种联系感是实时渲染的充分条件,但第三个元素已成为其定义的一部分:图形加速硬件。许多人认为 1996 年推出的 3Dfx Voodoo 1 卡是消费级三维图形的真正开始。随着这个市场的快速发展,现在每台电脑、平板电脑和手机都配备了内置的图形处理器。图 1.1 和 1.2 显示了通过硬件加速实现实时渲染结果的一些优秀示例。
图形硬件的进步推动了交互式计算机图形学领域研究的爆炸式增长。我们将重点介绍提高速度和改善图像质量的方法,同时还描述加速算法和图形 API 的功能和限制。我们无法深入涵盖每个主题,因此我们的目标是介绍关键概念和术语,解释该领域最强大和最实用的算法,并提供指向更多信息的最佳位置的指针。我们希望我们为你提供理解该领域的工具的尝试被证明是值得你花时间和精力阅读我们的书。
符号和定义
首先,我们将解释本书中使用的数学符号。
数学符号
表 1.1总结了我们将使用的大部分数学符号。此处将详细描述其中的一些概念。
请注意,表中的规则有一些例外,主要是使用文献中非常成熟的符号对方程进行阴影处理,例如,L* 表示辐射度,E 表示辐照度, σ s σ_s σs 表示散射系数。
角度和标量取自 R,即它们是实数。向量和点用粗体小写字母表示,分量以
$v = \begin{pmatrix}v_x\ v_y\ v_z\end{pmatrix}
的形式访问,即采用列向量格式,这是计算机图形学界常用的格式。在文本的某些地方,我们使用 $(v_x,v_y,v_z) 而不是形式上更正确的 ( v x , v y , v z ) T (v_x ,v_y ,v_z)^T (vx,vy,vz)T,因为前者更易于阅读。
类型 | 表示法 | 例子 |
---|---|---|
角度 | 小写希腊字母 | α i , φ , ρ , η , γ 2 42 , θ α_i,φ,ρ,η,γ_242,θ αi,φ,ρ,η,γ242,θ |
标量 | 小写斜体 | a , b , t , u k , v , w i j a, b,t, u_k,v,w_{ij} a,b,t,uk,v,wij |
向量或点 | 小写粗体 | a , u , v s h ( ρ ) , h z a,u, v_s h(ρ), h_z a,u,vsh(ρ),hz |
矩阵 | 大写粗体 | T ( t ) , X , R x ( ρ ) T(t), X, R_x(ρ) T(t),X,Rx(ρ) |
平面 | π:一个向量和一个标量 | π:n · x + d = 0 π 1 : n 1 ⋅ x + d 1 = 0 π_1: n_1 · x + d_1 = 0 π1:n1⋅x+d1=0 |
三角形 | △ 3个点 | △ v 0 , v 1 , v 2 v_0,v_1,v_2 v0,v1,v2, △cba |
线段 | 两个点 | uv, a i , b j a_i,b_j ai,bj |
几何实体 | 大写斜体 | A O B B A_{OBB} AOBB,T,B_{AABB} |
表1.1.本书中使用的符号摘要
使用齐次表示法,坐标由四个值 v = ( v x , v y , v z , v w ) T v =(v_x, v_y, v_z, v_w)^T v=(vx,vy,vz,vw)T 表示,其中向量为 v = ( v x , v y , v z , 0 ) T v = (v_x, v_y, v_z, 0)^T v=(vx,vy,vz,0)T,点为 v = ( v x , v y , v z , 1 ) T v =(v_x, v_y, v_z, 1)^T v=(vx,vy,vz,1)T。有时我们只使用三元素向量和点,但我们尽量避免对使用哪种类型产生任何歧义。对于矩阵操作,向量与点具有相同的表示法是非常有利的。有关详细信息,请参阅有关转换的第 4 章。在某些算法中,使用数字索引而不是 x、y 和 z 是可以的,例如 v = ( v 0 , v 1 , v 2 ) T v = (v_0, v_1, v_2)^T v=(v0,v1,v2)T。向量和点的所有这些规则也适用于二元素向量;在这种情况下,我们只需跳过三元素向量的最后一个分量。
矩阵值得多解释一下。使用的常见大小为 2 ×2、3×3 和 4×4。我们将回顾访问 3 × 3 矩阵 M 的方式,将此过程扩展到其他大小很简单。Mare 的(标量)元素表示为 m i j m_{ij} mij, 0 ≤ ( i , j ) ≤ 2 0 \leq (i,j) \leq 2 0≤(i,j)≤2,其中 i 表示行,j 表示列,如等式 1.1所示:
M = ( m 00 m 01 m 02 m 10 m 11 m 12 m 20 m 21 m 22 ) M =\begin{pmatrix} m_{00} & m_{01} & m_{02} \\ m_{10} & m_{11} & m_{12} \\ m_{20} & m_{21} & m_{22} \\ \end{pmatrix} M= m00m10m20m01m11m21m02m12m22
(1.1)
对于 3 × 3 矩阵,公式 1.2 中显示了以下表示法,用于从矩阵 M 中分离向量: m , j m,_j m,j 表示第 j 列向量, m i m_i mi 表示第 i 行向量(列向量形式)。与向量和点一样,如果更方便的话,也可以使用 x、y、z 或有时使用 w 来索引列向量。
M =
(
m
,
0
m
,
1
m
,
2
)
(m,_0 m,_1 m,_2)
(m,0m,1m,2) =
(
m
x
m
y
m
z
)
(m_x m_y m_z)
(mxmymz) =
(
m
0
T
,
m
1
T
,
m
2
T
)
\begin{pmatrix}m_0^T, & m_1T, & m_2T \\ \end{pmatrix}
(m0T,m1T,m2T)
(1.2)
平面表示为 π :n · x + d = 0 并包含其数学公式、平面法线 n 和标量 d。法线是描述平面朝向方向的向量。更通俗地说(例如,对于曲面),法线描述了表面上特定点的这个方向。对于一个平面,相同的法线恰好适用于它的所有点。π 是平面的常用数学符号。据说平面 π 将空间划分为正半空间,其中 n·x + d > 0,为负半空间,其中 n·x + d < 0。据说所有其他点都在平面上。
三角形可以用 v 0 、 v 1 v_0、v_1 v0、v1 和 v 2 v_2 v2 三个点定义,用 △ v 0 v 1 v 2 v_0v_1v_2 v0v1v2 表示。
表 1.2 提供了一些额外的数学运算符及其表示法。转置运算符将列向量转换为行向量,反之亦然。因此,列向量可以以压缩形式编写在文本块中,如 v = ( v x v y v z ) T v = (v_x v_y v_z)^T v=(vxvyvz)T。Graphics Gems IV 中引入的运算符 4 是二维向量上的一元运算符。让这个算子处理向量 $v = (v_x v_y)^T 会得到一个垂直于 v 的向量,即 v ⊥ = ( − v y v x ) T v⊥ = (−v_y v_x)^T v⊥=(−vyvx)T。
算子 | 描述 | |
---|---|---|
1: | · | 点积 |
2: | × | 矢积 |
3: | v T v^T vT | 向量v的转置 |
4: | ⊥ ^⊥ ⊥ | 一元点积算子 |
5: | | · | | 行列式 |
6: | | · | | 标量的绝对值 |
7: | || · || | 参数长度 |
8: | x + x^+ x+ | 将x的最小值限制在0 |
9: | x + ˘ x^{\breve +} x+˘ | 将x限制在0到1之间 |
10: | n! | 阶乘 |
11: | ( n k ) \begin{pmatrix}n \ k \end{pmatrix} (n k) | 二项式系数 |
表1.2 一些数学算子的符号
我们用 |a| 表示标量 a 的绝对值,而 |A| 则表示矩阵 A 的行列式。有时,我们也使用 |A| = |a b c| = det(a,b,c),其中 a、b 和 c 是矩阵 A 的列向量。
运算符 8 和 9 是限制操作符,常用于着色计算中。操作符8会将输入值的负数部分限制到0:
x + = { x , if x > 0 0 , otherwise x^+ = \begin{cases}x,&\text{if x > 0} \\ 0,&\text{otherwise} \end{cases} x+={x,0,if x > 0otherwise
(1.3)
操作符9则会将输入值限制在0到1之间:
x + ˘ = { 1 , if x > 0 x , if 0 < x < 1 0 , otherwise x^{\breve +} = \begin{cases}1,&\text{if x > 0} \\ x,&\text{if 0 < x < 1} \\ 0,&\text{otherwise} \end{cases} x+˘=⎩ ⎨ ⎧1,x,0,if x > 0if 0 < x < 1otherwise
(1.4)
操作符10是阶乘(factorial)操作符,其定义如下所示,请注意0 != 1:
n ! = n ( n − 1 ) ( n − 2 ) ⋅ ⋅ ⋅ 3 ⋅ 2 ⋅ 1 n! = n(n-1)(n-2)···3·2·1 n!=n(n−1)(n−2)⋅⋅⋅3⋅2⋅1
(1.5)
操作符11是组合数,也叫做二项式系数,其定义方程1.6:
( n k ) = n ! k ! ( n − k ) ! \begin{pmatrix}n \\ k \end{pmatrix} = \frac{n!}{k!(n - k)!} (nk)=k!(n−k)!n!
(1.6)
除此之外,我们一般将 x = 0 x = 0 x=0, y = 0 y = 0 y=0, z = 0 z = 0 z=0这三个平面叫做坐标平面或者轴对齐平面。将 e x = ( 1 0 0 ) T e_x = \begin{pmatrix}1 & 0 & 0 \end{pmatrix}^T ex=(100)T, e y = ( 0 1 0 ) T e_y = \begin{pmatrix} 0 & 1 & 0 \end{pmatrix}^T ey=(010)T, e z = ( 0 0 1 ) T e_z = \begin{pmatrix} 0 & 0 & 1 \end{pmatrix}^T ez=(001)T 叫做主轴或者主方向;或者分别叫做 x x x 轴, y y y 轴和 z z z 轴。这组向量通常也会被称为标准基。除了特殊说明之外,我们将会使用标准正交基(即由相互垂直的单位向量所组成的基底)。
我们将同时包含 a , b a,b a,b,以及两者之间所有数字的范围区间记为 [ a , b ] [a,b] [a,b]。如果我们只想要 a , b a,b a,b 之间的数字,而不想要 a , b a,b a,b 本身的话,那么我们可以将其记为 ( a , b ) (a, b) (a,b)。我们也可以将开闭区间进行组合使用,例如: [ a , b ) [a,b) [a,b) 代表包括 a a a 在内,但是不包括 b b b 在内的, a , b a,b a,b 之间的所有数字。
函数 | 描述 | |
---|---|---|
1 | atan(y,x) | 二元反正切函数 |
2 | log(n) | n的自然对数 |
表1.3 一些特殊的数学函数的表示方法
a t a n 2 ( y , x ) atan2(y, x) atan2(y,x) 是一个C语言中的数学函数,它在本文中经常使用,因此值得我们去关注一下。它是数学函数 arctan ( x ) \arctan(x) arctan(x) 的一个拓展,它俩的主要区别在于 − π 2 < arctan ( x ) < π 2 -\frac{\pi}{2} < \arctan(x) < \frac{\pi}{2} −2π<arctan(x)<2π,而 − π ≤ a t a n 2 ( y , x ) ≤ π -\pi \leq \mathsf{atan2}(y, x) \leq \pi −π≤atan2(y,x)≤π;并且后者包含一个额外的参数输入。这个函数的常见应用是用来计算 arctan ( y / x ) \arctan(y/x) arctan(y/x),当 x = 0 x = 0 x=0 时,分母就为0了。而拥有两个参数的 a t a n 2 ( y , x ) \mathsf{atan2}(y, x) atan2(y,x) 则可以避免这一点。
在本书中, log ( n ) \log(n) log(n) 始终代表了自然对数,即 log e ( n ) \log_e(n) loge(n),而不是以10为底的对数 log 10 ( n ) \log_{10}(n) log10(n)。
颜色使用一个三维向量来进行表示,例如 ( r e d , g r e e n , b l u e ) (red,green,blue) (red,green,blue),其中每个分量的范围都是 [ 0 , 1 ] [0,1] [0,1]。
几何定义
几乎所有图形硬件使用的渲染图元都是点、线和三角形。
我们所知道的唯二例外就是Pixel-Planes,它可以绘制球体;以及NVIDIA NV1芯片,它可以绘制椭球体。
在本书中,我们会将一个几何实体的集合称作为模型或者物体。场景是指环境中所有待渲染模型的集合,同时场景中还包含了材质信息,灯光信息,以及观察信息等。
这里的物体可以是一辆车,一栋建筑甚至是一条直线。在实际中,一个物体中包含了一系列的渲染图元,但是也有例外,物体也可以是其他更加高级的几何表现形式,例如Bezier 曲线、Bezier 曲面或者是细分曲面。同时,一个物体也可以同时包含其他的物体,例如一辆车包含了四个车门以及四个轮子等。
着色
sp; 这里的物体可以是一辆车,一栋建筑甚至是一条直线。在实际中,一个物体中包含了一系列的渲染图元,但是也有例外,物体也可以是其他更加高级的几何表现形式,例如Bezier 曲线、Bezier 曲面或者是细分曲面。同时,一个物体也可以同时包含其他的物体,例如一辆车包含了四个车门以及四个轮子等。
着色
按照约定俗成的计算机图形学惯例,本书中的“着色”和“着色器”以及相关的派生词,常常被用来指向两个相关但是完全不同的概念:一个是计算机生成的视觉外观,例如:“着色模型”,“着色方程”,“卡通渲染”等;另一个是渲染系统中的可编程组件,例如:“顶点着色器”,“着色器语言”等。在这两种不同的情况下,你可以通过上下文来推断出它具体指向的含义。