图形学初识--定义摄像机类(实战)

news2024/11/26 2:40:28

文章目录

  • 前言
  • 正文
    • 定义摄像机的操作方式
      • 键盘操作
      • 鼠标操作
    • 定义摄像机类核心数据
      • 视图矩阵回顾:
      • 模拟摄像机的移动
      • 模拟摄像机的旋转
  • 结尾:喜欢的小伙伴点点关注+赞哦!

前言

前面一些章节讲解了图形学的比较原理性的内容,这一章节咱就实战一下,封装一个简易的摄像机类,看看最基本的摄像机是如何一步步实现出来的!

正文

定义摄像机的操作方式

键盘操作

规定使用WSAD模拟摄像机的前后左右移动。即如下:

  • W按键,使得摄像机前进,也就是朝-Z轴方向移动
  • S按键,使得摄像机后退,也就是朝Z轴方向移动
  • A按键,使得摄像机向左边移动,也就是朝-X轴方向移动
  • D按键,使得摄像机向右边移动,也就是朝X轴方向移动

鼠标操作

规定按住鼠标右键:上下移动,类似点头;左右移动,类似左右摇头。类似下图的:pitch和yaw操作

在这里插入图片描述

由于咱们模拟的是射击类游戏的镜头,所以绕Z轴旋转的Roll操作,咱们并不涉及,这里不多阐述,其实原理大同小异!

定义摄像机类核心数据

最基本的核心数据如下图所示,由于是使用glm数学库表示的向量,glm::vec3表示三维向量。

在这里插入图片描述

视图矩阵回顾:

通过摄像机正向变换过程的逆变换定义,正向过程如下:

在这里插入图片描述

假设正向过程定义为 M = T ∗ R M = T * R M=TR,R表示旋转矩阵,T表示平移矩阵,则视图矩阵表示为M的逆过程,也就是: M − 1 = R − 1 ∗ T − 1 M^{-1} = R^{-1}*T^{-1} M1=R1T1

回顾一下,R是通过摄像机三个基向量 r ⃗ 、 u ⃗ 、 − ⃗ f \vec r、\vec u、\vec -f r u f 定义而来,如下:
R = [ r x u x − f x 0 r y u y − f y 0 r z u z − f z 0 0 0 0 1 ] R = \begin{bmatrix} r_x & u_x & -f_x & 0\\ r_y & u_y & -f_y & 0\\ r_z & u_z & -f_z & 0\\ 0 & 0 & 0 & 1\\ \end{bmatrix} R= rxryrz0uxuyuz0fxfyfz00001
T是通过摄像机的位置 P = ( p x , p y , p z ) P = (p_x,p_y,p_z) P=(px,py,pz) 定义而来,如下:
T = [ 1 0 0 p x 0 1 0 p y 0 0 1 p z 0 0 0 1 ] T=\begin{bmatrix} 1 & 0 & 0 & p_x\\ 0 & 1 & 0 & p_y\\ 0 & 0 & 1 & p_z\\ 0 & 0 & 0 & 1\\ \end{bmatrix}\\ T= 100001000010pxpypz1

因而得到最终的 M − 1 M^{-1} M1矩阵,如下:
M − 1 = [ r x r y r z 0 u x u y u z 0 − f x − f y − f z 0 0 0 0 1 ] ∗ [ 1 0 0 − p x 0 1 0 − p y 0 0 1 − p z 0 0 0 1 ] = [ r x r y r z − r ⃗ ⋅ p ⃗ u x u y u z − u ⃗ ⋅ p ⃗ − f x − f y − f z f ⃗ ⋅ p ⃗ 0 0 0 1 ] \begin{align} M^{-1}&=\begin{bmatrix} r_x & r_y & r_z & 0\\ u_x & u_y & u_z & 0\\ -f_x & -f_y & -f_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} r_x & r_y & r_z & -\vec{r} \cdot \vec{p}\\ u_x & u_y & u_z & -\vec{u} \cdot \vec{p}\\ -f_x & -f_y & -f_z & \vec{f} \cdot \vec{p}\\ 0 & 0 & 0 & 1\\ \end{bmatrix} \end{align} M1= rxuxfx0ryuyfy0rzuzfz00001 100001000010pxpypz1 = rxuxfx0ryuyfy0rzuzfz0r p u p f p 1

模拟摄像机的移动

