基本知识

右手坐标系

右手手掌弯曲,手指方向由正X轴指向正Y轴,如果这时Z轴正方向与大拇指方向保持一致,坐标系为右手坐标系,否则为左手坐标系。

向量叉乘的方向

向量(1,0,0)与向量(0,1,0)叉乘的结果可以由公式计算得到为(0,0,1),在数值上它是始终不变的。但放在坐标中进行解释,(0,0,1)都是代表Z轴正方向,但在左右手坐标系中他们与X,Y轴正方向的相对空间位置是不同的。在右手坐标中判断叉乘结果的方向使用右手定律,左手坐标系中使用左手。

视图变换是三维渲染中物体顶点坐标变换的一部分,完整的流程为:

1使用Module矩阵将物体顶点坐标从物体坐标系转换至世界坐标系

2使用View矩阵将物体顶点坐标从世界坐标系转换至由摄像机定义的坐标系,摄像机坐标系原点在摄像机,Z轴方向沿着视线方向往前,y轴方向即摄像机的向上向量。

3.使用透视投影矩阵及透视除法将位于视锥体内的顶点坐标转换到X,Y,Z范围都为-1至1.

摄像机特点:

三维自由运动的物体有六个运动自由度,分别是X,Y,Z方向的平移和绕X,Y,Z轴的选择。绕Z轴的旋转使物体发生侧向倾斜,如果站在人的角度考虑的话,就是向左或向右倾斜了,这个自由度在大部分情况是可以不要的,他更容易使人产生眩晕感。所以这里的摄像机拥有剩余的五个自由。绕X轴选择代表了仰视和俯视,绕Y轴旋转代表了旋转自身,比如从向东旋转到向西。

View矩阵的工作原理

View矩阵的工作目标是将世界坐标系中的所有物体的顶点的坐标从世界坐标系转换到摄像机坐标系。

摄像机坐标系的原点不一定与世界坐标系重合,同时由于自身的旋转,坐标轴也一定不与世界坐标系的坐标轴平行。为完成工作任务,需要分为两步走1.整体平移,将摄像机平移至世界坐标系原点,2.将坐标点从世界坐标系转换至摄像机坐标系。

使用单位向量U,V,W分别代表摄像机坐标系X,Y,Z轴正向的单位向量在世界坐标系中的表示,则在摄像相机坐标系与世界坐标系原点重合的情况下,物体顶点坐标代表的向量(即从世界原点指向物体顶点的向量)在U,V,W上的投影大小即是物体顶点在摄像机坐标系下的坐标值。因为U,V,W是单位向量,使用二者的点乘即可以得到顶点的投影大小。

Lookat函数的一般形式

LookAt(Vector3 eyePos,Vector3 targerPos,Vector3 upDir,Matrix4 & ViewMatrix);

函数的参数:eyePos代表了摄像机在世界坐标系中的坐标,targetPos代表了视线方向上某个目标物体的坐标,upDir一般使用的是世界坐标系中的向上向量,即(0,1,0).

这个函数将传入的最后一个参数设置为前面参数所指定的View矩阵。

首先要先求得摄像机坐标系的U,V,W。

1.首先已知eyePos和tarPos,可以求得视线方向,视线方向由eyePos指向tarPos,所以viewDir=tarPos-eyePos,W=viewDir.normalize()

2.U=crossProduct(upDir,W) U=U.normalize()

upDir一般是向量(0,1,0),所以求得的U向量必然是平行于地面,而如果物体绕Z轴选择,X轴将不再平行于地面。说明使用upDir为(0,1,0)时计算U,V,W的计算方法默认摄像机只有两个旋转自由度。

3.V=crossProduct(W,U) V.normalize()

注意:这里使用右手坐标系,使用向量叉积计算U,V时,crossProduct()函数的参数的顺序是重要的。叉乘结果向量的方向符合右手法则。

现在View矩阵可以由两个矩阵合成,一个是将摄像机平移至原点的矩阵T,一个是将坐标点从世界坐标系转换至摄像机坐标系的矩阵R。

 

大概的代码表示的流程

 void Matrix4X4::initLookAtMatrix(const Vector3& eyePos, const Vector3& targetPos, const Vector3& updir) {
Vector3 eye = eyePos;
Vector3 tar = targetPos;
Vector3 up = updir; Vector3 W = tar - eye;
W.normalize();
Vector3 U = Vector3::crossProduct(up, W);
U.normalize();
Vector3 V = Vector3::crossProduct(W, U);
V.normalize(); float m[][] = { { U.x,U.y,U.z, },{ V.x,V.y,V.z, },{ W.x,W.y,W.z, },{ ,,, } };
Matrix4X4 coordiTransformMatrix(m); Matrix4X4 contraryTranslation;
contraryTranslation.initTranslationMatrix(-eyePos.x, -eye.y, -eye.z); *this = coordiTransformMatrix*contraryTranslation; }

