一: 摄像机

  • OpenGL本身没有摄像机(Camera)的概念,但我们可以通过把场景中的所有物体往相反方向移动的方式来模拟出摄像机,产生一种我们在移动的感觉,而不是场景在移动。
  • 以摄像机的视角作为场景原点时场景中所有的顶点坐标:观察矩阵把所有的世界坐标变换为相对于摄像机位置与方向的观察坐标。
  • 要定义一个摄像机,我们需要它在世界空间中的位置、观察的方向、一个指向它右测的向量以及一个指向它上方的向量。
  • 实际上创建了一个三个单位轴相互垂直的、以摄像机的位置为原点的坐标系。
  1. 摄像机位置:摄像机位置简单来说就是世界空间中一个指向摄像机位置的向量。
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
  1. 摄像机方向:这里指的是摄像机指向哪个方向。现在我们让摄像机指向场景原点:(0, 0, 0)。

    2.1 用场景原点向量减去摄像机位置向量的结果就是摄像机的指向向量。

    2.2 由于我们知道摄像机指向z轴负方向,但我们希望方向向量(Direction Vector)指向摄像机的z轴正方向。如果我们交换相减的顺序,我们就会获得一个指向摄像机正z轴方向的向量:
glm::vec3 cameraTarget = glm::vec3(0.0f, 0.0f, 0.0f);//表示摄像机指向的地方,即原点
glm::vec3 cameraDirection = glm::normalize(cameraPos - cameraTarget);//方向向量,与指向的方向相反的向量
  2.3 ** 方向向量 **:(与实际指向的方向相反)方向向量(Direction Vector)并不是最好的名字,因为它实际上指向从它到目标向量的相反方向(注意看前面的那个图,蓝色的方向向量大概指向z轴的正方向,与摄像机实际指向的方向是正好相反的)。
  1. 右轴:需要的另一个向量是一个右向量(Right Vector),它代表摄像机空间的x轴的正方向。为获取右向量我们需要先使用一个小技巧:先定义一个上向量(Up Vector)。接下来把上向量和第二步得到的方向向量进行叉乘。两个向量叉乘的结果会同时垂直于两向量,因此我们会得到指向x轴正方向的那个向量(如果我们交换两个向量叉乘的顺序就会得到相反的指向x轴负方向的向量):
glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);
glm::vec3 cameraRight = glm::normalize(glm::cross(up, cameraDirection));
  1. 上轴:已经有了x轴向量(cameraRight)和z轴向量(cameraDirection),获取一个指向摄像机的正y轴向量就相对简单了:我们把右向量和方向向量进行叉乘:
glm::vec3 cameraUp = glm::cross(cameraDirection, cameraRight);

二:LookAt矩阵

  1. 使用矩阵的好处之一是如果你使用3个相互垂直(或非线性)的轴定义了一个坐标空间,你可以用这3个轴外加一个平移向量来创建一个矩阵,并且你可以用这个矩阵乘以任何向量来将其变换到那个坐标空间。
  2. 有了3个相互垂直的轴和一个定义摄像机空间的位置坐标,可以创建自己的LookAt矩阵
  3. LookAt矩阵就像它的名字表达的那样:它会创建一个看着(Look at)给定目标的观察矩阵。
  4. 位置向量在矩阵中运算时时相反的:因为我们最终希望把世界平移到与我们自身移动的相反方向。
  5. glm::LookAt函数需要一个位置、目标和上向量。它会创建一个和在上一节使用的一样的观察矩阵。(根据以上的分析,有了这三个向量足以构建出LookAt矩阵)
glm::mat4 view;
view = glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f), //摄像机的位置向量
glm::vec3(0.0f, 0.0f, 0.0f), //目标位置向量
glm::vec3(0.0f, 1.0f, 0.0f));//上向量
  1. 摄像机类里面返回的观察矩阵定义如下:
view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);

这里的目标位置改成了摄像机位置加上方向向量(glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);)这样做可以保证,摄像机始终注视着目标方向。

三: 视角移动

  1. 为了能够改变视角,我们需要根据鼠标的输入改变cameraFront向量(上面说的方向向量:cameraDirection)。
  2. 欧拉角:俯仰角(Pitch)、偏航角(Yaw)和滚转角(Roll)

    2.1 俯仰角(Pitch):如何往上或往下看的角,绕x轴

    2.2 偏航角(Yaw):偏航角表示我们往左和往右看的程度,绕y轴

    2.3 滚转角(Roll):如何翻滚摄像机,绕z轴