既然我们知道视图变换矩阵,由哪些变量控制,那咱们要通过WASD按键模拟摄像机的前进、后退、左移、右移,其实就对应着控制摄像机的位置向量而已。

那么究竟往什么方向移动呢?其实就受到上述坐标基向量 f ⃗ 、 r ⃗ \vec f、\vec r f r 的影响了!W对应 f ⃗ \vec f f 方向,S对应 − f ⃗ -\vec f f 方向,A对应 − r ⃗ -\vec r r 方向,D对应 r ⃗ \vec r r 方向!

既然方向有了,那么依次根据方向走多少呢?这个其实咱们可以通过实践进行调整,设置一个合理的步长即可!这里也就对应上述类中的 m o v e _ s p e e d _ move\_speed\_ move_speed_变量!

这里给出一个基本逻辑代码贴出:

glm::vec3 moveDirection = { 0.0f, 0.0f, 0.0f };

glm::vec3 front = front_;
glm::vec3 right = glm::normalize(glm::cross(front_, top_));

if (move_state_ & MOVE_FRONT) 
{
    moveDirection += front;
}

if (move_state_ & MOVE_BACK) 
{
    moveDirection += -front;
}

if (move_state_ & MOVE_LEFT) 
{
    moveDirection += -right;
}

if (move_state_ & MOVE_RIGHT) 
{
    moveDirection += right;
}

if (moveDirection != glm::vec3(0.0, 0.0, 0.0)) 
{
    moveDirection = glm::normalize(moveDirection);
    position_ += move_speed_ * moveDirection;
}

这里需要注意的是,在实现按键控制摄像机移动时,我们需要考虑多键位同时按下的情况,也就是有可能存在多个方位叠加的情况,所以上述是通过位运算进行判定移动状态!

模拟摄像机的旋转

我们思考一个问题,旋转代表什么含义?

通过上述的视图矩阵回顾我们知道主要由三个基向量决定,但是我们知道只要知道两个就可以叉乘得出另外一个。

我们又知道第三人称的射击类游戏,一般摄像机的穹顶 T o p ⃗ \vec {Top} Top 方向都是固定的为 ( 0 , 1 , 0 ) (0,1,0) (0,1,0),这样推论的话,也就一个 f ⃗ \vec f f 方向咱们是可以移动,也就是摄像机看向的方向,所以咱们需要通过这个向量来定义摄像机的旋转,示意图如下:

在这里插入图片描述

咱们观察右侧的公式,咱们通过引入pitch和yaw张角,从而定义 f r o n t ⃗ \vec {front} front 向量,也就是摄像机观察的方向向量。

这里我们注意一下,一般来说射击类游戏的摄像机pitch的角度是由范围限制的,也就是 ( − 90 , 90 ) (-90,90) (90,90) °的范围!为了保险起见,一般都是限制在 ( − 89 , 89 ) (-89,89) (89,89)°之间。

既然咱们可以通过约束 f ⃗ r o n t \vec front f ront 向量,来模拟摄像机的旋转,那么咱们就究竟是如何通过鼠标的移动转化的呢?

其实很简单,鼠标如果向上移动,就表示pitch角度变大,向下移动就表示pitch角度变小;同理,鼠标如果向左移动,就表示yaw角度变小,向右移动就表示yaw角度变大。至于变大或变小多少,就可以自定义一个合理的步长即可,类似上述的 m o u s e _ s e n s i t i v i t y _ mouse\_sensitivity\_ mouse_sensitivity_ 变量!

这里贴出pitch和yaw的逻辑代码片段,仅供参考:

void Camera::Pitch(int yoffset) 
{
	pitch_angle_ += yoffset * mouse_sensitivity_;

	if (pitch_angle_ >= 89.0f)
	{
		pitch_angle_ = 89.0f;
	}

	if (pitch_angle_ <= -89.0f)
	{
		pitch_angle_ = -89.0f;
	}

	front_.y = sin(glm::radians(pitch_angle_));
	front_.x = cos(glm::radians(yaw_angle_)) * cos(glm::radians(pitch_angle_));
	front_.z = sin(glm::radians(yaw_angle_)) * cos(glm::radians(pitch_angle_));

	front_ = glm::normalize(front_);
}

void Camera::Yaw(int xoffset) 
{
	yaw_angle_ += xoffset * mouse_sensitivity_;

	front_.y = sin(glm::radians(pitch_angle_));
	front_.x = cos(glm::radians(yaw_angle_)) * cos(glm::radians(pitch_angle_));
	front_.z = sin(glm::radians(yaw_angle_)) * cos(glm::radians(pitch_angle_));

	front_ = glm::normalize(front_);
}

