这篇鸽了,真的不好意思……(对不起评论区的小伙伴)
原定是上个月译完发的,没想到业务繁忙,没有什么精力与时间做这事了。
另外,第四章的第一节篇幅是真的长,而且有各种数学符号与公式,光输入就花了不少时间。
不过每天这么一段一段的往前推进,最终还是完成了!业余翻译,若有不周到之处,还请多多指教。
实时渲染(第四版)Real-Time Rendering (Fourth Edition)
第4章 变换 Chapter 4 Transforms
要是愤怒的航船(vectors)改变了方向
围绕着你沉睡的脑袋,和身体
那就永远不必去害怕
穷苦世界的抽象风暴之暴行
——罗伯特·佩·华伦
(注:此处航船可换为向量,与此章联系起来,一语双关。)
变换(transform)是一种操作,它接受点(points),向量(vectors)或颜色(colors)之类的实体(entities),并且以某种方式转换它们。对于计算机图形从业者来说,掌握变换是非常重要的。有了它们,你可以定位(position)、重塑(reshape)和移动(animate)物体、灯光和照相机。你还可以确保所有计算都在同一坐标系中进行,并且以不同的方式将对象投影到平面上。这里只是少数可以通过变换执行的操作,但是这已经充分说明了变换(transform)在实时图形或任何类型计算机图形中的重要性。
线性变换(linear transform)是保留向量加法和标量乘法的变换。具体来说:
举个例子, 是一个使向量每个元素乘以 5 的变换。为了证明这是线性的,需要满足两个条件(公式 4.1 与 公式 4.2)。第一个条件成立,因为任何两个向量乘以 5 然后相加就等于将向量相加然后再相乘。第二个标量乘法条件(公式 4.2)已经明显是满足的。此函数我们称为缩放变换(scaling transform),因为它可以更改对象的缩放比例(大小)。旋转变换(rotation transform)是另一个线性变换,它可使向量绕原点旋转。包括缩放和旋转变换,实际上三维向量的所有线性变换,都可以使用 3 × 3 矩阵表示。
然而,矩阵的大小通常不够大。三维向量 的函数,例如
是非线性的。在两个单独的向量上执行此函数将把
的每个值相加两次。这种将定值向量加到另一个向量上的操作称为平移(translation),它会将位置移动相应的值。平移是一种很有用的变换类型,接下来我们将组合各种变换,例如,将对象缩放到一半大小,然后将其移动到其他位置。此时我们会发现,将函数保持在简单形式是很难轻松地进行组合的。
我们可以使用仿射变换(affine transform)将线性变换(linear transforms)和平移(translations)结合起来,仿射变换通常存储为 4 × 4 矩阵。仿射变换是先执行线性变换然后执行平移变换。为了表示四维向量,我们使用齐次表示法(homogeneous notation),以相同的方式表示点和方向(使用粗体小写字母)。方向向量(direction vector)表示为 ,点(point)表示为
。在本章中,我们将广泛使用在 realtimerendering.com 上可下载的线性代数附录中解释的术语和运算。
所有平移(translation),旋转(rotation),缩放(scaling),反射(reflflection)和剪切矩阵(shearing matrices)都是仿射(affine)。仿射矩阵(affine matrix)的主要特征就是它保留了线的平行性,但不一定保留长度和角度。仿射变换(affine transform)也可以是各个仿射变换级联(concatenations)的任何序列。
本章将从最根本的基本仿射变换(basic affine transforms)开始。本部分可以看作是简单变换的“参考手册”。之后,我们会描述一些专用的矩阵,随后对四元数(quaternions)——一种强大的变换工具,进行讨论和描述。然后是顶点融合(blending)和变形(morphing),这是表达网格动画的两种简单但有效的方法。最后,描述了投影矩阵。这些变换中大多数,它们的符号,功能和特性都总结在 表 4.1 中,其中正交矩阵的逆矩阵为其转置矩阵。
变换(Transforms)是用于操纵几何体(geometry)的基本工具。大多数图形应用程序编程接口允许用户设置任意矩阵,有时库(library)可能与实现本章讨论的许多变换的矩阵运算一起使用。但是,仍然有必要了解函数调用背后的实际矩阵及其相互作用。知道调用函数后矩阵做了什么是一个开始,但是了解矩阵本身的属性将使你的理解更进一步。例如,这种理解可以使你辨别何时处理正交矩阵(正交是其转置),从而可以更快地进行矩阵求逆。这样的知识可以让你的代码更加高效。
4.1 基本变换 Basic Transforms
本节介绍最基本的变换,例如平移(translation),旋转(rotation),缩放(scaling),剪切(shearing),变换级联(transform concatenation),刚体变换(rigid-body transform),法线变换(normal transform)(然而并不是很正常 原文:which is not so normal 双关语笑话)和逆计算(computation of inverses)。对于有经验的读者,可以将其用作简单变换的参考手册,对于新手,则可以作为该主题的入门。本材料是本章其余部分和本书其他各章的必要背景。我们从最简单的变换——“平移”开始。
符号 Notation | 名称 Name | 特点 Characteristics |
---|---|---|
![]() |
平移矩阵
translation matrix
|
移动一个点。仿射。 |
![]() |
旋转矩阵
rotation matrix
|
绕 x 轴 旋转 y 轴 与 z 轴也使用此标记。 正交且仿射。 |
![]() |
旋转矩阵
rotation matrix
|
任意的旋转矩阵。 正交且仿射。 |
![]() |
缩放矩阵 scaling matrix |
根据 仿射。 |
![]() |
剪切矩阵 shear matrix |
相对于分量
|
![]() |
欧拉变换 Euler transform |
根据 head(yaw),pitch,roll 三个方向的欧拉角给出的方向矩阵。 正交&仿射。 |
![]() |
正交投影
orthographic projection
|
平行投影到某个平面或某个体积上。 仿射。 |
![]() |
透视投影
perspective projection
|
以透视图投影到平面或体积上。 |
斯勒普变换
slerp transform
(注:全称为球面线性插值变换 Spherical Linear Interpolation Transform) |
生成关于四元数 |
4.1.1 平移 Translation
从一个位置到另一个位置的变化由平移矩阵 表示。此矩阵通过向量 去平移实体。
由下面的 公式 4.3 给出:
图 4.1 显示了平移变换效果的示例。容易证明,将点 与
相乘会产生一个新的点
, 这显然是一个平移。请注意,向量
不受
乘法的影响,因为方向向量无法平移。相反,点和向量都受其余仿射变换(affine transforms)的影响。平移矩阵的逆是
,即向量
取反(negated)。
图 4.1 左边的方形进行了平移变换,平移矩阵为 ,方形向右移动了 5 个单位距离,向上移动了 2 个单位距离。
在这一点上,我们应该提到的是,有时在计算机图形学中看到的另一种有效的符号方案,它使用的矩阵的底标是平移向量。例如DirectX 就是使用这种形式。在该方案中,矩阵的顺序将颠倒,即矩阵应用的顺序将从左至右读取。由于向量是行向量,因此可以将这种表示形式的向量和矩阵称为行优先形式(row-major form)。在本书中,我们将使用列优先形式(column-major form)。无论使用哪种方式,这纯粹是一种符号上的差异。当矩阵存储在内存中时,十六进制的最后四个值为三个平移值加后跟的一个值。
4.1.2 旋转 Rotation
旋转变换将一个向量(位置或方向)绕经过原点的给定轴旋转指定的角度。像平移矩阵一样,它是一个刚体变换(rigid-body transform),换句话说,它保留了变换后的点之间的距离,并保留了惯用性(handedness)(即从不导致左右两侧互换)。在计算机图形学中,这两种类型的变换对于定位和定向对象显然很有用。方向矩阵(orientation matrix)是与摄像机视图(camera view)或对象相关联的旋转矩阵,它定义了其在空间中的方向,即其向上和向前的方向。
在二维中,旋转矩阵很容易得出。假设我们有一个向量 ,我们将其参数化为
。如果我们将向量旋转
弧度(逆时针),则将得到
。这可以重写为
在这里我们使用角度和关系来展开 和