Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第三章:变换

学习目标

  1. 理解如何用矩阵表示线性变换和仿射变换;
  2. 学习在坐标系中缩放,旋转和移动几何体;
  3. 学习利用矩阵的乘法合并几个变换矩阵;
  4. 学习如何在坐标系之间转换,并且表示为转换矩阵;斜体样式
  5. 学习如何利用DirectX Math库提供的方法构造转换矩阵。


1 线性转换


1.1 线性转换的定义

现在有方程 τ ( v ) = τ ( x , y , z ) = τ ( x 1 , y 1 , z 1 ) τ(v) = τ(x, y, z) = τ(x^1, y^1, z^1) τ(v)=τ(x,y,z)=τ(x1,y1,z1),当且仅当它满足下列属性的时候:
这里写图片描述
我们称它为一个线性变换。其中u和v是3D向量,k是标量。

例如定义 τ ( v ) = τ ( x , y , z ) = τ ( x 2 , y 2 , z 2 ) τ(v) = τ(x, y, z) = τ(x^2, y^2, z^2) τ(v)=τ(x,y,z)=τ(x2,y2,z2);τ(1, 2, 3) = (1, 4, 9);这个方程不是线性的,因为如果k = 2和u = (1, 2, 3):τ(ku) = τ(2, 4, 6) = (4, 16, 36),但是kτ(u) = 2(1, 4, 9) = (2, 8, 18)
所以不符合性质2,如果它是线性的,它应该符合:
这里写图片描述


1.2 矩阵表示

令u = (x, y, z)我们可以把它写成如下形式:
u = ( x , y , z ) = x i + y j + z k = x ( 1 , 0 , 0 ) + y ( 0 , 1 , 0 ) + z ( 0 , 0 , 1 ) u = (x, y, z) = xi + yj + zk = x(1, 0, 0) + y(0, 1, 0) + z(0, 0, 1) u=(x,y,z)=xi+yj+zk=x(1,0,0)+y(0,1,0)+z(0,0,1)
其中向量i = (1, 0, 0), j = (0, 1, 0), k = (0, 0, 1),是坐标系轴方向的单位向量,它们分别被称为 R 3 R^3 R3的标准基本向量,现在令τ为一个线性变换,它具备下面性质:
这里写图片描述
那么它可以被写成向量和矩阵相乘的形式:
这里写图片描述
其中这里写图片描述,我们称矩阵A是线性变换τ的矩阵表现。


1.3 缩放

我们使用下面的公式来定义缩放:
S ( x , y , z ) = ( s x x , s y y , s z z ) S(x, y, z) = (s_xx, s_yy, s_zz) S(x,y,z)=(sxx,syy,szz)
它是物体在x轴方向缩放 s x s_x sx倍,在y轴和z轴同理;我们现在要证明S 是一个线性转换:
这里写图片描述
为了得到矩阵表现,我们把S应用到每个标准基本向量中,然后把结果放到矩阵的每一行中:
这里写图片描述
所以S的矩阵表现为:
这里写图片描述
我们称这个矩阵为缩放矩阵,其逆矩阵为:
这里写图片描述


1.4 旋转

这一节我们描述将一个向量V关于轴n旋转θ角度;其中角度是当我们看向n轴时的顺时针方向,并且||n|| = 1:
这里写图片描述
首先将v分解为2部分:平行于n( p r o j n ( v ) proj_n(v) projn(v))和垂直于n( p e r p n ( v ) perp_n(v) perpn(v));因为n是一个单位向量,所以 p r o j n ( v ) = ( n ⋅ v ) n proj_n(v) = (n \cdot v)n projn(v)=(nv)n;值得注意的是 p r o j n ( v ) proj_n(v) projn(v)是平行于n的,它在旋转的过程中不变,所以我们只需要关注垂直那部分如果旋转,即旋转向量的结果就等于: R n ( v ) = p r o j n ( v ) + R n ( p e r p n ( v ) ) R_n(v) = proj_n(v) + R_n(perp_n(v)) Rn(v)=projn(v)+Rn(perpn(v))

为了计算 R n ( p e r p n ( v ) ) R_n(perp_n(v)) Rn(perpn(v)),我们在旋转的平面上构建一个2D坐标系,首先使用 p e r p n ( v ) perp_n(v) perpn(v)为第一个引用向量,为了得到第二个引用向量,我们使用叉积得到一个同时垂直于v和n的向量 n × v n \times v n×v,根据之前第一章练习14证明的公式(α是n和v之间的夹角):
∣ ∣ n × v ∣ ∣ = ∣ ∣ n ∣ ∣ ∣ ∣ v ∣ ∣ s i n a = ∣ ∣ v ∣ ∣ s i n a = ∣ ∣ ∣ p e r p n ( v ) ∣ ||n \times v|| = ||n||||v||sina = ||v||sina = |||perp_n(v)| n×v=nvsina=vsina=perpn(v)
所以所有引用向量的长度都是一样的,并且都是同一个园的半径,现在我们可以建立起他们之间的联系,得到公式如下:
这里写图片描述

