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 空间、投影、视角相关推荐

  1. 深入理解OpenGL之投影矩阵推导

    深入理解OpenGL之投影矩阵推导 OpenGL流水线中的投影矩阵以及坐标变换 OpenGL中,投影矩阵在Vertex shader中使用,用于变换顶点.一般和Model, View矩阵结合成MVP矩 ...

  2. 采用空间投影的深度图像点云分割

    本文摘自于:郭清达,全燕鸣. 采用空间投影的深度图像点云分割[J]. 光学学报, 2020, 40(18): 1815001 编辑:新机器视觉 点云分割是点云处理的一个关键环节,其分割质量决定了目标测 ...

  3. 脑电分析系列[MNE-Python-10]| 信号空间投影SSP数学原理

    projector(投影)和投影背景 projector(投影)(简称proj),也称为信号空间投影(SSP),定义了应用于空间上的EEG或MEG数据的线性操作. 可以将该操作看做是一个矩阵乘法,通过 ...

  4. Python-EEG工具库MNE中文教程(10)-信号空间投影SSP数学原理

    目录 projector(投影)和投影背景 案例解释投影原理 导入工具库 什么是projector(投影)? 计算正交平面 使用SVD计算投影矩阵 本分享为脑机学习者Rose整理发表于公众号:脑机接口 ...

  5. 脑电分析系列[MNE-Python-11]| 信号空间投影SSP 应用

    信号空间投影(SSP) 在前面一篇分享(脑电分析系列[MNE-Python-10]| 信号空间投影SSP数学原理)中提到,投影矩阵将根据您试图投射出的噪声种类而变化.信号空间投影(SSP)是一种通过比 ...

  6. OpenGL学习: 投影矩阵和视口变换矩阵(math-projection and viewport matrix)

    转自:https://blog.csdn.net/wangdingqiaoit/article/details/51589825 本文主要翻译并整理自 songho OpenGL Projection ...

  7. OpenGL中投影矩阵(Projection Matrix)详解

    在游戏开发中,一个物体模型从它自身的坐标系转换至我们在屏幕上所见的样子,需要进行一系列的坐标变换以及其他的操作.该过程称为渲染管线.以OpenGL为例: 该过程在以前是被封装的,不能访问.但是现在我们 ...

  8. Android App开发中OpenGL三维投影的讲解及实现(附源码和演示 简单易懂)

    运行有问题或需要源码请点赞关注收藏后评论区留言~~~ 一.三维投影 OpenGL,定义了跨语言跨平台的图形程序接口,对于Android开发者来说,OpenGL就是用来绘制三维图形的技术手段.当然Ope ...

  9. OpenGL空间(坐标系)变换

    网友的<3D图形学的学习策略>一文使我深受启发,在图形学以及openGL学习方面给了我很有价值的指导性意见,在此对前辈们的不吝赐教表示感激,谢谢你们的无私分享. 如文章所说,API是工具, ...

最新文章

  1. python画图标题_使用pyplot.matshow()函数添加绘图标题
  2. ubuntu+php+mysql+apache安装配置
  3. ORA-01555 snapshot too old
  4. 论文笔记——N2N Learning: Network to Network Compression via Policy Gradient Reinforcement Learning...
  5. Android java.lang.IllegalArgumentException: You cannot start a load for a destroyed activity
  6. date javascript 时区_第23节 Datejs 日期库-Web前端开发之Javascript-零点程序员-王唯
  7. Jquery中$(document).ready(function(){ })函数的使用详解
  8. spring源码分析第二天------spring系统概述以及IOC实现原理
  9. android 手机号码显示加空格,Android实现输入手机号时自动添加空格
  10. 用c语言写出一个榜单程序,C语言依然位居榜单前列,依然值得程序员学习
  11. enum python_python 枚举Enum
  12. git源码安装后报错:bash: /usr/bin/git: No such file or directory
  13. HTML动态视频背景全代码
  14. i2c驱动之at24c08(1)
  15. 敏捷转型中的敏态与稳态
  16. asio ssl 笔记
  17. 赤峰市田家炳中学2021高考成绩查询,2021年常州各高中高考成绩排名及放榜最新消息...
  18. Linux查看mac地址
  19. Iphone被刷机后用电信卡提示未激活,移动联通卡可以正常使用
  20. 我在首席数据官年会上的演讲实录

热门文章

  1. 综合设计一个OPPE主页--页面的搜素欧珀部分的样式
  2. C++ Primer plus学习总结(未完成)
  3. 如何认识网络变压器芯片引脚图及网络变压器外围BOB-SMITH电路
  4. 华为三层交换机VLAN配置
  5. 设计登录校园网网关java,基于web认证校园网共享实例
  6. java 方法重写概念
  7. 【VerySky原创】RPR_ABAP_SOURCE_SCAN
  8. 摄像头sensor的数据输出格式。
  9. 亚马逊店铺注册注意事项,亚马逊无货源模式的到来会成为热门吗?
  10. 使用CNN生成图像先验,实现更广泛场景的盲图像去模糊