# 模型、世界、观察、裁剪空间的坐标转换
在 3D 图形编程中,模型、世界、观察和裁剪空间的坐标转换,是将 3D 对象从其原始位置转换到最终可以在屏幕上渲染的 2D 图像的关键步骤。
这些转换通常在图形渲染管线的顶点着色器阶段进行。
下面是每个空间的简要说明和它们之间的转换:
这些转换涉及到矩阵乘法,其中模型矩阵、视图矩阵和投影矩阵是最重要的三个矩阵,它们共同定义了场景的变换。
开发者可以通过修改这些矩阵来改变场景的视觉效果,例如实现相机移动、对象旋转和视角变换等。
# 模型空间
是指一个物体在其自身坐标系中的表示。
每个三维模型都有一个独立的坐标系,这个坐标系定义了模型在其自身空间中的位置、方向和大小。
假设有一个立方体模型,其顶点坐标在模型空间中可能是 (-1, -1, -1) 到 (1, 1, 1),这些坐标是相对于立方体自身的中心点(原点)的。
当你将这个立方体放置到场景中时,你需要将其从模型空间转换到世界空间,这通常涉及平移、旋转和缩放操作。
# 世界空间
是指整个场景或世界的全局坐标系。
世界空间是一个全局坐标系,所有物体的位置、方向和大小都是相对于一个统一的参考点(通常是场景的原点)来定义的。
世界空间用于管理和组织整个场景中的所有物体。通过在世界空间中定义物体的位置和方向,可以方便地进行场景的渲染、碰撞检测、物理模拟等操作。
假设有两个立方体模型,每个立方体在模型空间中的顶点坐标都是 (-1, -1, -1) 到 (1, 1, 1)。当你将这两个立方体放置到世界空间中时,你可以通过平移操作将第一个立方体放置在 (0, 0, 0),将第二个立方体放置在 (5, 0, 0)。这样,在世界空间中,第一个立方体的顶点坐标将是 (-1, -1, -1) 到 (1, 1, 1),而第二个立方体的顶点坐标将是 (4, -1, -1) 到 (6, 1, 1)。
# 模型空间转世界空间的例子
假设有两个模型:
我们希望在世界空间中,1 个单位长度表示 1 米。
缩放模型 A:
缩放模型 B:
应用模型变换:
- 对缩放后的模型
A 和模型 B,分别应用平移和旋转矩阵,将它们转换到世界空间中的目标位置和方向。
通过上述步骤,模型 A 和模型 B 在世界空间中的单位长度将统一为 1 米,从而保持一致的比例。
# 观察空间
是指从摄像机或观察者的视角来看待场景的坐标系。
在这个空间中,摄像机位于原点,观察方向沿着 Z 轴的负方向,摄像机的上方向沿着 Y 轴正方向。
观察空间是一个局部坐标系,所有物体的位置和方向都是相对于摄像机的位置和方向来定义的。
物体从世界空间转换到观察空间通常涉及一个视图变换。这个变换将物体从世界坐标系转换到摄像机的局部坐标系。
在观察空间中,通常会进行裁剪操作,以去除摄像机视野范围之外的物体。裁剪操作通常在观察空间中进行,因为在这个空间中,摄像机的视野范围可以很容易地用一个视锥体来表示。
摄像机的视锥体在观察空间中定义,它决定了哪些对象会被渲染到视图中。视锥体包括近裁剪面和远裁剪面,以及摄像机的视场角。
假设有一个立方体在世界空间中的位置是 (5, 0, 0),并且摄像机位于 (0, 0, 5),观察方向沿着 Z 轴的负方向。通过视图变换,你可以将立方体从世界空间转换到观察空间。在这个过程中,立方体的位置会相对于摄像机的位置和方向进行调整。
作用:
-
裁剪和优化:在观察空间中,可以进行视锥体裁剪,这是一种优化技术,用于剔除那些不在摄像机视锥体内的对象,从而提高渲染效率。
-
光照和阴影计算:在观察空间中,可以计算相对于摄像机的光照和阴影效果,这对于动态光源和阴影的计算尤为重要。
-
透视投影:在观察空间中,可以应用透视投影,将 3D 坐标转换为 2D 屏幕坐标,这种投影考虑了透视效果,即远处的物体看起来比近处的物体小。
-
深度缓冲:在观察空间中,可以计算每个像素的深度值,这有助于确定对象的前后顺序,以及处理遮挡关系。
# =====