右手坐标系下LookAt视图矩阵的推导的更多相关文章

  1. 视图矩阵的推导-opengl应用

    把物体从世界坐标系转化到视点坐标系的矩阵称为视图矩阵. 下面我们先看下opengl视图矩阵的推导过程: 假设视点或camera的局部坐标系为UVN,UVN分别指向右方.上方和后方从而构成右手坐标系,视 ...

  2. (转)投影矩阵的推导(Deriving Projection Matrices)

    转自:http://blog.csdn.net/gggg_ggg/article/details/45969499 本文乃<投影矩阵的推导>译文,原文地址为: http://www.cod ...

  3. WEBGL学习【四】模型视图矩阵

    <html lang="zh-CN"> <!--服务器运行地址:http://127.0.0.1:8080/webgl/LearnNeHeWebGL/NeHeWe ...

  4. OpenGL(五) 三维变换之模型视图矩阵

    计算机三维图形学中,一个基本的任务是如何描述三维空间中一个物体位置的变化,也就是如何 描述物体的运动.通常情况下,物体位置的变化包含三个基本的变化:平移.旋转和缩放,物体的运动也可以用这三个基本的运动 ...

  5. 3D中的相机 - 投影矩阵和视图矩阵

    3D中的相机 - 投影矩阵和视图矩阵 3d游戏中,一般通过相机的设置来计算投影矩阵和视图矩阵,比如untiy和cocos,一般情况下我们不用关注如何计算, 可以直接在可视化的编辑器中调整参数就可以了, ...

  6. 解决Oracle在scott用户下创建视图(VIEW)权限不足的方法

    问题描述:在scott用户下创建视图的时候,报错:权限不足.(其他用户以此类推)解决方法: 以dba用户登录 sqlplus / as sysdba 赋予scott用户创建VIEW的权限 grant  ...

  7. UFLDL深度学习笔记 (二)SoftMax 回归(矩阵化推导)

    UFLDL深度学习笔记 (二)Softmax 回归 本文为学习"UFLDL Softmax回归"的笔记与代码实现,文中略过了对代价函数求偏导的过程,本篇笔记主要补充求偏导步骤的详细 ...

  8. OpenGL中投影矩阵的推导

    本文主要是对红宝书(第八版)第五章中给出的透视投影矩阵和正交投影矩阵做一个简单推导.投影矩阵的目的是:原始点P(x,y,z)对应后投影点P'(x',y',z')满足x',y',z'∈[-1,1]. 一 ...

  9. [OpenGL](翻译+补充)投影矩阵的推导

    1.简介 基本是翻译和补充 http://www.songho.ca/opengl/gl_projectionmatrix.html 计算机显示器是一个2D的平面,一个3D的场景要被OpenGL渲染必 ...

随机推荐

  1. Hibernate 再接触 多对一与一对多

    多对一单向关联 数据库设计: 错误做法:在多方加外键 在多这一方加外键 第一种 annotation Group.java package com.bjsxt.hibernate; import ja ...

  2. Structs复习 Action传递参数

    Structs传递参数通常有三种方式 下面我来一个个介绍 1.属性 Jar包 web.xml <?xml version="1.0" encoding="UTF-8 ...

  3. c++之enum(枚举)可以没有枚举名

    转载自https://blog.csdn.net/u013591613/article/details/71215000 C_enum(枚举)可以没有枚举名 如果声明枚举类型时没有指定枚举名,其作用就 ...

  4. css3文本和颜色

    1.文本阴影text-shadow 语法 text-shadow:X-Offset Y-Offset blur color; X-Offset:表示阴影的水平偏移距离,其值为正值时阴影向右偏移,反之向 ...

  5. js高级-闭包

    function foo(x){ var tmp = 3; return function(y){ //把一个函数作为返回值,定义时候的作用域 console.log(x+y+(++tmp)) //+ ...

  6. java.lang.UnsupportedClassVersionError 异常

    运行的JDK版本和开发环境的版本不一致导致 解决办法:更换运行环境的JDK版本,使其与运行环境一致.

  7. vue watch详细用法

    在vue中,使用watch来响应数据的变化.watch的用法大致有三种.下面代码是watch的一种简单的用法 html: <input type="text" v-model ...

  8. linux编译安装php apache mysql (已试过)

    阅读目录 (全部使用源码安装方式,先安装mysql,然后是apache,再是php,这样好像能防止挺多问题的,期间出现问题基本是依赖没有或者版本不对) 1.简介 2.安装apache 2.1.yum方 ...

  9. 获取cookie

    1.cookie是存储在用户本地终端的数据,实际上是一小段的文本信息 2.cookie的作用 帮助web站点保存有关的访问者的信息,方便用户的访问,如记住用户名和密码,实现自动登录功能案例:查看访问我 ...

  10. WPF双向绑定

    需求: 思想批量保存数据. 思路: 看了一下MVVM.发现只需要实现前台和后台数据的同步即可.也就是前台的文本框内容变化时后台的对象的属性也要变化就可以了. 参考: http://www.cnblog ...