OpenGL 空间、投影、视角
Space、Projection、View
程序运行效果
空间 Space ?
在电脑中,空间就是某种坐标系!
Space = Coordinate
公式:
Vclip = Mprojection ⋅ Mview ⋅ Mmodel ⋅ Vlocal
V: Vector、 M: Matrix、local: Vertex
反方向(右到左)看过来:
local代表本地的顶点数据---->
---->经由Model Matrix转换得到---->
---->[World Space世界空间] ?坐标系的转换!---->
而得到的世界空间的坐标系我们---->
---->经由View Matrix转换得到---->
---->[View Space观察空间] ? (可以是Camera摄像机) ---->
而得到的观察空间坐标系我们---->
---->经由Projection Matrix转换得到---->
---->[Clip Space剪裁空间] ? (空间很大,但屏幕有限,so…) ---->
---->经由Viewport Transform视口变换 ---->
----> [Screen Space显示器屏幕(2D)]
(学习OpenGL或者Direct3D,我们可以先不要关注线性代数、离散数学等内容,可以先将流程与代码搞清楚就好…)
dont ask why,first how to do!
shader 代码:
#version xxx xxx
layout (location = n) in vec3 vert;uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;void main()
{gl_Position = projection * view * model * vec4(vert, 1.0f);
}
注意:矩阵以及向量相乘的这个顺序不能改变!
投影、视角
代码:
// projection投影矩阵:角度(45度) 视野FOV(Field of View)、宽高比、NearPlane近平面、FarPlane远平面
glm::mat4 proj = glm::mat4(1.0f);
proj = glm::perspective(glm::radians(45.0f), (float)800/(float)600, near, far);
ourShader.setMat4("proj", proj);glm::mat4 view = glm::mat4(1.0f);
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
ourShader.setMat4("view", view);
glm::perspective(fov, aspect-ratio, near-plane, far-plane);
透视投影:(视锥、可视空间的大平截头体)
参数 | 描述 |
---|---|
fov | field of view 视野 |
aspect-ratio | 宽高比 |
near-plane | 近平面 |
far-plane | 远平面 |
FOV这个参数其实玩过摄影的哥们,我说相机镜头的焦段的话,应该很容以就理解了。
我们人类眼睛的焦段通常为:45~55mm,人像头通常为:85mm,而大小三元头中的长焦头通常为:70-200mm,广角:18-28mm,超广角:12-14mm。
说这个,仅为我个人举个简单的例子,镜头的焦段,我们可以理解为镜头的FOV,也就是镜头的视野。
镜头是焦段越小,视野越广,所以超广角通常都是14mm以内。而焦段越长,视野越小,但是与目标成像距离越近(望远镜)所以拍摄远处的特写,例如飞鸟,野生动物,往往200mm焦段的镜头都不够用,400mm以上的大炮随处见!
广角人像效果(我自己西藏自驾游时拍的):
对于镜头来说,可视角度越大,画面的透视越严重。这个原理也适用3D渲染。
可可西里的那张就是14mm拍摄,羊卓雍错第3张是70-200mm的镜头,而布达拉宫第一张是14-28mm拍摄,焦段应该是28mm。
所以我们在传入FOV参数的时候:
fov角度的变化代表我们摄像机镜头焦段的变化。可以拉近拉远。
宽高比,决定了视野剪裁,毕竟我们渲染的内容最终要呈现到屏幕。
近/远平面的范围,我们可以理解为可视的范围,现实中,镜头成像的内容是模拟量,转数字量(采样)细节越小,越看不清。但哪怕是几十公里外的内容也能被拍摄到,至少不清晰。
但在3D渲染中,这个范围外的内容实会被剪裁掉。也就是只显示近/远平面的范围内的内容。
用过maya、3dsmax、softimage这类3D艺术软件的朋友如果接触过超大场景组装的话会发现,通常摄像机的参数中,near会调节到最小,而far会调节到最大,否则软件中也会出现剪裁象形。即超出这个范围的将不可见。
正交投影与透视投影:
// projection投影矩阵:角度(45度) 视野FOV(Field of View)、宽高比、NearPlane近平面、FarPlane远平面
glm::mat4 proj = glm::mat4(1.0f);
proj = glm::perspective(glm::radians(45.0f), (float)800/(float)600, near, far);
ourShader.setMat4("proj", proj);glm::mat4 view = glm::mat4(1.0f);
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
ourShader.setMat4("view", view);// 渲染容器
glBindTexture(GL_TEXTURE_2D, texture);
glBindVertexArray(VAO);
// glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
// glDrawArrays(GL_TRIANGLES, 0, 36);for (unsigned int i = 0; i < 10; i++)
{// transform 就是Model Matrixglm::mat4 transform = glm::mat4(1.0f);transform = move(transform,cubePositions[i].x,cubePositions[i].y,cubePositions[i].z);GLfloat angle = 20.0f * i;if (i % 3 == 0){transform = rotate(transform, (GLfloat)glfwGetTime(), 1.0f, 0.3f, 0.5f);}else{transform = rotate(transform, glm::radians(angle) * (GLfloat)glfwGetTime(), 5.0f, 1.0f, 2.0f);}ourShader.setMat4("transform", transform);glDrawArrays(GL_TRIANGLES, 0, 36);
}
Shader Program Code:
#version 330 core
layout (location = 0) in vec3 aPos;
// layout (location = 1) in vec3 aColor;
layout (location = 1) in vec2 aTexCoord;out vec3 ourColor;
out vec2 TexCoord;uniform mat4 transform;
uniform mat4 view;
uniform mat4 proj;void main()
{// transform = model(matrix)gl_Position = proj * view * transform * vec4(aPos, 1.0f);// ourColor = aColor;TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}
全部代码:
OpenGL 空间、投影、视角相关推荐
- 深入理解OpenGL之投影矩阵推导
深入理解OpenGL之投影矩阵推导 OpenGL流水线中的投影矩阵以及坐标变换 OpenGL中,投影矩阵在Vertex shader中使用,用于变换顶点.一般和Model, View矩阵结合成MVP矩 ...
- 采用空间投影的深度图像点云分割
本文摘自于:郭清达,全燕鸣. 采用空间投影的深度图像点云分割[J]. 光学学报, 2020, 40(18): 1815001 编辑:新机器视觉 点云分割是点云处理的一个关键环节,其分割质量决定了目标测 ...
- 脑电分析系列[MNE-Python-10]| 信号空间投影SSP数学原理
projector(投影)和投影背景 projector(投影)(简称proj),也称为信号空间投影(SSP),定义了应用于空间上的EEG或MEG数据的线性操作. 可以将该操作看做是一个矩阵乘法,通过 ...
- Python-EEG工具库MNE中文教程(10)-信号空间投影SSP数学原理
目录 projector(投影)和投影背景 案例解释投影原理 导入工具库 什么是projector(投影)? 计算正交平面 使用SVD计算投影矩阵 本分享为脑机学习者Rose整理发表于公众号:脑机接口 ...
- 脑电分析系列[MNE-Python-11]| 信号空间投影SSP 应用
信号空间投影(SSP) 在前面一篇分享(脑电分析系列[MNE-Python-10]| 信号空间投影SSP数学原理)中提到,投影矩阵将根据您试图投射出的噪声种类而变化.信号空间投影(SSP)是一种通过比 ...
- OpenGL学习: 投影矩阵和视口变换矩阵(math-projection and viewport matrix)
转自:https://blog.csdn.net/wangdingqiaoit/article/details/51589825 本文主要翻译并整理自 songho OpenGL Projection ...
- OpenGL中投影矩阵(Projection Matrix)详解
在游戏开发中,一个物体模型从它自身的坐标系转换至我们在屏幕上所见的样子,需要进行一系列的坐标变换以及其他的操作.该过程称为渲染管线.以OpenGL为例: 该过程在以前是被封装的,不能访问.但是现在我们 ...
- Android App开发中OpenGL三维投影的讲解及实现(附源码和演示 简单易懂)
运行有问题或需要源码请点赞关注收藏后评论区留言~~~ 一.三维投影 OpenGL,定义了跨语言跨平台的图形程序接口,对于Android开发者来说,OpenGL就是用来绘制三维图形的技术手段.当然Ope ...
- OpenGL空间(坐标系)变换
网友的<3D图形学的学习策略>一文使我深受启发,在图形学以及openGL学习方面给了我很有价值的指导性意见,在此对前辈们的不吝赐教表示感激,谢谢你们的无私分享. 如文章所说,API是工具, ...
最新文章
- python画图标题_使用pyplot.matshow()函数添加绘图标题
- ubuntu+php+mysql+apache安装配置
- ORA-01555 snapshot too old
- 论文笔记——N2N Learning: Network to Network Compression via Policy Gradient Reinforcement Learning...
- Android java.lang.IllegalArgumentException: You cannot start a load for a destroyed activity
- date javascript 时区_第23节 Datejs 日期库-Web前端开发之Javascript-零点程序员-王唯
- Jquery中$(document).ready(function(){ })函数的使用详解
- spring源码分析第二天------spring系统概述以及IOC实现原理
- android 手机号码显示加空格,Android实现输入手机号时自动添加空格
- 用c语言写出一个榜单程序,C语言依然位居榜单前列,依然值得程序员学习
- enum python_python 枚举Enum
- git源码安装后报错:bash: /usr/bin/git: No such file or directory
- HTML动态视频背景全代码
- i2c驱动之at24c08(1)
- 敏捷转型中的敏态与稳态
- asio ssl 笔记
- 赤峰市田家炳中学2021高考成绩查询,2021年常州各高中高考成绩排名及放榜最新消息...
- Linux查看mac地址
- Iphone被刷机后用电信卡提示未激活,移动联通卡可以正常使用
- 我在首席数据官年会上的演讲实录