于是咱们就大功告成了啊!如果需要学习相关代码的小伙伴,建议点击这里学习哦,如果对你有用的话,建议给仓库点个Start哦,感谢各位老铁们!

结尾:喜欢的小伙伴点点关注+赞哦!

你们的点赞就是我创作的最大动力!希望对各位小伙伴能够有所帮助哦,永远在学习的道路上伴你而行, 我是航火火,火一般的男人!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1816901.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

监控登录用户数

检查登录用户数 当登录系统用户数超过3个报警&#xff0c;并发送邮件提示 首先&#xff0c;配置发送邮件功能。 1、安装mailx [rootnode1 ~]# yum install mailx2、配置/etc/mail.rc [rootnode1 ~]# vim /etc/mail.rc set fromxxx163.com #发件人地址 set smtpsmtp.163…

深层网络:层数多真的更好吗?

深层网络&#xff1a;层数多真的更好吗&#xff1f; 在深度学习的世界里&#xff0c;"深度"始终是一个热门话题。随着技术的发展&#xff0c;我们有了越来越多的方法来构建更深的神经网络&#xff0c;这似乎暗示着“层数越多&#xff0c;效果越好”。然而&#xff0…

通用大模型与垂直大模型:双轨并进的人工智能未来

在人工智能(AI)的浩瀚宇宙中&#xff0c;大模型以其强大的学习能力和广泛的适用性&#xff0c;正逐步成为推动技术进步和产业革新的核心动力。在这股浪潮中&#xff0c;通用大模型与垂直大模型如同两颗璀璨的星辰&#xff0c;各自散发着独特的光芒&#xff0c;共同照亮了AI发展…

哪个品牌洗地机专业?四款明星精湛产品集结

当代快节奏的生活&#xff0c;人们每天下班回到家只想瘫倒在沙发&#xff0c;打扫卫生成为了一种负担......但洗地机的出现&#xff0c;大大的减轻了人们地板清洁的焦虑&#xff0c;因为它只需轻轻地推拉机子转悠房屋一圈&#xff0c;地面上的赃污便能清理干净&#xff0c;清洁…

如何优化大屏网站的响应式设计?技巧一览

为了显示不同屏幕尺寸设备的显示效果&#xff0c;有必要优先考虑响应设计&#xff0c;因为开发人员可以在不同的设备中构建应用程序。响应设计是一种灵活的设计&#xff0c;可以兼顾多屏幕和多场景&#xff0c;可以使我们的网页布局在各种屏幕下呈现出更好的效果。今天&#xf…

“JS加密在线”:简单直接的在线JS加密网站

网站名&#xff1a;“JS加密在线”&#xff0c; 功能&#xff1a;JavaScript源代码加密。 UI&#xff1a; http://jsjiami.online/ 非常简洁的JS加密网站&#xff0c;几乎只有两个功能&#xff1a;上传JS文件、下载加密后的JS文件。 JS加密&#xff0c;就应该这样简单直接。…

Splashtop 荣获“2024年安全校园白金奖”

2024年6月12日 加利福尼亚州库比蒂诺 作为远程访问和 IT 支持领域的领先企业&#xff0c;Splashtop 很荣幸地宣布获得“2024年安全校园白金奖”。Splashtop 的 Foxpass Cloud RADIUS 解决方案在专注校园安全的重要杂志《今日校园安全》颁发的访问控制和云端管理类别奖项中荣获…

Hyper-V 安装Win11注意事项

1. 安装前检查设置&#xff0c;勾选TPM2. 启动的时候要一直按F2&#xff0c;否则提示找不到系统镜像 3. 安装完成后开机后在查看里取消增强会话&#xff0c;否则开机进入锁屏界面&#xff0c;无法输入密码进入系统。一般这种情况出现在通过微软账户登录的系统&#xff0c;可首…

CG-85C 振弦式土压力计厂家 结构物内部土压力变化量如何测量?

产品概述 振弦式土压力计由背板、感应板、信号传输电缆、振弦及激振电磁线圈等组成&#xff0c;是了解被测结构物内部土压力变化量、并可同步测量埋设点温度的监测设备。 功能特点 ◆精度高&#xff0c;能够提供准确的测量结果。 ◆稳定性好&#xff0c;不易受到外界因素的…

