实时渲染主要是有关使用计算机如何快速生成图像的过程,这是计算机图形学中最具有交互性的领域。交互性是指在屏幕上显示了一幅图像,观察者会据此作出某些行动或反应,并反馈给计算机以生成下一幅图像。当这种不断反应并渲染的循环过程执行的速度足够快时,观察就会沉浸在一种动态的变化过程中,而不是简单地看到多个单独的图像。
图像显示的速度可以使用frames per second(fps)或者Hertz(Hz)进行表示。如果一秒钟渲染一帧图像,就无法感觉到交互性,观察都就会痛苦的等等每一幅新图像的到来。当渲染速度达到大约6 fps,就会开始产生一点点交互的感觉。如果一个应用程序的显示速度达到15 fps就完全是实时的,观察都就可以重点关注作用和反作用。然而,实时的交互性有一个上限。在显示速度大于等于72 fps时,实时性就无法有效的察觉到。
虽然图像闪烁速度达到60 fps时显示效果可能就是可接受的,但是要减少交互响应时间,一个更高的速度是非常重要的。即使是延迟时间尽可能少于15毫秒也会降低并干扰交互性。如果以速度作为唯一标准,任何应用程序只要能够快速响应用户命令并在屏幕上绘制图像都是符合要求的。实时渲染通常是指三维渲染。
构成实时渲染的充分条件是交互性,以及某种意义上与三维空间的关联性,但是定义实时渲染还需要第三个组成部分:图形加速硬件(graphics acceleration hardware,显卡)。虽然专门用于三维图形加速的硬件已经在专业的计算机工作站中使用了很多年,但直到最近几年面向普通消费者的显卡才真正成为可能。人们普遍认为1996年推出的3Dfx Voodoo 1是第一个消费级显卡。近年来随着消费级显卡的快速发展,在家用计算机上添加一个三维图形加速硬件与添加一对扬声器一样简单。虽然对于实时渲染来说显卡不是绝对必要的,但是在大多数实时应用程序中却是不可或缺的。图1.1中显示了一个使用显卡执行实时渲染的示例生成的逼真的图像结果。
图1.1. A wonderful image from the Toy Shop demo [1246, 1247, 1249], generated at interactive rates. (Image courtesy of Natalya Tatarchuk, ATI Research, Inc.)
在过去的几年里,显卡的发展在交互式计算机图形学领域已经得到了爆发式的研究成果。在本书中我们将重点讲解提高渲染速度以及改进图像质量的方法,同时还会描述加速算法和图形APIs的特点及局限性。由于我们无法深入涵盖每一个图形学主题,因此本书旨在介绍概念和术语,使读者在一定程度上知道如何以及何时使用某种方法,并提供深入学习某个主题的最好的参考资料。我们希望本书中所提供的内容是值得你花时间和精力去学习的。
以下先简要概述本书所有章节的内容。
此外,本书的附录中还讲述了linear algebra(线性代数)和trigonometry(三角函数)。
首先,我们将讲解在本书中使用的数学记号。关于本节使用的大量记号的全面讲解请阅读附录A。
表格1.1中总结了我们将要使用的大部分数学记号。部分概念将会在本节进行描述。
Type | Notation | Examples |
---|---|---|
angle(角度) | lowercase Greek(小写希腊字母) | αi,ϕ,ρ,η,λ242,θ |
scalar(标量) | lowercase italic(小写斜体) | a,b,t,uk,v,wij |
vector or point (向量,点) | lowercase bold(小写粗体) | a,u,vs,h(ρ),hz |
matrix(矩阵) | capital bold (首字母粗体) | T(t),X,Rx(ρ) |
plane(平面) | π : a vector and a scalar(一个法向量及一个标量) | π:n⋅x+d=0π1:n1⋅x+d=0 |
triangle(三角形) | △ 3 points (3个点) | △v0v1v2,△cba |
line segment (线段) | two points(2个点) | uv,aibj |
geometric entity(几何实体) | capital italic(首字母斜体) | AOBB,T,BAABB |
表格1.1 Summary of the notation used in this book.
角度和标量来自 R (欧几里德空间),也就说这两个记号值为实数。向量和点记号以小写的粗体字母表示,并通过如下分量形式进行访问:
在homogenous coordinates(齐次坐标系,见附录A.4)中,使用 v=(vxvyvzvw)T 表示一个坐标,相应的 v=(vxvyvz0)T
表示一个向量, v=(vxvyvz1)T 表示一个坐标点。有时我们只使用三维向量和坐标点,但是要避免在向量和坐标点的类型表示之间变得模糊不清。对于矩阵运算,使用同样的记号表示向量和坐标点是非常有利的(见第4章的变换运算,以及附录A.4的齐次记号)。在某些算法中,使用数字索引如 v=(v0v1v2)T 的表示形式更方便,而不是使用 x,y,z 索引。这些表示向量和坐标点的方式同样适用于二维向量;在这种情况下,只是简单地忽略一个三维向量的最后一个分量。
接下来我们更详细地讲解矩阵。常用的矩阵大小分别是 2×2 , 3×3 和 4×4 。首先让我们回顾一下 3×3 矩阵 M 的访问方式,对该方式进行简单地扩展就可以用于访问任意大小的矩阵。矩阵 M 的(标量)元素使用 mij,0≤(i,j)≤2 表示,其中 i 表示行号 j 表示列号,如公式1.2所示:
平面的表示方式为 π:n⋅x+d=0 ,这种方式包含了平面的数学方程式,平面的法向量 n 和标量 d 。其中法向量描述了平面的朝向。对于更普遍的表面(比如曲面),法向量描述了表面上某个特定点的方向。而对于平面,同一个法向量可以用于表示平面上所有点的方向。通常使用数学记号 π 表示一个平面。在三维空间中,平面把空间分为positive half-space(正半空间)和nagetive half-space(负半空间)分别表示为 n⋅x+d>0 和 n⋅x+d<0 。其他所有的坐标点都位于平面上。
使用三个坐标点 v0,v1,v2 可以定义一个三形,并表示为 △v0v1v2 。
表格1.2中列出一些其他的数学运算符和对应的记号。其中,dot(点积),cross(叉积),determinant(行列式),length(长度)运算符在附录A进行了详细讲解。
Num | Operator | Description |
---|---|---|
1: | ⋅ | dot product(点积) |
2: | × | cross product(叉积) |
3: | vT | 向量 v 的转置 |
4: | ⊗ | 分段向量乘法 |
5: | ⊥ | 正交点积一元运算符 |
6: | |⋅| | 矩阵的行列式 |
7: | |⋅| | 标量的绝对值 |
8: | ∥⋅∥ | 参数的长度(模) |
9: | n! | 阶乘 |
10: | (nk) | 二项式系数 |
表格1.2 Notation for some mathematical operators.
transpose(转置)运算符用于把一个列向量转换成行向量,反之亦然。因为可以使用压缩的形式把列向量写到一个文本块中,如 v=(vxvyvz)T 。第4个操作符需要进一步讲解: u⊗v 表示向量 (uxvxuyvyvzvz)T ,即向量 u 的 i 分量和向量 v 的 i 分量相乘,并把乘积保存到一个新向量对应的 i 分量中。在本书中,该运算符专门用于颜色向量的乘法运算。第5个运算符引自Graphics Gems IV,是用于一个二维向量的一元运算符。对一个向量 v=(vxvy)T 执行这种运算符操作,可以得到向量 v 的正交向量,即 v⊥=(−vyvx)T 。记号 |a| 表示标量 a 的绝对值,相应的,矩阵 A 的行列式使用记号 |A| 表示。有时,矩阵 A 的行列式也可以表示为 |A|=|abc|= det (a,b,c) ,其中 a,b,c 为矩阵的列向量。第9个操作符是一个阶乘操作符,定义如下:
第10个操作符是一个二项式系数,定义为公式1.5所示:
进一步我们可以把平面 x=0 , y=0 和 z=0 称为coordinate planes(坐标平面)或axis-aligned planes(轴对齐平面)。同时,把轴 ex=(100)T , ey=(010)T 和 ez=(001)T 称为main axes(主轴)或main directions(主方向),通常对应为 x 轴, y 轴和 z 轴。此外,这三个轴通常被称为standard basis(标准基)。除非特别说明,我们将统一使用正交基(由一组相互垂直的单位向量组成;见附录 A.3.1)。
记号 [a,b] 表示一个同时包括a和b值的范围,并且该范围内的所有数值都介于a和b之间。如果要表示一个所有数介于a和b之间但不包括a和b本身的数值范围,则使用记号 (a,b) 。另外,还可以组合使用这些记号,例如 [a,b) 表示所有介于a和b之间的数值,但是该范围包含a而不包含b。
在本书中经常会用到C语言数学库函数 atan2(y,x) ,因此专门在这里讲解一下。该函数是对三角函数 arctan(x) 的扩展。这两个函数主要不同的地方是值域不同,分别为 0≤atan2(y,x)<2π 和 −π2<arctan(x)<π2 ,另外在 atan2(y,x) 函数中还有一个额外的参数。要避免该参数值为0,以免产生除以0的运算,即执行 x=y/x 时避免 x=0 。
Num | Function | Description |
---|---|---|
1: | atan2(y,x) | two-value arctangent |
2: | cos¯¯¯¯¯(θ) | clamped cosine |
3: | log(n) | natural logarithm of n ( n 的自然对数) |
表格1.3 Notation for some specialized mathematical functions.
第2个要介绍的函数是clamped-cosine(约束的余弦函数) cos¯¯¯¯¯(θ) ,该函数是为了使shading公式不至于太难阅读。如果正常的余弦函数值小于0,则clamped余弦函数就会返回0值。
第3个函数是 log(n) ,在本书中该记号表示自然对数 loge(n) ,而不是底为10的对数 log10(n) 。
此外,我们使用右手坐标系(见附录A.2),因为这是计算机图形学领域表示三维几何的标准坐标系。
颜色值使用一个包含3个元素分量的向量表示,比如 (red,green,blue) ,其中每一个元素分量都介于范围 [0,1] 之间。
大部分显卡使用的基本渲染图元(也称为绘制图元)分别是点,线和三角形。
除了点,线和三角形,唯一的例外是Pixel-Planes,可以直接绘制球体,NVIDIA NV1芯片可以直接绘制椭圆体。
在本书中,我们把几何体的集合称为模型或物体。把渲染环境中包含的全部模型的集体称为场景。此外,在场景中还可以包含材质描述,光照,以及观察规范。
物体有多种表示形式,比如一辆汽车,一幢大楼,甚至是一个线条。在实际工作过程中,通常使用一组绘制图元表示一个物体,但是凡事都有例外情况;一个物体还可能包含一种更高级的几何表示,比如贝塞尔曲线或曲面,细分表面等等。另外,物体也可以由其他的物体组成,例如,一个汽车模型的车门可以称为一个物体或都汽车的子集。
我们能够提供的最重要的参考资源是本书的配套网站:http://www.realtimerendering.com。该网站上包含了最新的信息,以及每一章相关的网站。随着时间的进展实时渲染领域也在不断发展。本书中我们会尽量重点讲解那些很可能不会过时的概念和技术。在网站上,我们会展示有关现今的软件开发人员的信息,并时刻保持最新的内容。