进一步,可以得到旋转公式:
这里写图片描述

然后根据1.2中的公式,将上述线性变换转成矩阵(其中c为cosθ,s为sinθ):
这里写图片描述

旋转矩阵有一个有趣的性质,它每一行的向量都是单位长度,并且互相垂直,所以它的行向量们是标准正交的;一个矩阵的行向量们标准正交的话,该矩阵称为标准正交矩阵。标准正交矩阵有一个很吸引人的性质:它的逆矩阵等于它的转置矩阵,所以:
这里写图片描述
通常来说,标准正交矩阵是非常值得使用的,因为它的逆矩阵可以很简单和高效的计算出来。

在特殊情况下,如果我们要围绕x,y,z轴旋转,我们可以得到下列矩阵:
这里写图片描述



2 仿射变换


2.1 齐次坐标系

在下一节中,我们将看到仿射变换其实是线性变换结合位移;位移不适用于向量,因为向量只表示方向和长度,其次坐标系中提供了一个计数方法可以点和向量的变化一致:
1、使用(x, y, z, 0)表示向量(w = 0可以保证向量在变化中不进行位移);
2、使用(x, y, z, 0)表示点。


2.2 矩阵表示的定义

一个仿射变换是一个线性变化加一个位移变化:
a ( u ) = τ ( u ) + b a(u) = τ(u) + b a(u)=τ(u)+b
或者用矩阵表示:
这里写图片描述
如果我们使用w = 1来扩展到齐次坐标系,那么可以使用更简洁的写法:
这里写图片描述
这个4 x 4矩阵就是仿射变换的矩阵表示,如果是针对向量,不想做位移操作,只需要把第四行w设置为0即可。


2.3 位移

位移矩阵:
这里写图片描述
位移矩阵的逆矩阵:
这里写图片描述


2.4 仿射矩阵的缩放和旋转

这里写图片描述


2.5 仿射矩阵变换的几何解释

令τ是一个旋转变换,b是一个平移变换,那么这个变换就可以描述为一个仿射变换:
这里写图片描述

用其次坐标系(对于顶点w=1,对向量w=0)的矩阵表示为:
这里写图片描述

我们可以看到τ只是旋转了每一个标准分向量i,j和k;α(x, y, z) = xτ(i) + yτ(j) + zτ(k) + b,向量b只是平移了每一个顶点:
这里写图片描述
这里写图片描述

相同的思路也可以解释缩放变换:
这里写图片描述



3 变换的结合

假设S是一个缩放矩阵,R是一个旋转矩阵,T是一个平移矩阵;如果我们要对一个具有8个顶点的立方体做如何变换,最显而易见的方法是一步一步变换:
这里写图片描述

因为矩阵的乘法具有结合律,所以:
这里写图片描述
我们可以设C = SRT为一个同时封装了3个变换的矩阵。



4 坐标系变换

在3D计算机图形学中,我们需要使用到多个坐标系和坐标系之间的变换,对于顶点和向量的坐标系变幻是不同的。


4.1 向量

下图中,有两个坐标系A和B,与一个向量P。
这里写图片描述
很明显 p = xu + yv,其中u和v是坐标系A中,x和y方向上的单位向量;那么 P B P_B PB就可以解释为 P B = x u B + y v B P_B = xu_B + yv_B PB=xuB+yvB;所以,如果我们知道 u B = ( u x , u y ) u_B = (u_x, u_y) uB=(ux,uy) v B = ( v x , v y ) v_B = (v_x, v_y) vB=(vx,vy),那么我们就可以计算出 p B = ( x ′ , y ′ ) p_B = (x', y') pB=(x,y)

扩展到3D情况:这里写图片描述


4.2 点

点的变换和向量有一点不同,点的位置很重要,如下图:
这里写图片描述
P点在坐标系A中可以表示为p = xu + yv + Q,那么在B坐标系中可以表示为 P B = x u B + y v B + Q B P_B = xu_B + yv_B + Q_B PB=xuB+yvB+QB;所以,如果我们知道 u B = ( u x , u y ) u_B = (u_x, u_y) uB=(ux,uy) v B = ( v x , v y ) v_B = (v_x, v_y) vB=(vx,vy) Q B = ( Q x , Q y ) Q_B = (Q_x, Q_y) QB=(Qx,Qy),那么我们就可以计算出 p B = ( x ′ , y ′ ) p_B = (x', y') pB=(x,y)

