计算机图形学 | 实验七:完成摄像机类的创建

计算机图形学入门28:相机、透镜和光场 计算机图形学入门,成像方法,小孔成像,针孔相机,FOV,曝光,透镜,景深,光场,光场相机。 阅读详情

华中科技大学《计算机图形学》课程

MOOC地址:计算机图形学(HUST)

计算机图形学 | 实验七:完成摄像机类的创建

摄像机/观察空间

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

我们在构造摄像机类的时候。着重强调4个重要的向量:

  • 摄像机位置:摄像机位置简单来说就是世界空间中一个指向摄像机位置的向量;
  • 摄像机方向:指的是摄像机指向哪个方向。一般我们让摄像机指向场景原点:(0, 0, 0);
  • 右轴:代表摄像机空间的x轴的正方向。为获取右向量我们需要先使用一个小技巧:先定义一个上向量(比如(0,1,0))。接下来把上向量和第二步得到的方向向量进行叉乘。得到的结果即为右向量;
  • 上轴:有了x轴向量和z轴向量,获取一个指向摄像机的正y轴向量就相对简单了:我们把右向量和方向向量进行叉乘得到上轴。

Look At 矩阵

LookAt矩阵就像它的名字表达的那样:它会创建一个看着(Look at)给定目标的观察矩阵。具体形式如下:

在这里插入图片描述

其中R是右向量,U是上向量,D是方向向量P是摄像机位置向量。GLM已经提供了这些支持。我们要做的只是定义一个摄像机位置,一个目标位置和一个表示世界空间中的上向量的向量(我们计算右向量使用的那个上向量)。接着GLM就会创建一个LookAt矩阵,我们可以把它当作我们的观察矩阵。

glm::mat4 Camera::GetViewMatrix()
{
	return glm::lookAt(Position, Position + Forward, Up);
}

自由移动

现在我们为GLFW的键盘输入定义一个processInput函数,我们来新添加几个需要检查的按键命令。使用GLFW的glfwGetKey函数,它需要一个窗口以及一个按键作为输入。这个函数将会返回这个按键是否正在被按下。我们使用WSAD来模拟摄像机的前后左右运动。

//键盘输入
void processInput(GLFWwindow *window)
{
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
		glfwSetWindowShouldClose(window, true);

	if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
		camera.ProcessKeyboard(FORWARD, deltaTime);
	if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
		camera.ProcessKeyboard(BACKWARD, deltaTime);
	if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
		camera.ProcessKeyboard(LEFT, deltaTime);
	if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
		camera.ProcessKeyboard(RIGHT, deltaTime);
}

目前我们的移动速度是个常量。理论上没什么问题,但是实际情况下根据处理器的能力不同,有些人可能会比其他人每秒绘制更多帧,也就是以更高的频率调用processInput函数。

图形程序和游戏通常会跟踪一个时间差(Deltatime)变量,它储存了渲染上一帧所用的时间。我们把所有速度都去乘以deltaTime值。结果就是,如果我们的deltaTime很大,就意味着上一帧的渲染花费了更多时间,所以这一帧的速度需要变得更高来平衡渲染所花去的时间。使用这种方法时,无论你的电脑快还是慢,摄像机的速度都会相应平衡,这样每个用户的体验就都一样了。

float deltaTime = 0.0f; // 当前帧与上一帧的时间差 
float lastFrame = 0.0f; // 上一帧的时间
//每一帧计算出新的deltaTime 
float currentFrame = glfwGetTime(); 
deltaTime = currentFrame - lastFrame; 
lastFrame = currentFrame; //从而控制移动速度 
float cameraSpeed = 2.5f * deltaTime;

视角移动

为了能够改变视角,我们需要根据鼠标的输入改变cameraFront向量,这里我们将用到数学里的欧拉角的相关知识。

欧拉角是可以表示3D空间中任何旋转的3个值,由莱昂哈德·欧拉(Leonhard Euler)在18世纪提出。一共有3种欧拉角:俯仰角(Pitch)、偏航角(Yaw)和滚转角(Roll),如下图所示:

在这里插入图片描述