摄像机+LookAt矩阵+视角移动+欧拉角的更多相关文章

  1. OpenGL中摄像机矩阵的计算原理

    熟悉OpenGL|ES的朋友,可能会经常设置摄像机的view矩阵,iOS中相对较好,已经封装了方向,只需要设置摄像机位置,目标点位置以及UP向量即可.下面先介绍下摄像机view矩阵的计算原理.此处假设 ...

  2. OpenGL入门1.7:摄像机

    每一个小步骤的源码都放在了Github 的内容为插入注释,可以先跳过 前言 我们已经知道了何为观察矩阵以及如何使用观察矩阵移动场景(我们向后移动了一点) OpenGL本身没有摄像机(Camera)的概 ...

  3. opengl摄像机

    摄像机/观察空间 当我们讨论摄像机/观察空间(Camera/View Space)的时候,是在讨论以摄像机的视角作为场景原点时场景中所有的顶点坐标:观察矩阵把所有的世界坐标变换为相对于摄像机位置与方向 ...

  4. unity3D基础学习 通过判断鼠标点击的是否是目标物体,物体旋转,滑动滚轮缩放拉近视角

    贴代码: 摄像机的拉近视角代码: public Transform target;     public float minFov = 15f;     public float maxFov = 7 ...

  5. 《逐梦旅程 WINDOWS游戏编程之从零开始》笔记9——游戏摄像机&三维地形的构建

    第21章 游戏摄像机的构建 之前的程序示例,都是通过封装的DirectInput类来处理键盘和鼠标的输入,对应地改变我们人物模型的世界矩阵来达到移动物体,改变观察点的效果.其实我们的观察方向乃至观察点 ...

  6. 本质矩阵E求解及运动状态恢复

    为了获取本质矩阵,首先计算基础矩阵F.根据本质矩阵E,即可恢复得到运动的状态R和T. 由可以根据匹配点得到F,然后根据和相机内参,即可得到本质矩阵E.进而根据: 注意:根据摄像机模型t=-RT,恢复运 ...

  7. LearnOpenGL

    ---------------------------------------------- LearnOpenGL ----------------------------------------- ...

  8. OpenGL的一些名词

    搬运自:https://learnopengl-cn.github.io/01%20Getting%20started/10%20Review/ 词汇表 OpenGL: 一个定义了函数布局和输出的图形 ...

  9. openGL学习----相机

    0.参考:https://learnopengl-cn.github.io/01%20Getting%20started/09%20Camera/ 0.0其实相机就是搞清楚cameraPos,came ...

随机推荐

  1. hdu4920Matrix multiplication (矩阵,bitset)

    Problem Description Given two matrices A and B of size n×n, find the product of them. bobo hates big ...

  2. hdu2546 饭卡

    Problem Description 电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额.如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负) ...

  3. 深入了解typeof与instanceof的使用场景及注意事项

    JavaScript中的数据类型分为两类,undefined,number,boolean,string,symbol,bigint,null[1]组成的基础类型和Object.Function.Ar ...

  4. Java15变量竟然没什么区别,八大基本数据类型你知道吗?

    变量是什么? 变量是用来为不同数据类型在内存中分配的空间用来储存该数据. 不同于python这样的弱类型语言,变量声明不需要定义数据类型,就和写数学方程式一般,谁等于谁即可.而Java这个发展了多个版 ...

  5. console.dir()可以显示一个对象所有的属性和方法

    console.dir()可以显示一个对象所有的属性和方法 具体方法如下:

  6. how to stop MongoDB from the command line

    how to stop MongoDB from the command line stop mongod https://docs.mongodb.com/manual/tutorial/manag ...

  7. PAUL ADAMS ARCHITECT:华州加州城市楼市竞争力居全美前列

    美国房地产公司最新一份报告显示,美国楼市竞争力最高的十个城市中有八个来自华盛顿州和加利福尼亚州,主要原因在于越来越多的买家考虑迁居房价更划算的都会区.数据显示,斯潘那维65%的房屋以高于要价的价格售出 ...

  8. NGK主网上线后内存价格上涨30倍,NGK RAM是否值得买入?

    美国加州时间10月14日上午10时,NGK主网正式上线.因为市场预期向好,NGK上线以后迎来了大涨,NGK的代币价格上涨了10倍,内存价格上涨了30倍.目前,NGK上线已经有五天的时间,盘面上已经出现 ...

  9. C++算法代码——单词查找

    题目来自:http://218.5.5.242:9018/JudgeOnline/problem.php?id=2472 题目描述 给定 n 个长度不超过 50 的由小写英文字母组成的单词准备查询,以 ...

  10. 01、初识Java

    目录 前言 一.认识Java 历史介绍 Java介绍 二.认识及安装JDK 1.认识JDK 2.安装JDK 配置与测试 配置注意及不生效解决 3.认识Java虚拟机 三.Java的工作方式 四.jav ...