扩展到3D的情况:这里写图片描述(其中Q是原点)


4.3 矩阵的表示

在齐次坐标系下:这里写图片描述

那么矩阵表示如下:
这里写图片描述
我们称上述矩阵为一个坐标系变换矩阵,它将坐标系A变换到坐标系B。


4.4 坐标系变换矩阵的结合律

假设我们有3个坐标你F,G,H;矩阵A可以从F变换到G,矩阵B可以从G变换到H;我们希望将向量p从F变换到H,最显而易见的方法就是一步一步变换:
这里写图片描述

根据矩阵的乘法结合律:
这里写图片描述

在这种情况下,矩阵C= AB可以将p直接从F坐标系变换到H坐标系。(再次提醒,矩阵的乘法不支持交换律)


4.5 坐标系变换矩阵的逆矩阵

假设我们有一个在B坐标系的向量p,我们有从坐标系A变换到B的矩阵M,如果将P变换到坐标系A,乘以M的逆矩阵就可以了:
这里写图片描述

在本书中提到的坐标系变换映射都是可逆的,所以不需要担心是否存在逆矩阵。
这里写图片描述



5 变换矩阵 vs 坐标系变换矩阵

变换矩阵和坐标系变换矩阵是相同的,变化矩阵可以被解释为一个坐标系变换矩阵,反之亦然。
这里写图片描述
这里写图片描述



6 DIRECTX MATH 中的变换函数

在DIRECTX MATH中与变换函数相关的总结如下:

// Constructs a scaling matrix:
XMMATRIX XM_CALLCONV XMMatrixScaling(
float ScaleX,
float ScaleY,
float ScaleZ); // Scaling factors

// Constructs a scaling matrix from components in vector:
XMMATRIX XM_CALLCONV XMMatrixScalingFromVector(
FXMVECTOR Scale); // Scaling factors (sx, sy, sz)

// Constructs a x-axis rotation matrix Rx:
XMMATRIX XM_CALLCONV XMMatrixRotationX(
float Angle); // Clockwise angle θ to rotate

// Constructs a y-axis rotation matrix Ry:
XMMATRIX XM_CALLCONV XMMatrixRotationY(
float Angle); // Clockwise angle θ to rotate

// Constructs a z-axis rotation matrix Rz:
XMMATRIX XM_CALLCONV XMMatrixRotationZ(
float Angle); // Clockwise angle θ to rotate

// Constructs an arbitrary axis rotation matrix Rn:
XMMATRIX XM_CALLCONV XMMatrixRotationAxis(
FXMVECTOR Axis, // Axis n to rotate about
float Angle); // Clockwise angle θ to rotate

// Constructs a translation matrix:
XMMATRIX XM_CALLCONV XMMatrixTranslation(
float OffsetX,
float OffsetY,
float OffsetZ); // Translation factors

// Constructs a translation matrix from components in a vector:
XMMATRIX XM_CALLCONV XMMatrixTranslationFromVector(
FXMVECTOR Offset); // Translation factors (tx, ty, tz)

// Computes the vector-matrix product vM where vw = 1 for transforming points:
XMVECTOR XM_CALLCONV XMVector3TransformCoord(
FXMVECTOR V, // Input v
CXMMATRIX M); // Input M

// Computes the vector-matrix product vM where vw = 0 for transforming vectors:
XMVECTOR XM_CALLCONV XMVector3TransformNormal(
FXMVECTOR V, // Input v
CXMMATRIX M); // Input M

最后两个函数XMVector3TransformCoord和XMVector3TransformNormal,你不需要手动设置w = 0还是1,因为函数中会强制设置w的值。



7 本章总结

  1. 基础的变换矩阵:旋转,缩放和平移矩阵公式如下:
    这里写图片描述
  2. 我们使用4x4矩阵表示变换;用1x4齐次坐标系来描述顶点和向量,其第四个值w,对于顶点为1,对于向量为0;
  3. 一个矩阵如果其4行向量都是单位向量并且相互垂直,则该矩阵为正交矩阵;正交矩阵的逆矩阵和它的转置矩阵相等,所以它的逆矩阵计算起来很简单和高效,所有旋转矩阵都是正交矩阵;
  4. 根据矩阵的乘法结合律,我们可以将多个变换矩阵合成为一个变化矩阵;
  5. u B u_B uB v B v_B vB Q B Q_B QB W B W_B WB描述B坐标系下在A坐标系中的值,那么一个在A坐标系下的向量/顶点P,在B坐标系下的值就可以计算为:
    这里写图片描述
  6. 假设有3个坐标系F,G和H,并且A矩阵从F变换到G,B矩阵从G变换到H;我们可以得到C = AB矩阵从F变换到H;
  7. 如果矩阵M可以从A坐标系变换到B坐标系,那么M的逆矩阵就可以从B坐标系变换到A坐标系;
  8. 一个有效的变换可以被解释为坐标系变换,反之亦然。