俯仰角(Pitch)是描述我们如何往上戒往下看的角,可以在第一张图中看到。第二张图展示了偏航角(Yaw),偏航角表示我们往左和往右看的程度。滚转角(Roll)代表我们如何翻滚摄像机, 欧拉角都有一个值来表示,把三个角结合起来我们就能够计算3D空间中任何的旋转向量.

对于摄像机系统来说,我们只关心俯仰角和偏航角,所以我们不会在代码中加入滚转角。

鼠标输入

偏航角和俯仰角是通过鼠标移动获得的,水平的移动影响偏航角,竖直的移动影响俯仰角。通过储存上一帧鼠标的位置,在当前帧中我们当前计算鼠标位置不上一帧的位置相差多少。

首先我们要告诉GLFW,它应该隐藏光标,并捕捉(Capture)它。捕捉光标表示的是,如果焦点在你的程序上,光标应该停留在窗口中(除非程序失去焦点戒者退出)。我们可以用GLFW为我们提供的方法来配置:

glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);

让GLFW监听鼠标移动事件。(和键盘输入相似)使用的函数如下:

//鼠标移动响应
void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{
	if (firstMouse)
	{
		lastX = xpos;
		lastY = ypos;
		firstMouse = false;
	}

	float xoffset = xpos - lastX;
	float yoffset = lastY - ypos;

	lastX = xpos;
	lastY = ypos;

	camera.ProcessMouseMovement(xoffset, yoffset);
}

这里我们还引入了一个量sensitivity(灵敏度)来控制鼠标移动对视角影响的幅度。

float sensitivity = 0.1f; 
xoffset *= sensitivity; 
yoffset *= sensitivity;

其次我们需要添加一些限制,防止摄像机发生奇怪的移动(对于俯仰角,要让用户不能看向高于89度的地方,因为在90度时视角会发生逆转,所以我们把89度作为极限)。

if (pitch > 89.0f) pitch = 89.0f; 
if (pitch < -89.0f) pitch = -89.0f;

如果你现在运行代码,你会发现在窗口第一次获取焦点的时候摄像机会突然跳一下。想一想原因是什么?

答:在你的鼠标移动迚窗口的那一刻,鼠标回调函数就会被调用,这时候的xpos和ypos会等亍鼠标刚刚迚入屏幕的那个位置。这通常是一个距离屏幕中心很进的地方,因而产生一个很大的偏移量,所以就会跳了。我们可以简单的使用一个bool变量检验我们是否是第一次获取鼠标输入,如果是,那么我们先把鼠标的刜始位置更新为xpos和ypos值,这样就能解决这个问题;接下来的鼠标移动就会使用刚迚入的鼠标位置坐标来计算偏移量了。

if (firstMouse)
{
	lastX = xpos;
	lastY = ypos;
	firstMouse = false;
}

缩放

作为我们摄像机系统的一个附加内容,我们还会来实现一个缩放(Zoom)接口。在乊前的教程中我们说视野(Field of View)戒fov定义了我们可以看到场景中多大的范围。当视野变小时,场景投影出来的空间就会减小,产生放大(Zoom In)了的感觉。我们会使用鼠标的滚轮来放大,和鼠标移动视角一样,我们规定鼠标滚轮事件实现视野的方法和缩小。

//鼠标滚轮响应
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) 
{ 
	if(fov >= 1.0f && fov <= 45.0f) fov -= yoffset; 
	if(fov <= 1.0f) fov = 1.0f; 
	if(fov >= 45.0f) fov = 45.0f; 
}

其中,45.0f是默认设置的视野值。

同样之前记得用GLFW相应函数注册监控滚轮事件:

glfwSetScrollCallback(window, scroll_callback);

这样我们的摄像机类就完成了,运行程序后你可以通过WASD和鼠标控制你的视角。

运行结果:

在这里插入图片描述

