原文作者讲得太好了,唯有这篇让我对视图矩阵了解的清晰了很多。

----------------------------------------------------------------------------

什么是View Transform

我们可以用照相机的原理来阐释3D图形的绘制过程,想象一下,我们在摄影的时候都需要做哪些工作,大致可分为如下几个步骤

  1. 摆放好待拍摄的物品,或者人物。
  2. 调整好拍摄角度。
  3. 调整焦距。
  4. 拍摄。

好了,来分析一下,上面的第一步就相当于世界变换了,将一个模型置于一个公认的坐标系中,这里所谓的公认,也就是大家都遵守的,目的是保证待拍摄的物体和照相机在同一个坐标系。第二步相当于视图变换,这个过程是调整Camera到合适的位置以便拍摄,在3D程序中,也就是设置View Matrix了。第三步调整焦距,这就相当于3D编程中的投影变换。

View Transform的过程就是在世界坐标系中摆放Camera的过程,并将顶点由世界坐标系转换到Camera Space,在Camera Space中,观察者(Camera)位于坐标原点,观察方向指向Z轴正方向。

为什么要进行View Transform?

在world space中,camera并不一定位于坐标原点,并且观察方向不一定指向Z轴正方向,对于投影变换及其他的一些操作来说,如果不满足这两个条件,后续的的操作就会变得非常低效,所以为了提高效率,我们需要进行view transform。

View Transform的作用

View Transform主要有下面两个作用。

  • 移动camera,使其位于world space的坐标原点
  • 旋转camera,使其朝向z轴正方向,也就是视线由原点指向z轴正方向。

这两个过程,前一个实际上是平移,后一个实际上是旋转。你可以想象成Camera也有三个坐标轴x,y,z,视图变换的过程就是将Camera的坐标轴与世界坐标系的坐标轴对齐的过程。

注意:view transform中,所有位于world space中的models都随着camera一起变换,所以视野并未发生变化,具体过程见下图

如何求解View Matrix?

使用D3D函数

使用下面的D3D函数可以计算view matrix,第一个参数是输出参数,返回求得的视图矩阵,第二个参数是眼睛的位置,第三个参数是观察点中心,最后一个参数是向上向量。该函数的最后两个字母表示左手系(Left Hand)。

D3DXMatrixLookAtLH(&M, &eyePt, &lookCenter, &upVec) ;

手动求解

手动求解View matrix并不是难事,一个camera一般有如下四个属性,

  • 向前向量(direction),相当于Z轴
  • 向上向量(up vector),相当于Y轴
  • 向右向量(right vector),相当于X轴
  • 位置(position)

其中前三个向量要求是相互垂直的。假设我们分别用d, u, v和p来表示这四个变量。并假设待求的视图矩阵为V,根据前面的介绍我们知道,V的作用就是将摄像机移动到原点,并将摄像机的三个向量分别与坐标轴对齐,d与z轴正方向对齐,u与y轴正方向对齐,r与x轴正方向对齐。假设将摄像机与坐标轴对齐的矩阵为V,那么V的推导过程如下。

通常在实际的编程中,只会给出如下三个量。至于d和r这两个量,只能通过计算求得。

  • 摄像机(眼睛)的位置(eye point),相当于p
  • 观察点中心(look at),假设为向量c
  • 向上向量(up vector),相当于u

可以通过下面方法求得d, r和u。

  • d = c - p,下面第一幅图
  • r = d x u,下面第二幅图
  • u = r x d,下面第三幅图

注意上面的x是叉积运算(cross product),现在p,d,r,u四个量都已经知道,于是就可以根据上面的矩阵M求得视图变换矩阵了,对应的代码如下。该函数有三个参数,分别是摄像机位置p,向上向量u和视点中心lookAt。

D3DXMATRIX buildViewMatrix(D3DXVECTOR3& p, D3DXVECTOR3& u, D3DXVECTOR3& lookAt)
{
// Calculate d
D3DXVECTOR3 d = lookAt - p;
D3DXVec3Normalize(&d, &d); // Calculate r
D3DXVECTOR3 r;
D3DXVec3Cross(&r, &u, &d);
D3DXVec3Normalize(&r, &r); // Calculate up
D3DXVec3Cross(&u, &r, &d);
D3DXVec3Normalize(&u, &u); // Fill in the view matrix entries.
float x = -D3DXVec3Dot(&p, &r);
float y = -D3DXVec3Dot(&p, &u);
float z = -D3DXVec3Dot(&p, &d); D3DXMATRIX M;
M(0,0) = r.x;
M(1,0) = r.y;
M(2,0) = r.z;
M(3,0) = x; M(0,1) = u.x;
M(1,1) = u.y;
M(2,1) = u.z;
M(3,1) = y; M(0,2) = d.x;
M(1,2) = d.y;
M(2,2) = d.z;
M(3,2) = z; M(0,3) = 0.0f;
M(1,3) = 0.0f;
M(2,3) = 0.0f;
M(3,3) = 1.0f; return M;
}

注意事项,在求取View Matrix的时候有几点是需要注意的:

  • 叉积满足右手法则。
  • 叉积不满足交换律。 a x b = - b x a
  • DirectX使用左手系,满足左手法则。

只要最终求得的三个向量,up, right和d满足左手法则即可。如果应用了View Matrix之后发现模型左右或者上下颠倒了,那么就说明求取的时候没有满足左手系。