8 练习题

1、定义如下变换:τ(x, y, z) = (x + y, x – 3, z)。τ是否为线性变换,如果是,找出它的矩阵表示:

2、定义如下变换:τ(x, y, z) = (3x + 4z, 2x – z, x + y + z)。τ是否为线性变换,如果是,找出它的矩阵表示:

3、假设τ是一个线性变换,进一步假设τ(1, 0, 0) = (3, 1, 2), τ(0, 1, 0) = (2, -1, 3), 和 τ(0, 0, 1) = (4, 0, 2);找出τ(1, 1, 1):

4、创建一个缩放矩阵,x轴方向放大2倍,y轴方向放大-3倍,Z轴保持不变:

5、创建一个旋转矩阵,围绕(1, 1, 1)旋转30度:

6、创建一个平移矩阵,x轴方向移动4,y轴方向不变,z轴方向移动-9:

7、创建一个矩阵,先缩放(2, -3, 0),再平移(4, 0, -9):

8、创建一个矩阵,先旋转(0, 45度, 0),再平移(-2, 5, 1):

9、重做例子3.2,这次缩放(1.5, 0.75, 1),并且画图验证结果:

10、重做例子3.3,这次旋转(0,45度,0),并且画图验证结果:

11、重做例子3.4,这次平移(-5, -3, 4),并且画图验证结果:

12、证明 R n ( v ) = c o s θ v + ( 1 − c o s θ ) ( n ⋅ v ) n + s i n θ ( n × v ) R_n(v) = cosθv + (1 − cosθ) (n·v)n + sinθ(n × v) Rn(v)=cosθv+(1cosθ)(nv)n+sinθ(n×v)是线性变换,并且找到他的矩阵表示:

13、证明 R y R_y Ry是标准正交的,为了更多扩展练习,读者也可以证明基本旋转矩阵也是标准正交的:

14、证明M是标准正交的,有且仅有当 M T = M − 1 M^T = M^{-1} MT=M1

15、计算这里写图片描述
这些计算移动顶点了吗,移动向量了吗?为什么没有移动向量在坐标系中的位置?

16、证明缩放矩阵的倒转就是它的逆矩阵,用矩阵的乘法表示为: S S − 1 = S − 1 S = I SS^{-1} = S^{-1}S = I SS1=S1S=I;同样的,证明平移矩阵:

17、假设我们有2个坐标系A和B,在A坐标系下的点p和力q;
这里写图片描述
创建从A坐标系映射到B坐标系的坐标系变换矩阵,并且计算在B坐标系下的p和q,并且画图验证结果:

18、

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
This updated bestseller provides an introduction to programming interactive computer graphics, with an emphasis on game development using DirectX 11. The book is divided into three main parts: basic mathematical tools, fundamental tasks in Direct3D, and techniques and special effects. It includes new Direct3D 11 features such as hardware tessellation and the compute shader, and covers advanced rendering techniques such as ambient occlusion, normal and displacement mapping, shadow rendering, particle systems, and character animation. Includes a companion DVD with code and figures. Brief Table of Contents: Part I Mathematical Prerequisites. Vector Algebra. Matrix Algebra. Transformations. Part II Direct3D Foundations. Direct3D Initialization. The Rendering Pipeline. Drawing in Direct3D. Lighting. Texturing. Blending. Stenciling. The Geometry Shader. The Compute Shader. The Tessellation Stages. Part III Direct3D Topics. Building a First Person Camera. Instancing and Frustum Culling. Picking. Cube Mapping. Normal and Displacement Mapping. Terrain Rendering. Particle Systems and Stream-Out. Shadow Mapping. Ambient Occlusion. Meshes. Quaternions. Character Animation. Appendices. Introduction to Windows Programming. High-Level Shading Language Reference. Some Analytic Geometry. Selected solutions. Features: +Provides an introduction to programming interactive computer graphics, with an emphasis on game development using DirectX 11 +Covers new Direct3D 11 features +Includes companion DVD with source code and 4-color graphics
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值