第三章 第六节 转换模型坐标到视点坐标

转换模型坐标到视点坐标(Converting Model Coordinates to the View Frame

 

前面的步骤都是关于(geared towards)在当前场景中建立和最小化可见的多边形。描述这些多边形的定点都存储成坐标,这些坐标都是物体的本地坐标。为了让我的3D场景看起来像模像样,我需要把所有的这些顶点变换到正确的屏幕坐标。这个过程通过三个变换矩阵来完成。前两个是投影(projection)和观察(view)矩阵。这两个涉及到摄像机,我们将在第六章讨论。眼下,我们仅需认为这两个矩阵用来定义摄像机的位置和镜头。对物体很重要的是第三个矩阵。

 

第三个矩阵叫做世界变换矩阵。此矩阵用来把物体坐标系的每个顶点变换到世界坐标。视频卡将使用基于摄像机(camera-based)的矩阵把经过变换的最终顶点变换到屏幕坐标。既然我们已经确定了此矩阵要做些什么,那么就看看它是怎么工作的。

 

每个矩阵是4x4的浮点值数组。通过在一个矩阵和一个顶点向量之前执行向量/矩阵乘法,我们最终得到另一个坐标系统下的一个经过变换的向量。此乘法允许我们在顶点上一次支持三种操作:平移、旋转和缩放。3-2 图示了这个矩阵,我们后面的讨论将以这些字母来指代矩阵的16个元素。

3-2:世界变换矩阵

 

作为出发点,我们看看一个不改变任何东西的矩阵。这就是知名的单位矩阵。单位矩阵所有元素全零除了四个对角元素(AFKP)是1。用此矩阵去乘任何顶点向量,会得到和原来向量一样的新向量。换句话说,单位矩阵就相当于乘了一个1

 

为了在变换中移动一个顶点,矩阵中有三个元素分别表示沿每个坐标轴移动的数量。M表示沿X轴移动的数量。N表示沿Y轴移动的数量,而O则是沿Z轴移动的数量。

 

通过在变换矩阵内包含缩放因子,我们可以使离视点远的物体变换较小,而离视点近的物体则较大。这三个元素是AFK,分别对应沿XYZ轴的缩放因子。

 

矩阵执行的第三个操作是旋转。这个操作要教复杂一些,因为有三个独立的(three separate rotations)旋转需要处理,每个都围绕其中的一个坐标轴。让我们从围绕X轴旋转开始,每此只看一个旋转。在这些例子中,Q表示旋转的角度,以弧度为单位。所有的旋转都以弧度为单位,因为三角函数例如sinecosinesin cos)需要接受弧度为输入参数。为了围绕X轴旋转,矩阵的多个元素需要设定,见列表3-9

 

列表 3.9X轴旋转变换

F = cos(Q)

G = sin(Q)

J = 2* sin(Q)

K=cos(Q)

 

围绕Y轴旋转需要设置的元素见列表3-10

列表 3.10Y轴旋转变换

A = cos(Q)

C = 2 * sin(Q)

I = sin(Q)

K = cos(Q)

 

最后,围绕Z轴旋转需要设定的矩阵元素见列表3-11

列表 3.11Z轴旋转变换

A = cos(Q)

B = sin(Q)

E = 2 * sin(Q)

F = cos(Q)

 

把它们放在一起,我们得到面目狰狞(nasty-looking)矩阵,见3-3

3-3:世界变换矩阵公式

 

幸运的是我们不必要手动的在每一帧建立这个矩阵。Microsoft在类Matrix里提供了许多方法用来处理矩阵。表格3-1列出了这些方法,后面跟了一个简短的描述,介绍怎么使用。

 

表格3-1Matrix处理方法

方法

描述

Matrix.Identity

Indicates a static property identity matrix

Translate

Sets the translation factors along the three axes

Scale

Sets the transform scaling factor

RotateX

Adds a rotation factor around the X-axis

RotateY

Adds a rotation factor around the Y-axis

RotateZ

Adds a rotation factor around the Z-axis

RotateYawPitchRoll

Rotates around all three axes using the three supplied angles

Multiply

Combines two matrices by multiplying them together

你将会在后面的章节里看到当我们使用3D对象时使用这些方法。

 

一旦我们为当前对象确定了变换矩阵,就到把对象里所有顶点变换到世界坐标系的时刻了。就在最近几年前,我们还必须在代码中亲自迭代处理所有的顶点,执行乘法。幸运的是,现代的视频卡带了硬件的变换和光照功能。为了使用这个特征,我仅仅需要把顶点列表和要使用的世界变换矩阵提供给视频卡即可。列表3-12来自Microsoft的公告板Demo,做了一个示例。

 

列表3.12Matirx操作示例

foreach(Tree t in trees)

{

   // Set the tree texture.

   device.SetTexture(0, treeTextures[t.treeTextureIndex] );

 

   // Translate the billboard into place.

   billboardMatrix.M41 = t.vPos.X;

   billboardMatrix.M42 = t.vPos.Y;

   billboardMatrix.M43 = t.vPos.Z;

   device.SetTransform(TransformType.World , billboardMatrix);

   // Render the billboard.

   device.DrawPrimitive( PrimitiveType.TriangleStrip, t.offsetIndex, 2 );

}

   // Restore state.

   Matrix matWorld;

   matWorld = Matrix.Identity;

   device.Transform.World = matWorld;

 

让我们浏览一下代码,看看发生了什么。示例中软件(译注:原文是software,可以理解成code,这里作者选用software一词,强调了视频卡硬件和软件的区别。)循环遍历了树中所有的对象。For each tree, the texture for the tree billboard is set as the current texture. 在这个例子中,通过设置矩阵里的平移成员来直接设定树的位置。SetTransform方法把矩阵提供给设备(device)以便渲染程序使用。循环里最后的调用DrawPrimitive方法执行广告牌树真正的渲染。方法的第一个参数指明了顶点是排列成三角形带。这种格式允许一个矩形(两个贴着的三角形)使用四个顶点来指定。第二个参数表示从顶点缓存(vertex buffer)的偏移开始进行渲染。最后一个参数表示有两个三角形需要渲染。

 

通过把数据下载至视频卡让DirectX来执行变换,并且DirectX让硬件来执行变换对渲染性能是一个很大的促进。即使视频卡不支持硬件变换和光照,使用DirectX执行运算也要比我们自己来做这件事更好。DirectX支持的软件变换是经过高度优化的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值