摄像机+LookAt矩阵+视角移动+欧拉角
一: 摄像机
- OpenGL本身没有摄像机(Camera)的概念,但我们可以通过把场景中的所有物体往相反方向移动的方式来模拟出摄像机,产生一种我们在移动的感觉,而不是场景在移动。
- 以摄像机的视角作为场景原点时场景中所有的顶点坐标:观察矩阵把所有的世界坐标变换为相对于摄像机位置与方向的观察坐标。
- 要定义一个摄像机,我们需要它在世界空间中的位置、观察的方向、一个指向它右测的向量以及一个指向它上方的向量。
- 实际上创建了一个三个单位轴相互垂直的、以摄像机的位置为原点的坐标系。
- 摄像机位置:摄像机位置简单来说就是世界空间中一个指向摄像机位置的向量。
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
- 摄像机方向:这里指的是摄像机指向哪个方向。现在我们让摄像机指向场景原点:(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轴的正方向,与摄像机实际指向的方向是正好相反的)。
- 右轴:需要的另一个向量是一个右向量(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));
- 上轴:已经有了x轴向量(cameraRight)和z轴向量(cameraDirection),获取一个指向摄像机的正y轴向量就相对简单了:我们把右向量和方向向量进行叉乘:
glm::vec3 cameraUp = glm::cross(cameraDirection, cameraRight);
二:LookAt矩阵
- 使用矩阵的好处之一是如果你使用3个相互垂直(或非线性)的轴定义了一个坐标空间,你可以用这3个轴外加一个平移向量来创建一个矩阵,并且你可以用这个矩阵乘以任何向量来将其变换到那个坐标空间。
- 有了3个相互垂直的轴和一个定义摄像机空间的位置坐标,可以创建自己的LookAt矩阵
- LookAt矩阵就像它的名字表达的那样:它会创建一个看着(Look at)给定目标的观察矩阵。
- 位置向量在矩阵中运算时时相反的:因为我们最终希望把世界平移到与我们自身移动的相反方向。
- 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));//上向量
- 摄像机类里面返回的观察矩阵定义如下:
view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
这里的目标位置改成了摄像机位置加上方向向量(glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);)这样做可以保证,摄像机始终注视着目标方向。
三: 视角移动
- 为了能够改变视角,我们需要根据鼠标的输入改变cameraFront向量(上面说的方向向量:cameraDirection)。
- 欧拉角:俯仰角(Pitch)、偏航角(Yaw)和滚转角(Roll)
2.1 俯仰角(Pitch):如何往上或往下看的角,绕x轴
2.2 偏航角(Yaw):偏航角表示我们往左和往右看的程度,绕y轴
2.3 滚转角(Roll):如何翻滚摄像机,绕z轴
摄像机+LookAt矩阵+视角移动+欧拉角的更多相关文章
- OpenGL中摄像机矩阵的计算原理
熟悉OpenGL|ES的朋友,可能会经常设置摄像机的view矩阵,iOS中相对较好,已经封装了方向,只需要设置摄像机位置,目标点位置以及UP向量即可.下面先介绍下摄像机view矩阵的计算原理.此处假设 ...
- OpenGL入门1.7:摄像机
每一个小步骤的源码都放在了Github 的内容为插入注释,可以先跳过 前言 我们已经知道了何为观察矩阵以及如何使用观察矩阵移动场景(我们向后移动了一点) OpenGL本身没有摄像机(Camera)的概 ...
- opengl摄像机
摄像机/观察空间 当我们讨论摄像机/观察空间(Camera/View Space)的时候,是在讨论以摄像机的视角作为场景原点时场景中所有的顶点坐标:观察矩阵把所有的世界坐标变换为相对于摄像机位置与方向 ...
- unity3D基础学习 通过判断鼠标点击的是否是目标物体,物体旋转,滑动滚轮缩放拉近视角
贴代码: 摄像机的拉近视角代码: public Transform target; public float minFov = 15f; public float maxFov = 7 ...
- 《逐梦旅程 WINDOWS游戏编程之从零开始》笔记9——游戏摄像机&三维地形的构建
第21章 游戏摄像机的构建 之前的程序示例,都是通过封装的DirectInput类来处理键盘和鼠标的输入,对应地改变我们人物模型的世界矩阵来达到移动物体,改变观察点的效果.其实我们的观察方向乃至观察点 ...
- 本质矩阵E求解及运动状态恢复
为了获取本质矩阵,首先计算基础矩阵F.根据本质矩阵E,即可恢复得到运动的状态R和T. 由可以根据匹配点得到F,然后根据和相机内参,即可得到本质矩阵E.进而根据: 注意:根据摄像机模型t=-RT,恢复运 ...
- LearnOpenGL
---------------------------------------------- LearnOpenGL ----------------------------------------- ...
- OpenGL的一些名词
搬运自:https://learnopengl-cn.github.io/01%20Getting%20started/10%20Review/ 词汇表 OpenGL: 一个定义了函数布局和输出的图形 ...
- openGL学习----相机
0.参考:https://learnopengl-cn.github.io/01%20Getting%20started/09%20Camera/ 0.0其实相机就是搞清楚cameraPos,came ...
随机推荐
- B-number HDU - 3652
题意: 找出区间[li,ri]有多少个符合要求的数: 1.这个数里面有13 2.这个数可以被13整除 题解: 这个题目和之前的有点不一样就是这个题目要我们求包含13的(之前做过的都是不包含).但是都差 ...
- c#中几种常见的数据结构
数组(Array): 1.数组存储在连续的内存上 2.数组的元素类型必须相同 3.数组可以直接通过下标访问 4.查找与修改元素的速度非常快 5.必须在声明时指定长度 动态数组(ArrayLis ...
- 要想用活Redis,Lua脚本是绕不过去的坎
前言 Redis 当中提供了许多重要的高级特性,比如发布与订阅,Lua 脚本等.Redis 当中也提供了自增的原子命令,但是假如我们需要同时执行好几个命令的同时又想让这些命令保持原子性,该怎么办呢?这 ...
- 【Azure Redis 缓存】使用Python代码获取Azure Redis的监控指标值 (含Powershell脚本方式)
问题描述 通过Metrics监控页面,我们能得知当前资源(如Redis)的运行情况与各种指标.如果我们需要把指标下载到本地或者生成JSON数据导入到第三方的监控平台呢?Azure是否可以通过Pytho ...
- 大数据开发-Spark Join原理详解
数据分析中将两个数据集进行 Join 操作是很常见的场景.在 Spark 的物理计划阶段,Spark 的 Join Selection 类会根 据 Join hints 策略.Join 表的大小. J ...
- Socket 编程简介
Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯. 本章节我们为大家接收 Perl ...
- ffmpeg开发环境搭建--(linux)
1. 下载源码: http://ffmpeg.org/download.html 2. 解压:tar –xvf ffmpeg-3.2.1.tar.bz2 3. 配置 Eg:./ ...
- sdutoj2887
#include <stdio.h> #include <math.h> int main(){ int px,tx;double alpha; int T;scanf(&qu ...
- Vue Cheat Sheet & Nuxt.js Cheat Sheet
Vue Cheat Sheet & Nuxt.js Cheat Sheet Vue Cheat Sheet https://www.vuemastery.com/pdf/Vue-Essenti ...
- 一个模块如何同时支持 ESM 和 CJS
一个模块如何同时支持 ESM 和 CJS 模块转化 webpack + babel refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问 ...