后端开发面经系列 -- 小鹏汽车一面面经

小鹏汽车一面面经 公众号&#xff1a;阿Q技术站 来源&#xff1a;职言详情页 (maimai.cn) 文章目录 小鹏汽车一面面经1、String类型为什么不可变&#xff1f;1. 安全性2. 缓存和性能优化3. 哈希码缓存4. 类设计和接口5. 简单性和可读性 2、在浏览器中输入url地址到显示主页的过…

Anti-ABCD3 Antibody-Monoclonal Antibody against Human ABCD3

本篇是对Atlas生产的Anti-ABCD3 Antibody的简单介绍&#xff0c;如需购买该产品或了解更多产品详情&#xff0c;可联系一级代理商欣博盛生物。 产品名称&#xff1a;Anti-ABCD3 Antibody 品牌&#xff1a;Atlas antibodies 货号&#xff1a;AMAb90995 规格&#xff1a;100ul…

大模型「训练」与「微调」概念详解【6000字长文】

本文你将学到什么 1、大模型预训练与微调的基本流程 2、预训练、训练、后期预训练、微调的区别 3、大模型训练与微调的一些概念&#xff0c;如&#xff1a; Post-pretrain、SFT、RLHF、模型对齐、Lora、Q-Lora、大模型量化、微调指标、微调参数、大模型评测指标 预训练与微…

AI Agent 热门的10篇论文

人工智能代理领域广阔,涵盖广泛的主题,包括多代理系统、强化学习、上下文感知系统以及将大型语言模型 (LLMs) 集成到基于代理的系统中。以下是 arXiv 的一些顶级论文,涵盖了人工智能代理的各个方面: A Framework For Intelligent Multi Agent System Based Neural Network …

[深度学习]使用python转换pt并部署yolov10的tensorrt模型封装成类几句完成目标检测加速任务

【简单介绍】 使用Python将YOLOv10模型从PyTorch格式&#xff08;.pt&#xff09;转换为TensorRT格式&#xff0c;并通过封装成类来实现目标检测加速任务&#xff0c;是一个高效且实用的流程。以下是该过程的简要介绍&#xff1a; 模型转换&#xff1a; 利用官方提供导出命令…

69. UE5 RPG 使用Gameplay Cue 实现技能表现效果

在上一章中&#xff0c;我们实现了敌人的攻击技能的特效和音效。如果我们在多人模式下打开&#xff0c;发现&#xff0c;其它客户端看不到对应的效果。 造成这种问题的原因是因为敌人的技能是运行在服务器端的&#xff0c;它只复制到拥有它的客户端&#xff0c;而敌人的效果对于…

2024最新流媒体在线音乐系统网站源码 音乐社区 多语言开心版

本文选自&#xff1a;2024最新流媒体在线音乐系统网站源码 音乐社区 多语言开心版 - 源码1688 应用介绍 简介&#xff1a; 2024最新流媒体在线音乐系统网站源码| 音乐社区 | 多语言 | 开心版 图片&#xff1a;

delmia机器人运动仿真PPR

创建时PPR时ProductList和ResourceList两个里面用到的产品或资源都必须是Product&#xff0c;才可以加载进来&#xff0c;否则不行。

项目文件预览

在实际项目开发过程&#xff0c;项目使用数据存在多种形式&#xff0c;“文件”也是一种常见形式&#xff0c;因此&#xff0c;“文件预览”功能变成了常规需求。 kkFileView项目使用流行的spring boot搭建&#xff0c;易上手和部署。万能的文件预览开源项目&#xff0c;基本支…

python实现自动化测试框架如何进行数据参数化?这个包可以了解下

1.数据参数化介绍 只要你是负责编写自动化测试脚本的&#xff0c;数据参数化这个思想你就肯定会用 &#xff0c;数据参数化的工具你肯定的懂一些 &#xff0c;因为它能大大的提高我们自动化脚本编写效率 。 1.1什么是数据参数化 所谓的数据参数化 &#xff0c;是指所执行的测…

[AI StoryDiffusion] 创造神奇故事,AI漫画大乱斗!

今天介绍一个新的AI项目&#xff0c;StoryDiffusion&#xff0c;用于生成一致性连贯的图像和视频。 因为它的一致性&#xff0c;因此可以用于创建漫画&#xff0c;或者长视频。 官方示例可看文末链接&#xff0c;这里不再赘述。 关键特性&#xff1a; StoryDiffusion 可以通…