最全计算机图形学面试资料整理 计算机图形学面试资料整理1 什么是渲染管线2 有那几个坐标系(空间)?如何在空间之间进行转换?3 三个重要的空间变换矩阵4 视口变换是什么?5 顶点缓冲对象(Vertex Buffer Objects,VBO)6 顶点数组对象(Vertex Arrary Object,VAO)7 渲染管线的流程8 三种着色器有什么用?各完成了什么过程?9 什么是光栅化?10 OpenGL中有哪几种缓冲?都有什么用?11 为什么要用齐次坐标系12 片段和像素的区别?13 深度缓存算法(zbuffer算法)14 光照计算处理共 阅读详情

相关推荐

unity3d与计算机图形学

对象(object)与观察者,在unity3d中的游戏对象(GameObject)有导入的3d模型还有基本对象(Primitive Objects),基本对象有立方体(cube)、球体(Sphere)、胶囊(Capsule)、圆柱(Cylinder)、平面(plane)、正方形(quad)。观察者看到图像需要成像系统,在计算机图形中成像系统有针孔照相机和人类视觉系统。在unity3d中成像系统是摄

weixin_38895366的博客 1512

OpenGL学习-第一章

重返GLM 在较新的GLM 版本中,创建一个矩阵时*切记一定*要给出初值(对角线初值),否则计算结果会严重出错: glm::mat4 trans;//NO trans = glm::translate(trans, glm::vec3(1, 1, 0));//结果严重出错 trans = glm::translate(glm::mat4(1), glm::vec3(1, 1, 0));//...

Retro-UN 499

计算机图形学中的四元数(Quaternions)

计算机图形学中的四元数计算机图形学中的四元数(Quaternions)前言欧拉角欧拉角的万向节死锁(Gimbal Lock)与插值问题四元数参考 计算机图形学中的四元数(Quaternions) 前言 最近上课,又学到了四元数部分,毕竟三维空间生物理解四维事物确实太抽象了,于是下定决心写一篇总结,分享一下自己的理解,同时也是巩固一下自己对于四元数的认识。 欧拉角 欧拉角相对来说是比较容易理解的一种描述旋转的方式。学术地说,欧拉角是用来唯一地确定定点转动刚体位置的三个一组独立角参量,由章动角θ、进动角ψ和自转

qq_36162042的博客 2553

计算机图形学【GAMES-101】12、相机(视场、曝光、光圈(F-Stop)、薄棱镜近似、CoC、景深)

Lecture191 相机2 视场(Field of Vied)(FOV)3 曝光(Exposure)4 光圈(F-Number)(F - Stop)5 薄透镜近似(Thin Lens Approximation)薄透镜公式6 Circle of Confusion(CoC)7 渲染中模拟透镜8 景深(Depth of Field) 1 相机 (1)图像 = 合成 + 捕捉 (图像可以是合成的,也可以是捕捉得到的) (2)快门和传感器 快门:可以控制光在一个极短的时间内进入相机 传感器:在曝光过程中,在传

记录值得记录的东西 4926

计算机图形学视图矩阵推导过程

视图矩阵推导过程(Demo基于WebGL 2.0实现) 一、概述 首先,我们需要了解些概念: 摄像机坐标系或者摄像机空间:物体经摄像机观察后,进入摄像机空间。 视变化,是将世界坐标系下的坐标变化到摄像机坐标系,视变换是通过乘以视图矩阵实现的。 我们要知道视并不存在真正的摄像机,只不过是在世界坐标系里面选择一个点,作为摄像机的位置。然后根据一些参数,在这个点构建一个坐标系。...

Webglzhang 1万+

计算机视觉,计算机图形学,模式识别,数字图像处理等概念和联系

学习了计算机视觉方向有段时间了,整理一下一些基本的概念: 1.计算机图形学 计算机图形学是给定关于景象结构、表面反射特性、光源配置及相机模型的信息,生成图像,实现的是从模型到图像的变换。  例如使用opengl进行渲染生成三维场景,这前提是我们已经给定了图形绘制,纹理,材质,灯光,摄像机等这些的配置信息,最后得到的是图形图像。 2.模式识别 模式识别则是从特征空间到类别空间的变换。研究内

龙在天涯 9588

Python之OpenGL笔记(17):键盘鼠标控制摄像机移动旋转

