精华内容
下载资源
问答
  • 1.12 创建视图变换

    2018-09-21 15:05:47
    应用程序需要动态变换视图的外观,从而为视图添加一些视觉效果,例如视觉变换效果。
  • 视图变换

    2021-01-27 10:22:39
    视图变换 我们可以这样来描述视图变换的任务:将虚拟世界中以(x,y,z)为坐标的物体变换到 以一个个像素位置(x,y) 来表示的屏幕坐标系之中(2维),这确实是一个较为复杂的过程,但是整个过程可以被细分为如下几个步骤...

    视图变换

    我们可以这样来描述视图变换的任务:将虚拟世界中以(x,y,z)为坐标的物体变换到 以一个个像素位置(x,y) 来表示的屏幕坐标系之中(2维),这确实是一个较为复杂的过程,但是整个过程可以被细分为如下几个步骤:

    (1) 模型变换(modeling tranformation):这一步的目的是将虚拟世界中或者更具体点,游戏场景中的物体调整至他们应该在的位置。

    即:找一个好地方,把所有人聚集起来。

    (2) 摄像机变换(camera tranformation):在游戏中我们真正在乎的是摄像机(或者说眼睛)所看到的东西,也就是需要得到物体与摄像机的相对位置。

    即:找一个好的角度去摆放相机位置

    (3) 投影变换(projection tranformation):根据摄像机变换得到了所有可视范围内的物体对于摄像机的相对位置坐标(x,y,z)之后,便是根据是平行投影或是透视投影,将三维空间投影至标准二维平面([-1,1]^2)之上 (tips:这里的z并没有丢掉,为了之后的遮挡关系检测)。

    即:Cheese!拍照(3D->2D),得到立方体[-1,1]

    (4) 视口变换(viewport transformation):将处于标准平面映射到屏幕分辨率范围之内,即[-1,1]^2[公式][0,width]*[0,height], 其中width和height指屏幕分辨率大小。

    即:生成照片的过程,立方体[-1,1] ->屏幕[0,width] x [0,height]

    有了如上4个步骤之后,整个视图变换的过程就变的清晰了起来,如下给出一个具体例子帮助理解:
    在这里插入图片描述
    参考: link.

    展开全文
  • 视图变换 从大局上考虑,在应用任何其他模型变换之前,必须先应用视图变换。-- 《OpenGL 超级宝典 第5版》 视图变换是应用到场景中的第一种变换,通过物体/观察者在Z轴上的移动,确定场景中利于观察的位置。 默认...

    视图变换

    从大局上考虑,在应用任何其他模型变换之前,必须先应用视图变换。-- 《OpenGL 超级宝典 第5版》

    视图变换是应用到场景中的第一种变换,通过物体/观察者在Z轴上的移动,确定场景中利于观察的位置。

    默认情况下,透视投影中的观察者位置处于原点(0,0,0),并沿着z轴负方向看向屏幕里面,一般通过moveForward方法来调整观察者位置,moveForward默认的朝向是-z轴,所以向屏幕里面移动传正数值,向屏幕外即+z轴,需要传负数值。

    模型变换

    模型变换不无外乎就是平移、旋转和缩放。在iOS核心动画中的仿射变换中的底层实现就是模型变换。

    平移(m3dTranslationMatrix44)

    物体沿着3D笛卡尔坐标系的某个坐标轴移动。
    在这里插入图片描述

    void m3dTranslationMatrix44(M3DMatrix44f m, floata x, float y, float z);
    参数:
    参数1:结果矩阵,平移之后的结果矩阵
    参数2:沿着X轴移动多少,正数\负数
    参数3:沿着Y轴移动多少,正数\负数
    参数4:沿着Z轴移动多少,正数\负数

    旋转(m3dRotationMatrix44)

    对象围绕着一条坐标轴进行旋转
    在这里插入图片描述
    m3dRotationMatrix44(M3DMatrix44f m, float angle, float x, float y, float z);
    参数1:结果矩阵,旋转之后的结果矩阵
    参数2:旋转多少弧度
    参数3:是否围绕X轴旋转,是(1),不是(0)
    参数4:是否围绕Y轴旋转,是(1),不是(0)
    参数5:是否围绕Z轴旋转,是(1),不是(0)

    缩放(m3dScaleMatrix44)

    对象的大小进行了指定数量的放大或缩小。缩放可以是不均匀的,即不同维度可以进行不同程度的缩放。
    在这里插入图片描述
    void m3dScaleMatrix44(M3DMatrix44f m, float xScale, float yScale, float zScale)
    参数1:结果矩阵
    参数2:围绕X轴放大\缩小;放大x>1,缩小:0.5f
    参数3:围绕Y轴放大\缩小;放大x>1,缩小:0.5f
    参数4:围绕Z轴放大\缩小;放大x>1,缩小:0.5f

    综合变换(m3dMatrixMultiply44)

    void m3dMatrixMultiply44(M3DMatrix44f product, const M3DMatrix44f a, const M3DMatrix44f b);
    参数1:结果矩阵
    参数2:先变换的矩阵
    参数3:后变换的矩阵

    展开全文
  • 视图变换View/Camera transformation 投影变换Projection transformation Orthographic projection Perspective projection

    前言

    我们知道我们在屏幕上看见的画面其实都是二维的,那么是怎么做到把三维空间中所展示的内容显示到一个二维空间上呢?这里就需要我们的视图变换以及投影变换来实现了。

    整个过程我们可以理解为生活中拍照片,例如我们想去一个摄影棚拍全家福,我们可以分如下三步:

    1. 首先我们可以先决定好站位问题,谁在前谁在后等等,这步操作就是我们前面学习的模型变换(Model Transformation)
    2. 然后我们得全家移步到摄影棚拍(即把摄影棚的相机当做坐标原点),然后还要摆正相机(相机自身的旋转),把相机镜头朝向我们(相机的朝向)以及相机要和我们保持一定的距离(与相机的距离)才能拍出好的照片。这步操作就是我们本章要学习的视图变换(View/Camera Transformation)
    3. 最后就是按下相机的快门,拍出照片(照片就是二维的),这步操作也是我们本章要学习的投影变换(Projection Transformation)

    上诉这些变换操作就是我们常说的MVP变换,它们对应的矩阵即MVP矩阵

     

    视图变换(View/Camera transformation)

    平时大家一定也都拍过照片,想要拍出想要的照片,我们肯定要选好拍照的位置,对准要拍摄的物体,以及拿好相机(因为可以横着拍,竖着拍或者斜着拍)。在图形学中,也是一样的道理,我们首先需要定义摄像机如下几个属性:

    • 位置(Position):即Camera的坐标,我们可以标记为 \vec{p}
    • 朝向(LookAt):即Camera往哪看,其实也就是相机的-z轴向量,我们可以标记为 \vec{l} (单位向量)
    • Y轴的朝向(UpDirection):即Camera的y轴向量,我们可以标记为 \vec{u} (单位向量)。例如若Camera的y轴和世界坐标系的y轴平行,则看见的画面是正的,若Camera的y轴绕z轴旋转,则看见的画面也会跟着旋转。

    注:我们约定在右手坐标系中,Camera的LookAt方向为自身的-z轴方向(例如3DMax中的Camera),而在左手坐标系中LookAt方向为自身的z轴方向(例如Unity中的Camera)。

    通过相对运动我们知道,如果摄像机所观察的物体和摄像机一起运动,那么摄像机所观察到的画面是保持不变的,例如下图中,两个摄像机的位置朝向都不相同,看见的画面确是一样的。

          

    那么假如有个变换矩阵 V ,使我们的摄像机变换为位置在世界坐标原点,看向-z方向,摄像机的y轴即为世界坐标y轴。那么摄像机所观察的物体同样使用矩阵 V 进行变换,即可保持所观察到的画面不变。这样的操作就是我们所谓的视图变换,变换矩阵 V 即为视图变换矩阵。至于为什么要执行这样的一步操作,是为了使后续在执行投影变换时,简化计算。

    接下来我们来看看矩阵 V 的值应该如何计算,根据前面的描述我们可以把视图变换拆分为如下几步:

    1. 通过平移变换,将Camera移到原点位置,即使 \vec{p} 变为 (0,0,0)
    2. 通过旋转变换,使Camera看向-z方向且自身的y轴与世界坐标的y轴重叠,即使 \vec{l} 变为 (0,0,-1), \vec{u} 变为 (0,1,0)

    通过复合变换我们可知,只需要把上面两部所对应的矩阵相乘得到的结果及时我们的视图变化矩阵 V 的值。


    首先是平移变换的矩阵,这个很简单,设 \vec{p} = (p_x,p_y,p_z),我们只需要移动 (-p_x,-p_y,-p_z) 即可将摄像机移动到原点,对应矩阵(设为 M)即为:

     M=\begin{bmatrix} 1 &0 &0 &-p_x \\ 0 &1 &0 & -p_y\\ 0 &0 & 1 & -p_z\\ 0 &0 & 0 &1 \end{bmatrix}


    移动到原点后,我们要通过旋转,使 \vec{l} = (l_x,l_y,l_z) 变为  (0,0,-1) ,\vec{u}=(u_x,u_y,u_z) 变为 (0,1,0)。这一步我们有点无从下手,因为我们之前讨论旋转矩阵时都是绕什么什么轴旋转多少多少度,而在这里我们并不知道应该绕什么轴旋转多少度。

    那么应该如何解决呢?这里有一个逆向思维,即我们不知道如何将 \vec{l} = (l_x,l_y,l_z) 变为  (0,0,-1) ,\vec{u}=(u_x,u_y,u_z) 变为 (0,1,0),但是我们能够知道如何将 (0,0,-1) 变为  \vec{l} = (l_x,l_y,l_z),(0,1,0) 变为 \vec{u}=(u_x,u_y,u_z),也就是上诉旋转的逆变换,我们假设我们原先要求的矩阵为 R ,那么它的逆变换矩阵即为 R^{-1}

    因为通过前面的知识我们知道,旋转矩阵中的值即为x,y,z三个轴的单位向量旋转后的值。在这里 (0,1,0) 变为 \vec{u}=(u_x,u_y,u_z) ,(0,0,1) 变为了 -\vec{l} = (-l_x,-l_y,-l_z),因为\vec{l}代表的是摄像机自身的-z轴方向,\vec{u}代表的是摄像机自身的y轴方向,根据叉乘的定义可得摄像机自身的x轴方向即为 \vec{l} \times \vec{u},即 (1,0,0) 变为 \vec{l} \times \vec{u}。那么我们就可得:

    R^{-1}=\begin{bmatrix} (\vec{l}\times\vec{u})_x & u_x & -l_x & 0\\ (\vec{l}\times\vec{u})_y & u_y & -l_y & 0\\ (\vec{l}\times\vec{u})_z & u_z & -l_z & 0\\ 0 & 0 & 0 & 1 \end{bmatrix}

    同时又因为我们的旋转矩阵为正交矩阵,其逆矩阵即等于转置矩阵,R^{-1}=R^{T},因此R的值即为R^{-1}的转置,可得:

    R=\begin{bmatrix} (\vec{l}\times\vec{u})_x & (\vec{l}\times\vec{u})_y & (\vec{l}\times\vec{u})_z & 0\\ u_x & u_y & u_z & 0\\ -l_x & -l_y & -l_z & 0\\ 0 & 0 & 0 & 1 \end{bmatrix}


    所以即可求得视图变化矩阵 V 的值,即为上面两个矩阵相乘:

    V=RM=\begin{bmatrix} (\vec{l}\times\vec{u})_x & (\vec{l}\times\vec{u})_y & (\vec{l}\times\vec{u})_z &0\\ u_x & u_y & u_z &0\\ -l_x & -l_y & -l_z &0\\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 &0 &0 &-p_x \\ 0 &1 &0 & -p_y\\ 0 &0 & 1 & -p_z\\ 0 &0 & 0 &1 \end{bmatrix}=\begin{bmatrix} (\vec{l}\times\vec{u})_x & (\vec{l}\times\vec{u})_y & (\vec{l}\times\vec{u})_z &-p_x(\vec{l}\times\vec{u})_x-p_y(\vec{l}\times\vec{u})_y-p_z(\vec{l}\times\vec{u})_z\\ u_x & u_y & u_z &-p_xu_x-p_yu_y-p_zu_z\\ -l_x & -l_y & -l_z &p_xl_x+p_yl_y+p_zl_z\\ 0 & 0 & 0 & 1 \end{bmatrix}

     

    投影变换(Projection transformation)

    摄像机对好要拍摄的物体后,就差最后按下快门变成照片这一步了,而这一步也就是我们的投影变换,即从三维变成二维。在图形学中,投影变换分为如下两种,分别为正交投影和透视投影。

    正交投影(Orthographic projection)

    正交投影示意图如下:

     

    可以发现,正交投影没有近大远小的现象,视线是互相平行的,类似于平行光照,这种投影更多的用于工程图。图中我们还可发现有一个Near clip plane和一个Far clip plane,它们分别代表该摄像机能看见的最近的距离以及最远距离,即摄像机只能看见两个平面之间的物体。在正交投影中,Near clip plane的大小等于Far clip plane,能被摄像机拍摄到的空间即为一个长方体。

    由于已经进行过了视图变换,即摄像机在原点,看向-z轴方向,摄像机的y轴与世界坐标y轴重叠。因此我们的所拍摄的空间也能够确定下来,如下图:

    该空间的宽度即为L点和R点的距离,设L点和R点的x轴坐标分别为 l 和 r ,高度即为T点和B点的距离,设T点和B点的y轴坐标分别为 t 和 b ,长度即为N点和F点的距离,设N点和F点的z轴坐标分别为 n 和 f 。可得:r > l 和 t > b,但是 f < n,因为是看向-z方向,所以更远的位置z的值越小。同时还要注意,虽然摄像机看向-z轴方向,但是N点并不一定是Near clip plane的中心点,因此 r 和 l 的绝对值不一定相等, t 和 b 的绝对值也不一定相等。

    从图中我们也可以发现当从三维变为二维时,空间内的物体的x轴和y轴位置不会发生变换,而是在z轴方向进行了压缩。我们可以把空间中的物体的z轴都设置为0,那么空间中的所有物体都会被压缩到xy平面上,也就是变为二维的了。

    然而更规范化的做法是将上诉摄像机所观测的空间(即长方体,设为 S )变换成一个标准立方体canonical cube)。何为标准立方体?即以原点为中心,边长为2的立方体,也就是立方形在x,y,z三个轴上都是从-1到1。

    整个变换过程就是我们的正交投影变换,其对应矩阵即为正交投影变换矩阵。该变换我们可以分为如下两步(这也体现了视图变换的重要性,使得我们做投影变换变得很简单):

    1. 平移变换,将长方体S平移到原点。
    2. 缩放变换,将长方体S的长宽高缩放到2

    同样的,我们来看看这两个变换的矩阵:


    首先是移到原点的平移变换,即把长方体S的中心点移动到原点,那么我们就要求出长方体中心点的坐标。根据前面的数据,我们可以知道中心点x的坐标即为 \frac{r+l}{2},中心点y的坐标即为 \frac{t+b}{2},中心点x的坐标即为 \frac{n+f}{2},因此平移矩阵(设为 M)即为:

    M=\begin{bmatrix} 1 &0 &0 & -\frac{r+l}{2}\\ 0 &1 &0 & -\frac{t+b}{2}\\ 0 &0 &1 & -\frac{n+f}{2}\\ 0 &0 &0 &1 \end{bmatrix}


    接着是将长方体S变为边长为2的立方体的缩放变换,那么我们只需要知道长方体的长宽高即可。我们设x轴方向的为长度,即为 r-l ,y轴方向的为高度,即为 t-b ,z轴方向的为宽度,即为 n-f 。

    所以缩放矩阵(设为 S)即为:

    S=\begin{bmatrix} \frac{2}{r-l} & 0 &0 &0 \\ 0& \frac{2}{t-b} &0 &0 \\ 0& 0 & \frac{2}{n-f} &0 \\ 0&0 & 0 & 1 \end{bmatrix}


    因此可以得出最终的正交投影变换矩阵(设为 P_{ortho})为:

    P_{ortho}=SM=\begin{bmatrix} \frac{2}{r-l} & 0 &0 &0 \\ 0& \frac{2}{t-b} &0 &0 \\ 0& 0 & \frac{2}{n-f} &0 \\ 0&0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 &0 &0 & -\frac{r+l}{2}\\ 0 &1 &0 & -\frac{t+b}{2}\\ 0 &0 &1 & -\frac{n+f}{2}\\ 0 &0 &0 &1 \end{bmatrix}= \begin{bmatrix} \frac{2}{r-l} &0 &0 & -\frac{r+l}{r-l}\\ 0 &\frac{2}{t-b} &0 & -\frac{t+b}{t-b}\\ 0 &0 &\frac{2}{n-f} & -\frac{n+f}{n-f}\\ 0 &0 &0 &1 \end{bmatrix}

    注:该变化会导致物体的被拉伸(因为长方体变成了立方体),在后续的视口变换过程中会再对此进行处理。

     

    透视投影(Perspective projection)

    与正交投影不同的是,透视投影会有近大远小的现象,类似于我们的人眼或者照相机拍照,这种投影更具有真实感,被广泛使用。从图中我们可以看出Far clip plane的面积要大于Near clip plane,因此我们摄像机所观测的区域不再是一个长方体,而是变成了一个四棱台(即四棱锥去掉顶部),也就是我们常说的视锥体(Frustum)。

    我们来看下在视图变换后,透视投影在坐标系中的样子,如下图:

    通过前面我们知道,投影变换是把相机观测的空间压缩成一个标准立方体,对于这个视锥体我们应该如何压缩呢?有个思路是这样的:

    1. 我们先通过某种变换把这个视锥体压缩成一个长方体
    2. 再把长方体移到原点上压缩成标准立方体,即等于执行正交投影变换

    那么我们只需要计算出第一步的变换矩阵(设为 T),然后将它乘以正交投影变换矩阵,即可得到我们的透视投影变换矩阵(设为 P_{persp})了。


    要使视锥体变为长方体,首先我们要使T1T2变为y=T1N的直线,B1B2变为y=-B1N的直线,L1L2变为x=-L1N的直线,R1R2变为x=R1N的直线。

    首先我们来看看如何使T1T2变为y=T1N的直线,做这一步前我们可以从x轴方向看向yz平面,来观察这个视锥体,方便理解。

    设N点的z值为 n,F点的z值为 f ,(f < n < 0)。

    通过图中我们可以发现,\bigtriangleup T_1ON 和 \bigtriangleup T_2OF 是相似三角形,可得:\frac{T_1N}{n}=\frac{T_2F}{f} ,即 T_2F \frac{n}{f} = T_1N 。扩展开来可得在T1T2直线上的任意一点,设(x,y,z),其y值只需乘以 \frac{n}{z} 即可与T1点的Y值相等,这样直线T1T2即变为一条y=T1N水平线,B1B2也是同理。

    对于L1L2和R1R2,我们只需要从y轴方向观察xz平面即可,同样是乘以 \frac{n}{z} 即可。

    因此对应视锥体里的任意一点 (x,y,z),我们只需要将其x和y的值乘以 \frac{n}{z} 即可使该视锥体变为长方体。但是z值是否会发生变换我们暂时还不知道,先当做未知来处理(看着似乎不会变换,但实际上并不是这样,后面会在解释)。

    关于上面的结论,我们可以得到如下一个变换矩阵:

    \begin{bmatrix} \frac{n}{z} & 0 & 0\\ 0 & \frac{n}{z} & 0\\ ? & ? & ? \end{bmatrix}\begin{bmatrix} x\\ y\\ z \end{bmatrix}=\begin{bmatrix} x\frac{n}{z}\\ y\frac{n}{z}\\ ? \end{bmatrix}

    这个矩阵有个问题,那就是矩阵中的z是一个变量,导致该矩阵并不是一个常量

    因此我们这里需要引入齐次坐标的概念,设我们有个常量k,通过其次坐标我们可以知道,(x,y,z,1) 是等价于 (kx,ky,kz,k) 的,那么可以得知:\begin{bmatrix} x\frac{n}{z}\\ y\frac{n}{z}\\ ? \\1 \end{bmatrix} =\begin{bmatrix} xn\\ yn\\ ? \\z \end{bmatrix}

    因此我们可以把上面的矩阵修改为:

    \begin{bmatrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ ? & ? & ? & ? \\0&0&1&0\end{bmatrix}\begin{bmatrix} x\\ y\\ z\\1\end{bmatrix}=\begin{bmatrix} xn\\ yn\\ ? \\z \end{bmatrix}

    这样我们矩阵中的变量z就被消灭掉了。


    接下来我们要看看z值的变换,从图中我们可得知的信息为变为长方体后:

    1. Near clip plane上的任意点,设为(i,j,n),它的z值不变依旧为 n。
    2. Far clip plane上的任意点,设为(k,l,f),它的z值不变依旧为 f。

    可得:

    \left\{\begin{matrix} \begin{bmatrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ ? & ? & ? & ? \\0&0&1&0\end{bmatrix}\begin{bmatrix} i\\ j\\ n\\1\end{bmatrix}=\begin{bmatrix} in\\ jn\\ n^2 \\n \end{bmatrix}\\ \\ \\ \begin{bmatrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ ? & ? & ? & ? \\0&0&1&0\end{bmatrix}\begin{bmatrix} k\\ l\\ f\\1\end{bmatrix}=\begin{bmatrix} kf\\ lf\\ f^2 \\f \end{bmatrix} \end{matrix}\right.

    设我们矩阵中的四个未知数分别为 A,B,C,D,可得:

    \left\{\begin{matrix} Ai+Bj+Cn+D=n^2\\ Ak+Bl+Cf+D=f^2 \end{matrix}\right.

    可知 A=B=0,简化得:

    \left\{\begin{matrix} Cn+D=n^2\\ Cf+D=f^2 \end{matrix}\right.

    即可算出,C=n+f,D=-nf,因此视锥体压缩为长方体的矩阵为:

    T=\begin{bmatrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ 0 & 0 & n+f & -nf \\0&0&1&0\end{bmatrix}

    因此也可以知道在该变换过程中,任意点的z的值可能是会发生变化的。举个例子,视锥体的中心点 (0,0,\frac{n+f}{2}) 变换后为:

    \begin{bmatrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ 0 & 0 & n+f & -nf \\0&0&1&0\end{bmatrix}\begin{bmatrix} 0\\ 0\\ \frac{n+f}{2}\\ 1 \end{bmatrix} = \begin{bmatrix} 0\\ 0\\ \frac{(n+f)^2}{2}-nf\\ \frac{n+f}{2} \end{bmatrix}= \begin{bmatrix} 0\\ 0\\ \frac{n^2+f^2}{n+f}\\ 1 \end{bmatrix}

    我们来比下大小:

    \frac{n+f}{2}-\frac{n^2+f^2}{n+f}=\frac{n^2+f^2+2nf-2n^2-2f^2}{2(n+f)}=\frac{-(n-f)^2}{2(n+f)}

    由于f < n < 0,所以 -(n-f)^2<0 ,2(n+f) < 0,可得(负数除以负数为一个正数)

    \frac{n+f}{2}-\frac{n^2+f^2}{n+f}>0

    即视锥体的中心点在变换后离摄像机更远了。


    变成长方体后,只需在执行一次正交投影变换即可,因此我们的透视投影变换矩阵为:

    P_{persp}=P_{ortho}T=\begin{bmatrix} \frac{2}{r-l} &0 &0 & -\frac{r+l}{r-l}\\ 0 &\frac{2}{t-b} &0 & -\frac{t+b}{t-b}\\ 0 &0 &\frac{2}{n-f} & -\frac{n+f}{n-f}\\ 0 &0 &0 &1 \end{bmatrix}\begin{bmatrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ 0 & 0 & n+f & -nf \\0&0&1&0\end{bmatrix} = \begin{bmatrix} \frac{2n}{r-l} &0 & -\frac{r+l}{r-l} & 0 \\ 0 &\frac{2n}{t-b} & -\frac{t+b}{t-b} &0 \\ 0 &0 &\frac{n+f}{n-f} & \frac{-2nf}{n-f} \\ 0 &0 &1 &0 \end{bmatrix}

    注:在有些文章里可以看见 P_{persp} 的第三列元素和本文的正好是取负的关系,那是因为他们在计算时,把 n 和 f 当做正数使用,即 N 点和 F 点的z轴坐标为 -n 和 -f 。

     

    使用FOV和Aspect ratio表示

    在上图中 \angle T_1OB_1 我们称之为 Field of View (for Y / for Vertical),也就是常说的FOV。自然而然 \angle L_1OR_1 自然是x轴或者是水平方向的FOV,我们只需要知道其中一个即可。我们设 \angle T_1OB_1=\theta 。

    L1R1的长度(即为宽,设值为w)与T1B1的长度(即为高,设值为h)比例我们称之为宽高比(Aspect ratio),我们假设为该值为 a,即 a=\frac{w}{h} 。


    此外我们的视锥体应为对称视锥体,即N点为Near clip plane的中心点,即可得:

    \left\{\begin{matrix} r=-l\\ t=-b\\w=r-l\\ h=t-b \end{matrix}\right.

    带入 P_{persp} 中,得:

    P_{persp}=\begin{bmatrix} \frac{2n}{w} &0 & 0 & 0 \\ 0 &\frac{2n}{h} &0 &0 \\ 0 &0 &\frac{n+f}{n-f} & \frac{-2nf}{n-f} \\ 0 &0 &1 &0 \end{bmatrix}

    通过上面yz平面的侧面图,我们可以发现:\tan\frac{\theta}{2} = \frac{h}{2n} ,即 \frac{2n}{h} = \frac{1}{\tan\frac{\theta}{2}} 。

    又因为 w=ah,所以 \frac{2n}{w}=\frac{2n}{ah} = \frac{1}{a \tan\frac{\theta}{2}} 。

    所以可得,FOV为 \theta ,宽高比为 a 时,透视投影矩阵为:

    P_{persp}=\begin{bmatrix} \frac{1}{a \tan\frac{\theta}{2}} &0 & 0 & 0 \\ 0 &\frac{1}{\tan\frac{\theta}{2}} &0 &0 \\ 0 &0 &\frac{n+f}{n-f} & \frac{-2nf}{n-f} \\ 0 &0 &1 &0 \end{bmatrix}

    同时知道了FOV和宽高比,我们就可以计算出之前的 r,l,t,b 这些值。

    展开全文
  • 模型变换 Void glTranslate(TYPE x,TYPE y,...2 视图变换 Void gluLookat(GLdouble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble centerz,GLdouble upx,GLdouble upy,GLdouble upz)
  • 视图变换的整个过程的主要目的: 为了把在虚拟世界中的物体的三维坐标转换到屏幕二维坐标系中的对应的位置上。 视图变换具体分为下面四个步骤: 1.模型变换:将准备拍摄的对象移动到它在虚拟场景中应该存在的位置 2....


    视图变换
    视图变换的整个过程的主要目的:
    为了把在虚拟世界中的物体的三维坐标转换到屏幕二维坐标系中的对应的位置上。

    视图变换具体分为下面四个步骤:
    1.模型变换:将准备拍摄的对象移动到它在虚拟场景中应该存在的位置
    2.摄像机变换:将摄像机(玩家观察虚拟世界的视角)移动到准备拍摄的位置
    3.投影变换:把当前摄像机视角之内的物体的与摄像机的相对三维坐标投影到标准二维平面上
    4.视口变换:把标准二维坐标对应到屏幕坐标上

    一.模型变换

    模型变换其实就是把物体经过各种矩阵变换之后移动到它在虚拟世界中的具体的位置。
    矩阵变换详见:https://blog.csdn.net/Immaturecld/article/details/115592

    二.摄像机变换

    首先,我们先来定义三个概念:
    相机的位置(eye position):e
    相机的朝向(gaze position):g
    相机的相对正上方向(up direction):t

    如果我们想让我们相机视角里的物体在我们相机移动的时候保持不变,我们就应该让视角里的物体和我们的相机进行一样的移动,也就是相对静止。为了操作简化,我们把相机的坐标轴和标准三维坐标轴进行移动重合。

    在这里插入图片描述
    如图,我们把上图中摄像机的坐标系与xyz标准坐标系重合,需要两步:
    1.把相机的位置e移动到xyz坐标系的原点上去
    2.经过旋转矩阵的变换,让两个坐标系重合

    平移矩阵
    在这里插入图片描述
    旋转矩阵
    在这里插入图片描述

    三.投影变换

    1.正交投影

    正交投影是一种坐标和坐标之间的相对位置不会发生变化的投影,最大的特点就是,平行的线段,在经过正交投影之后一定还是平行的。物体原先的三维坐标的x、y坐标在正交投影之后就是相应的二维坐标,只不过一般会按照比例缩放到-1~1之间(为了简化后续计算),而原先的z坐标不要舍弃掉,可以帮助我们判断三维坐标中点的前后关系(也就是投影之后是否可视)。
    在这里插入图片描述
    在这里插入图片描述
    先把物体中心移动到原点,然后再缩放

    2.透视投影

    透视投影是更接近与人的观感的一种投影,遵守近大远小的规则
    在这里插入图片描述
    上图中的两条铁轨虽然平行的,但是在人的视角中确实有交点的,这就是透视投影

    在这里插入图片描述
    左边是透视投影,右边是正交投影

    透视投影的步骤:
    1.在远处平面上的点,按一定规则进行挤压
    2.再进行一次正交投影

    在这里插入图片描述
    挤压的具体情况,就类似于上面的相似三角形,根据相似三角形可以计算出挤压的比例

    在这里插入图片描述
    上图就是x,y的挤压结果,我们希望找到一个4*4的变换矩阵可以完成上图的变换

    在这里插入图片描述
    这个矩阵的前两行很容易可以算出来,但是我们不知道第三行是什么样的
    但我们根据点在近平面(z=n)或者远平面(z=f)上怎么变换z都是不变的(也就是z和x,y没有关系)
    在这里插入图片描述

    所以我们设第三行是(0,0,A,B)
    在这里插入图片描述
    远平面的中心点(0,0,f),挤压之后xyz都不变
    在这里插入图片描述
    根据进平面和远平面我们分别得到了上面的两个式子,解出:
    A=n+f
    B=-nf

    那么最后的变换矩阵也就得到了:

    在这里插入图片描述
    然后再压缩到-1~1的空间中,透视投影也就完成了

    四.视口变换

    把目前再标准二位坐标上的投影,转换到屏幕坐标([0,width]*[0,height])上,变换矩阵如下:
    在这里插入图片描述

    展开全文
  • 实验6 OpenGL模型视图变换

    千次阅读 2020-10-21 15:44:10
    理解掌握OpenGL程序的模型视图变换。 掌握OpenGL三维图形显示与观察的原理与实现。 2.实验内容: (1)阅读教材有关三维图形变换原理,运行示范实验代码,掌握OPENGL程序三维图形变换的方法; (2)阅读实验原理,运行...
  • 坐在第一排划拉瑟图 ,老师突然布置了个作业:推导mv变换的矩阵。常言道上山容易下山难之用轮一时爽,造轮火葬场 ,这可把????急坏了,周末就嗯搁这埋头一顿推。推了挺久的 今天记录一下过程。 mv矩阵的目的是将世界...
  • 什么是View Transform ...好了,来分析一下,上面的第一步就相当于世界变换了,将一个模型置于一个公认的坐标系中,这里所谓的公认,也就是大家都遵守的,目的是保证待拍摄的物体和照相机在同一个坐标系。第...
  • 计算机图形学基础 视图变换:MVP变换、视口变换
  • 1、 模型变换和视图变换 从“相对移动”的观点来看,改变观察点的位置与方向和改变物体本身的位置与方向具有等效性。在OpenGL中,实现这两种功能甚至使用的是同样的函数。 由于模型和视图的变换都通过矩阵运算来...
  • 视图变换,是指变换照相机的位置,角度。  模型变换,是指变换被照物体的位置,角度。 这两个变换,都会影响最终图形中,物体的位置,角度。而这两个变换,可以达到相同的效果。比如,你想要一个倒着的水杯图形,...
  • 实验5 OpenGL模型视图变换

    千次阅读 2017-04-17 10:33:04
    1.实验目的:理解掌握OpenGL程序的模型视图变换。2.实验内容:(1)阅读实验原理,运行示范实验代码,理解掌握OpenGL程序的模型视图变换;(2)根据示范代码,尝试完成实验作业;3.实验原理:我们生活在一个三维...
  • 实验5 OpenGL模型视图变换 实验目的 理解掌握OpenGL程序的模型视图变换 2.实验内容 1阅读实验原理运行示范实验代码理解掌握OpenGL程序的模型视图变换 2根据示范代码尝试完成实验作业 3.实验原理 在OpenGL程序中视图...
  •  OpenGL采用的是相机模型,就是把视图变换操作类比为使用照相机拍摄照片的过程,具体步骤如下(这里和红宝书有一些改变): 将准备拍摄的对象移动到场景中指定位置。(模型变换,Model Transform)将相机移动到...
  • OpenGL取景变换(视图变换)矩阵推导

    千次阅读 2017-02-13 15:11:12
    OpenGL取景变换(视图变换)矩阵推导标签(空格分隔): OpenGL VR 游戏开发前言关于取景变换(视图变换)矩阵的推导本人查过许多资料, 包过关于openGL的和数学方面, 数学方面的资料很严谨, 推导过程环环相扣, 但是数书...
  • 学习目标 1、能够建立 相机坐标系 2、理解不同投影方式的特点 3、能建立所需的投影矩阵并用openGL实现 4、描述clipping的操作和函数 图像的产生过程 ...这一步相当于视图变换,这时候的坐标就是came...
  • 视图变换)2、移动或者旋转它,当然了,如果它只是计算机里面的物体,我们还可以放大或缩小它(物体运动,让人看它的不同部分)。(模型变换)3、如果把物体画下来,我们可以选择:是否需要一种“近大远小”的透视...
  • 视图变换(Viewing Transformation) 我们可以这样来描述视图变换的任务:将虚拟世界中以(x,y,z)为坐标的物体变换到 以一个个像素位置(x,y) 来表示的屏幕坐标系之中(2维),这确实是一个较为复杂的过程,但是整个...
  • OpenGL视图变换及gluLookAt

    千次阅读 2018-02-10 08:26:23
    视图变换,即相机变换,其作用是把相机放在指定位置并使其对准场景。该变换是针对相机的变换,不会影响到模型。视图变换决定了相机的位置与方向,因此可以通过视图变换来改变相机位置与方向,从而达到从各个不同的...
  • OpenGL的视图变换

    2015-04-08 20:10:46
    OpenGL的视图变换 OpenGL 中场景进行变换,要经历一些过程:视图变换 à 模型变换 à 投影变换,然后到了窗口坐标。这几个变换开始的时候把我搞很混,这几天整理一下。  一般书上把这几个变换用照相机类比...
  • 12.创建视图变换

    2018-09-18 09:09:14
    应用程序需要动态变换视图的外观,从而为视图添加一些视觉效果,例如视觉变换效果。 ##12.2 解决方案 (API Level 1) Viewgroup中的静态变换API提供了应用视觉效果的简单方法,例如旋转、缩放、透明度变化,而且...
  • 1,OpenGL渲染3D物体到屏幕上的过程其实类似我们平时用照相机拍照的过程,这个步骤大致如下:一,把照相机固定在三脚架并让它对准场景(视图变换)二,把场景中的物体调整摆放好(模型变换)三,选择照相机的镜头,并...
  • 视图变换小结

    2015-04-26 00:12:43
    视图变换小结
  • 进行模型和视图变换,主要涉及到三个函数: glTranslate*,把当前矩阵和一个表示移动物体的矩阵相乘。三个参数分别表示了在三个坐标上的位移值。 glRotate*,把当前矩阵和一个表示旋转物体的矩阵相乘。物体将绕着...
  • 模型变换和视图变换有关函数的使用方法和说明。透视原理解释说明,源程序,例程,运行效果。
  • 计算机图形学基础 实验五 视图变换 1.实验目的: 理解掌握OpenGL程序的模型视图变换。 2.实验内容: (1)阅读实验原理,运行示范实验代码,理解掌握OpenGL程序的模型视图变换; (2)根据示范代码,尝试完成实验...
  • 移动GPU中模型视图变换单元的可重构设计.pdf
  • 1)把相机固定在三角架上,并让它对准场景(视图变换) 2)对场景安排,使得各个物体在招片中的位置是我们所希望的(模型变换) 3)选择照相机的镜头,并调整放大的倍数(投影变换) 4)确定最终照片的大小,放大...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,729
精华内容 19,091
关键字:

视图变换