好了,矩阵求解完毕,赶快使用SetTransform(D3DTS_VIEW, &M) ;来试试吧,效果和使用函数D3DXMatrixLookAtLH是一样的!

Happy Coding!!!

作者:zdd
出处:http://www.cnblogs.com/graphics/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.

(转)View Transform(视图变换)详解的更多相关文章

  1. 第98天:CSS3中transform变换详解

    transform变换详解 本文主要介绍变形transform. Transform字面上就是变形,改变的意思.在CSS3中transform主要包括以下几种:旋转rotate.扭曲skew.缩放sc ...

  2. 【转载】D3DXMatrixLookAtLH视图变换函数详解

    原文:D3DXMatrixLookAtLH视图变换函数详解 /*D3DXMatrixLookAtLH函数返回的是世界->视图变换矩阵. 视图坐标系和局部坐标系是一样的,都是世界坐标系转换为指定的 ...

  3. ThinkPHP视图查询详解

    ThinkPHP视图查询详解 参考http://www.jb51.net/article/51674.htm   这篇文章主要介绍了ThinkPHP视图查询,需要的朋友可以参考下     ThinkP ...

  4. Android 通过Java代码生成创建界面。动态生成View,动态设置View属性。addRules详解

    废话不多说,本文将会层层深入给大家讲解如何动态的生成一个完整的界面. 本文内容: Java代码中动态生成View Java代码中动态设置View的位置,以及其他的属性 LayoutParams详解 一 ...

  5. matlab-霍夫变换详解(判断正方形长方形)

    霍夫变换 霍夫变换是1972年提出来的,最开始就是用来在图像中过检测直线,后来扩展能检测圆.曲线等. 直线的霍夫变换就是 把xy空间的直线 换成成 另一空间的点.就是直线和点的互换. 我们在初中数学中 ...

  6. 新版本Xcode 6的视图调试详解

    开发者会经常遇到视图或者Auto Layout约束中存在bug的情况,并且这种bug很难通过代码发现,所以开发者很有必要熟知如何进行简单高效的视图调试,而Xcode 6的发布使得视图调试变得前所未有的 ...

  7. 【OpenGL】法线变换详解(Normal Transform)[转]

    http://blog.csdn.net/xiajun07061225/article/details/7762711 在图形学中,同样的一个模型视图变换矩阵可以用来变换点.线.多边形以及其它几何体, ...

  8. SpringMVC视图机制详解[附带源码分析]

    目录 前言 重要接口和类介绍 源码分析 编码自定义的ViewResolver 总结 参考资料 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门bl ...

  9. Cocoa编程中视图控制器与视图类详解

    iPhone编程规则是:一个窗口,多个视图.UIView是iPhone屏幕上很多控件的基础类.每个iPhone用户界面都是由显示在UIWindow(这其实也是个特殊的UIView)内的众多UIView ...

  10. Android 自定义View修炼-Android开发之自定义View开发及实例详解

    在开发Android应用的过程中,难免需要自定义View,其实自定义View不难,只要了解原理,实现起来就没有那么难. 其主要原理就是继承View,重写构造方法.onDraw,(onMeasure)等 ...

随机推荐

  1. rpc框架实现(持续更新)

    网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,rpc基于长连接的远程过程调用应用而生. 一:A服务调用B服务,整个调用过程,主要经历如下几个步骤:(摘自 ...

  2. 微信小程序 获取位置、移动选点、逆地址解析

    WGS- 地心坐标系,即GPS原始坐标体系.在中国,任何一个地图产品都不允许使用GPS坐标,据说是为了保密.GoogleEarth及GPS芯片使用. .GCJ-02火星坐标系,国测局02年发布的坐标体 ...

  3. 图解ActiveMQ virtual topic

    http://activemq.apache.org/virtual-destinations.html 普通的 topic 是发布/订阅模式:消息会被广播发送给所有的订阅者,订阅者拿到的是全部消息, ...

  4. Linux安装配置NFS教程(CentOS 6.5)

    一.服务端安装nfs 1.1安装 yum install -y rpcbind yum install -y nfs-utils 1.2配置nfs共享目录 这里以/nfs目录为例 mkdir /nfs ...

  5. Swagger 路径过滤 -PreSerializeFilters

    Swagger 默认显示所有api, 如果要做路径过滤,可以这样做. //过滤,只显示部分api app.UseSwagger(c=> { c.PreSerializeFilters.Add(( ...

  6. linux查看在线用户并踢出用户

    linux查看在线用户并踢出用户 1.查看在线用户 w [root@dbserver01 ~]# w 16:45:04 up 16 days, 8:48, 1 user, load average: ...

  7. Cyclic Components CodeForces - 977E(DFS)

    Cyclic Components CodeForces - 977E You are given an undirected graph consisting of nn vertices and  ...

  8. day03_python_1124

    01 昨日内容回顾 while 条件: 循环体 如何终止循环: 1,改变条件. 2,break. 3,exit() quit() 不推荐. 关键字: break continue while else ...

  9. chrome console 阻止 Navigated to

    阻止如图 chrome 如图信息

  10. BootStrap字体图标不显示、下拉菜单不显示

    在W3CSchool学习BootStrap教程时遇到的问题…… 1.字体图标不能显示 上面是正常显示的样子,不能正常显示,因为缺少下面的字体图标样式文件 (1)在下载的Bootstrap包中将font ...