一、目的 1、键盘控制摄像机自由移动; 2、鼠标控制摄像机旋转; 3、鼠标滚轮放大缩小视野。 二、程序运行结果 三、自由移动 view = lookAt(cameraPos, cameraPos + cameraFront, cameraUp) cameraPos为摄像机位置 cameraPos + cameraFront为物体位置   当我们按下WASD键,摄像机的位置都会相应更新。如果我们希...

dalong10的专栏 4961

Windows 10/11下R与RStudio最新版安装避坑指南(含镜像加速配置)

本文提供了Windows 10/11系统下R与RStudio最新版的详细安装指南,包含镜像加速配置和常见问题解决方案。通过分步教程帮助用户避开安装陷阱,优化开发环境设置,特别适合国内用户快速搭建高效的数据分析平台。

weixin_29065959的博客 1008

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

学习如何定义一个射击类游戏的第三人称摄像机

航行的土豆的博客 997

从零开始:Doherty功率放大器的ADS仿真实践指南

本文详细介绍了Doherty功率放大器在ADS中的仿真设计流程,从基础原理到实际工程应用。通过负载调制技术,Doherty结构显著提高了功率放大器的效率,特别适合处理高峰均比信号。文章包含ADS环境搭建、对称与非对称设计、常见问题调试等实用内容,为射频工程师提供全面的实践指南。

weixin_29313547的博客 694

轻量级替代方案:用AIFlowy + Ollama在本地快速搭建一个可用的AI智能体平台

本文介绍了如何使用AIFlowy和Ollama在本地快速搭建轻量级AI智能体平台,涵盖从环境准备到智能体集成的全流程。通过简化部署步骤和优化性能,15分钟内即可完成搭建,适用于原型验证和小团队协作,显著提升开发效率。

weixin_29207533的博客 223

计算机图形学(Computer Graphics)的学习笔记

计算机图形学是研究通过计算机将数据转换为图形,并在专门的显示设备上显示的原理,方法和技术的学科。

伯努利 2万+

手把手教你用WF100DPZ数字压力传感器搞定I2C/SPI通信(附完整寄存器解析)

本文详细解析了WF100DPZ数字压力传感器的I2C与SPI通信驱动方法,涵盖硬件连接、寄存器配置、数据读取流程及常见问题排查。该传感器内置24位ADC和出厂校准,通过实战代码演示了如何稳定获取高精度压力与温度数据,帮助开发者快速集成到嵌入式项目中。

weixin_28285943的博客 378

计算机图形学

计算机图形学

ProgramNovice的博客 662

CANOCO5.0实现冗余分析(RDA)最详细步骤

在地理及生态领域会常使用RDA分析,RDA的实现路径也有很多,今天介绍一下CANOCO软件的实现方法。1.不同样点和环境因子之间夹角是锐角 是正相关,是钝角是负相关。2.夹角越大 说明相关性较小,夹角越小,相关性越大。得有不同的物种或者样点数值,再加上环境因子数据。3.箭头越长 相关性越大。时间调整到2010年。

Along6的博客 1万+

SQL基础:HQL之常用的行列转换应用总结

行列转换是数据开发者的基本技能,也是面试重点,在数据开发中处处可见,本文对常见的几种情况进行了总结,包括了多行转多列,多行转单列,多列转多行,单列转多行的几种情况,并给出了解决思路和方法,读者可根据本文给出的思路灵活应对业务中遇到的问题。

石榴姐yyds 1800

计算机图形学——大作业

计算机图形学大作业 一、实验要求 绘制一个简单的三维场景,可以是室内:卧室,办公室,教室,也可以是室外:运动场,公园等,加上光照效果,简单的纹理映射,透视投影;不能过于简单;可以加动画、鼠标和键盘交互。 上交材料: project和word文档(具体内容展示,思路和心得) 二、实验思路 首先初始化窗口,定义摄像机坐标与视口坐标,利用实验二的知识内容绘制三维立体模型,定义每一个模型的坐标值以及利用变换函数实现相对位置的放置;利用实验三中的知识给整个场景进行灯光的设置;然后使用实验四中的代码实...

加载中....... 2万+