# 仿射空间
仿射空间是向量空间(也叫线性空间)的扩展。
仿射空间是一个没有固定原点的向量空间,但保留了向量加法和数乘运算的结构。
点与向量:
在仿射空间中,点和向量是两个基本概念。
点表示位置,向量表示方向和大小。
每个向量的起点都是原点。
运算:
-
点与向量的加法:给定一个点 P 和一个向量 v,它们的和 P+v 是一个新的点 Q,表示从点 P 沿着向量 v 的方向移动得到的点。
-
向量的加法:给定向量 v1 和 v2,它们的和 v1+v2 是一个新的向量,表示两个向量的合成方向。
-
向量的数乘:给定向量 v 和标量 k,它们的积 kv 是一个新的向量,表示向量 v 按比例 k 缩放后的结果。
仿射组合:
在仿射空间中,一个点的位置可以通过一组基点的仿射组合来表示。
仿射组合是指一组点的线性组合,其系数之和为 1。
给定一组点 P1,P2,…,Pn 和一组标量 a1,a2,…,an,其中 a1+a2+⋯+an=1,仿射组合表示为:
P=a1P1+a2P2+⋯+anPn
这个组合表示一个新的点 P,它是基点 P1,P2,…,Pn 的线性组合。
仿射变换:
仿射变换是一种保持仿射空间中线性组合关系的变换。
常见的仿射变换包括平移、缩放、旋转和剪切。
仿射空间的特点:
# 仿射变换
仿射变换是一种保持仿射空间中线性组合关系的变换。
仿射变换可以表示为线性变换和平移的组合。
线性变换:
线性变换是一种保持向量加法和数乘运算的变换。在二维空间中,线性变换可以表示为一个矩阵乘法:
(x′y′)=(acbd)(xy)
其中 (acbd) 是变换矩阵。
平移:
平移是将所有点沿着某个方向移动固定距离的变换。在二维空间中,平移可以表示为:
(x′y′)=(xy)+(txty)
其中 (txty) 是平移向量。
仿射变换的表示:
仿射变换可以表示为线性变换和平移的组合。在二维空间中,仿射变换可以表示为:
(x′y′)=(acbd)(xy)+(txty)
其中 (acbd) 是线性变换矩阵,(txty) 是平移向量。
还可以表示为:
y=Ax+b
-
A 是一个线性变换矩阵。
-
x 是原始向量。
-
b 是一个平移向量。
-
y 是变换后的向量。
常见的仿射变换之平移:
(x′y′)=(1001)(xy)+(txty)
常见的仿射变换之缩放:
(x′y′)=(sx00sy)(xy)+(00)
其中 sx 和 sy 是缩放因子。
常见的仿射变换之旋转:
(x′y′)=(cosθsinθ−sinθcosθ)(xy)+(00)
其中 θ 是旋转角度。
常见的仿射变换之剪切:
(x′y′)=(1kykx1)(xy)+(00)
其中 kx 和 ky 是剪切因子。
# 仿射变换中的平移如何转换为线性变换?
在仿射变换中,平移是一种非线性变换,因为它不能通过简单的矩阵乘法来表示。
然而,通过引入齐次坐标,我们可以将平移转换为线性变换,从而使得仿射变换可以用单一的矩阵乘法来表示。
齐次坐标:
齐次坐标是一种在多维空间中表示点和向量的方法,通过增加一个额外的维度来实现。
在二维空间中,一个点的齐次坐标表示为 (x,y,w),其中 w 是齐次坐标中的权重因子。
通常情况下,我们使用 w=1 来表示二维空间中的点。
将平移转换为线性变换:
在二维空间中,平移变换可以表示为:
(x′y′)=(xy)+(txty)
其中 (txty) 是平移向量。
为了将平移转换为线性变换,我们引入齐次坐标,将二维点 (x,y) 表示为齐次坐标 (x,y,1)。然后,平移变换可以表示为一个矩阵乘法:
x′y′1=100010txty1xy1
仿射变换的齐次坐标表示:
通过引入齐次坐标,我们可以将仿射变换(包括线性变换和平移)表示为一个单一的矩阵乘法。在二维空间中,仿射变换可以表示为:
x′y′1=ac0bd0txty1xy1
其中 (acbd) 是线性变换矩阵,(txty) 是平移向量。
示例:
假设我们有一个点 P(x,y),我们希望对其进行平移变换,平移向量为 (23)。使用齐次坐标,我们可以表示为:
x′y′1=100010231xy1
# 齐次坐标中 w = 0 表示什么意思?
在齐次坐标系中,一个点的坐标通常表示为 (x,y,z,w),其中 w 是一个非零的实数。
齐次坐标的一个重要特性是,通过将每个坐标除以 w,可以得到该点的标准欧几里得坐标 (x/w,y/w,z/w)。
在齐次坐标中,w=0 表示一个在无穷远处的点和方向。
在二维空间中,(x,y,0) 表示一个无穷远处的点,而在三维空间中,(x,y,z,0) 表示一个无穷远处的点。这种表示法在处理透视变换、投影变换和射影几何时非常有用。
我们知道一个点光源的无限远处是平行光,类似于太阳光,太阳是一个点光源,光线到地球后变成了平行光。因此平行光可以通过改变点光源位置向量对应的齐次坐标中的 w 的值来表示,当 w=1 时,即还在点光源的原来位置,依旧是一个点光源。当 w=0 时,即在点光源的无限远处,变为一个平行光。
# 线性变换的本质
在二维空间中,设两个基向量 x=(1,0) 和 y=(0,1),则任意一个向量 a=(i,j) 可以表示为 a=ix+jy。
当空间发生线性变换后,所有向量都会发生变换,包括基向量。
假设变换后的基向量为 x′=(x1,y1) 和 y′=(x2,y2),则变换后的向量 a 可以表示为 a=ix′+jy′=i(x1,y1)+j(x2,y2)。
写成矩阵形式,得到:
a=i[x1y1]+j[x2y2]=[ix1iy1]+[jx2jy2]=[ix1+jx2iy1+jy2]=[x1y1x2y2][ij]
其中,[x1y1x2y2] 是变换矩阵。
x′=(x1,y1) 是 x=(1,0) 经过线性变换后的基向量,y′=(x2,y2) 是 y=(0,1) 经过线性变换后的基向量。
因此,线性变换的本质是将向量表示为基向量的线性组合,并通过变换矩阵将原来的基向量变换为新的基向量。
# 向量的构造以及平移不变性
向量的构造:
-
向量可以直接通过指定其分量来定义。
-
在二维空间中,向量 v=(v1,v2) 可以通过指定 v1 和 v2 的值来定义。
-
在三维空间中,向量 v=(v1,v2,v3) 可以通过指定 v1、v2 和 v3 的值来定义。
-
向量可以通过两个点的坐标差来计算。
-
在二维空间中,如果有点 A(x1,y1) 和点 B(x2,y2),那么从点 A 到点 B 的向量 v 可以表示为:v=(x2−x1,y2−y1)。
-
在三维空间中,如果有点 A(x1,y1,z1) 和点 B(x2,y2,z2),那么从点 A 到点 B 的向量 v 可以表示为:v=(x2−x1,y2−y1,z2−z1)。
-
在几何学中,向量可以通过几何构造得到。
平移不变性:
-
平移不变性是指将一个向量从一个位置平移到另一个位置,向量的方向和大小保持不变。
-
平移不变性是指向量的方向和大小不会因为空间的平移而改变,但这并不妨碍它们在空间中进行平移变换,因为这种变换只是改变了它们的位置,而没有改变它们的方向和大小。
-
有点 A(1,2) 和点 B(3,5),那么从点 A 到点 B 的向量 v 可以表示为:v=(3−1,5−2)=(2,3),对空间进行平移变换后,此时点 A(4,5) 和点 B(6,8),但向量 v=(2,3) 的方向和大小保持不变。
# 复合变换
将多个变换矩阵按顺序相乘,以实现一系列连续的变换。
这种复合变换可以应用于向量或点,使其按照指定的顺序进行旋转、缩放、平移等操作。
假设我们有多个变换矩阵 T1,T2,…,Tn,我们希望对一个向量 v 进行这些变换。复合变换的矩阵 T 可以通过将这些变换矩阵按顺序相乘得到:
T=Tn⋅Tn−1⋅…⋅T2⋅T1
然后,我们可以通过以下方式对向量 v 进行复合变换:
v′=T⋅v
其中,v′ 是变换后的向量。
具体例子:
假设我们有以下三个变换矩阵:
T1=100001000010txtytz1
- 旋转矩阵 T2(绕 z 轴旋转 θ 角度):
T2=cosθsinθ00−sinθcosθ0000100001
T3=sx0000sy0000sz00001
我们希望对向量 v=xyz1 进行先平移、再旋转、最后缩放的复合变换。
复合变换矩阵 T=T3⋅T2⋅T1。
计算复合变换矩阵 T:
T=sx0000sy0000sz00001⋅cosθsinθ00−sinθcosθ0000100001⋅100001000010txtytz1
对向量 v 进行复合变换:
v′=T⋅v
这样,v′ 就是经过平移、旋转和缩放后的向量。
矩阵乘法不满足交换律,即 A⋅B=B⋅A。因此,变换矩阵的顺序非常重要。通常,变换的顺序是从右到左,即先应用最右边的矩阵,最后应用最左边的矩阵。
通过这种方式,我们可以将多个变换组合成一个单一的变换矩阵,从而简化计算和提高效率。
# 三维空间的旋转变换
在三维空间中,旋转变换的定义和性质会受到坐标系手性的影响,即左手坐标系和右手坐标系之间的差异。
右手坐标系:
左手坐标系:
左手坐标系,绕 X 轴旋转:
正方向(顺时针)旋转 θ 角度,旋转矩阵 Rx(θ) 可以表示为:
Rx(θ)=1000cosθsinθ0−sinθcosθ
反方向(逆时针)旋转 θ 角度,旋转矩阵 Rx(θ) 可以表示为:
Rx(θ)=1000cosθ−sinθ0sinθcosθ
右手坐标系,绕 X 轴旋转:
正方向(逆时针)旋转 θ 角度,旋转矩阵 Rx(θ) 可以表示为:
Rx(θ)=1000cosθsinθ0−sinθcosθ
反方向(顺时针)旋转 θ 角度,旋转矩阵 Rx(θ) 可以表示为:
Rx(θ)=1000cosθ−sinθ0sinθcosθ
左手坐标系,绕 Y 轴旋转:
正方向(顺时针)旋转 θ 角度,旋转矩阵 Ry(θ) 可以表示为:
Ry(θ)=cosθ0−sinθ010sinθ0cosθ
反方向(逆时针)旋转 θ 角度,旋转矩阵 Ry(θ) 可以表示为:
Ry(θ)=cosθ0sinθ010−sinθ0cosθ
右手坐标系,绕 Y 轴旋转:
正方向(逆时针)旋转 θ 角度,旋转矩阵 Ry(θ) 可以表示为:
Ry(θ)=cosθ0−sinθ010sinθ0cosθ
反方向(顺时针)旋转 θ 角度,旋转矩阵 Ry(θ) 可以表示为:
Ry(θ)=cosθ0sinθ010−sinθ0cosθ
左手坐标系,绕 Z 轴旋转:
正方向(顺时针)旋转 θ 角度,旋转矩阵 Rz(θ) 可以表示为:
Rz(θ)=cosθsinθ0−sinθcosθ0001
反方向(逆时针)旋转 θ 角度,旋转矩阵 Rz(θ) 可以表示为:
Rz(θ)=cosθ−sinθ0sinθcosθ0001
右手坐标系,绕 Z 轴旋转:
正方向(逆时针)旋转 θ 角度,旋转矩阵 Rz(θ) 可以表示为:
Rz(θ)=cosθsinθ0−sinθcosθ0001
反方向(顺时针)旋转 θ 角度,旋转矩阵 Rz(θ) 可以表示为:
Rz(θ)=cosθ−sinθ0sinθcosθ0001
总结:
旋转矩阵的逆矩阵即是旋转矩阵的转置矩阵。