YOLOv8【第七章:损失函数篇·第1节】一文搞定,IoU系列损失函数!

🏆 本文收录于 《YOLOv8实战:从入门到深度优化》 专栏。该专栏系统复现并梳理全网各类 YOLOv8 改进与实战案例(当前已覆盖分类 / 检测 / 分割 / 追踪 / 关键点 / OBB 检测等方向),坚持持续更新 + 深度解析,质量分长期稳定在 97 分以上,可视为当前市面上 覆盖较全、更新较快、实战导向极强 的 YOLO 改进系列内容之一。

**My Coding Family** 1202

【斯坦福大学】计算机图形学实验室的概况

在北美各个大学网站中,我感觉最经常被访问的图形学实验室就是斯坦福大学计算机系的图形学实验室。 网址:http://graphics.stanford.edu/ 该实验室目前最重要的三个研究项目是: 【光场和计算摄影学】 【第二代摄像机】 【光场显微镜】 其他旧的项目有: 【体渲染】【3D传真机】【图像压缩,分析与合成】【多摄像机阵列】【实时可编程着色】【渲染算法集】【互动工作

舒夜无痕--成为更好的自己 5846

四麦轮机器人精准运动控制系统开发方案

本文提出了一套四麦轮机器人精准运动控制系统的开发方案,基于鲸鱼机器人专业版平台实现高精度的直线行走和平移功能。系统采用双闭环PID控制架构(速度环与距离环),结合编码器和IMU传感器反馈,通过图形化编程与C语言混合开发实现。方案详细阐述了四麦轮运动学模型、控制逻辑设计、传感器数据处理及核心算法实现,目标在3米行程内达到距离误差±10mm、角度偏差±2°的精度。全文涵盖理论分析、系统设计到程序实现的全流程,为机器人精准运动控制提供了完整解决方案。

huanghm88的专栏 275

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

【深圳大学计算机图形学】实验补充二 层级建模-人形机器人

1.参考上次上机课的内容绘制每一个节点,完成torso(), head(), left_upper_arm(), left_lower_arm(), right_upper_arm(), right_lower_arm(), left_upper_leg(), left_lower_leg(), right_upper_leg(), right_lower_leg()函数。2.上次实验课的display()函数,该函数调用每个节点的绘制方法,同时构建各个节点的局部变化矩阵;

归忆_AC的博客 1922

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

计算机图形学 | 实验六:旋转立方体

计算机图形学 | 实验六:旋转立方体

ProgramNovice的博客 1806

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

计算机图形学大作业c语言,《高级计算机图形学》大作业的报告

《高级计算机图形学》大作业报告1图形学与图形系统简述计算机图形学是一种使用数学算法将二维或三维图形转化为计算机显示器的栅格形式的科学。它的主要研究内容就是研究如何在计算机中表示图形、以及利用计算机进行图形的计算、处理和显示的相关原理与算法。图形通常由点、线、面、体等几何元素和灰度、色彩、线型、线宽等非几何属性组成。从处理技术上来看,图形主要分为两类,一类是基于线条信息表示的,如工程图、等高线地图、...

weixin_33716865的博客 1412

SWJTU 计算机图形学实验5 三维基本图形生成及变换

SWJTU 计算机图形学实验5 的相关内容及资源

yixianho的博客 597

计算机图形学笔记-视图矩阵推导过程

计算机图形学笔记-视图矩阵推导过程 视变化,是将世界坐标系下的坐标变化到摄像机坐标系,视变换是通过乘以视图矩阵实现的。 我们要知道视并不存在真正的摄像机,只不过是在世界坐标系里面选择一个点,作为摄像机的位置。 然后根据一些参数,在这个点构建一个坐标系。然后通过视图矩阵将世界坐标系的坐标变换到摄像机坐标系下。 我们先简单说一下我们的目标,在世界坐标系中选取一点作为观察点,并以观察点建立一个坐标系...

【黑键】 3179
上一篇: Leetcode2511. 最多可以摧毁的敌人城堡数目
下一篇: Leetcode697. 数组的度
UestcXiye
博客等级 码龄8年 9032粉丝 1306原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UestcXiye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值