【计算机图形学】 a.世界坐标系 - > 相机坐标系 b.正交投影和透视投影 c.视椎体

news/2024/10/30 13:52:37/

总结:计算机图形学更适合精通高等数学和线性代数的美術理论生

文章目录

  • 虚拟照相机观察变换
    • 相机的控制
  • 【世界坐标系 - > 相机坐标系】
  • 总 - 投影变换
  • 【正交投影】 - Orthographic Projection
      • 视景体(裁剪体)
      • 投影规范化(Projection Normalization)
  • 【透视投影】 - Perspective Projection
  • 【视椎体】怎么理解:
      • 两种定义透视投影视见体
        • 类似于正交投影的棱台视见体 【frustum】
        • 利用视域(FoV,Field of View)定义的视见体 【perspective】
      • 投影规范化
  • 【四种正方体对比】:模型变换 ,正交投影,棱台指定视见体的透视投影 ,视域指定视见体的透视投影

虚拟照相机观察变换

在这里插入图片描述
在这里插入图片描述

  • 投影线相交于投影中心(COP:Center of Projection),而COP对应于人眼或者相机镜头,从COP点发出投影光线将物体投影在投影平面上而成像。

  • 只要顶点着色器输出的顶点位于裁剪体(或视见体)内部,那么这些顶点会被送入绘制流水线后面的光栅化模块。
    【说人话就是东西如果在视野内,那么就画出来】

相机的控制

如果我们加入自定义的相机姿态,那么对相机的控制则尤为重要,因为相机的位置和朝向将决定怎么发出投影射线而将物体投影到投影平面上。

  1. 设置照相机的位置和方向,该操作由模-视变换来完成,当顶点经过该变换之后将位于相机坐标系中

  2. 使用投影变换,也就是说把指定的投影(正交投影或透视投影)应用到顶点上。并将默认的视见体内部对象变换到指定的裁剪立方体的内部

在这里插入图片描述

【世界坐标系 - > 相机坐标系】

所谓变换就是设置一个矩阵,然后乘以三维顶点的坐标(考虑齐次坐标系),得到变换之后的坐标值。


模-视变换是建模变换和观察变换的级联

  • 建模变换矩阵 将对象变换到世界坐标
    (一般来说,建模变换矩阵是单位阵,我们不需要额外处理。即 m o d e l M a t r i x = I 4 modelMatrix=I_4 modelMatrix=I4)
  • 观察变换 将世界坐标转换到相机坐标

对于照相机来说,其初始方向通常指向z轴负方向,这样才能看见位于相机前方的模型。
考虑一个位于原点的对象,由于照相机初始位置也在原点,方向指向z轴负方向,
如果该对象需要在z轴正方向的投影平面(在OpenGL中通常是近裁剪平面)上成像,那么必须要将相机沿着z轴正方向往后移动一定距离。

  • 相机移动之后的位置称为观察参考点(VRP,View Reference Pint)

考虑采用规范化变换(Normalization Transformation)来表示相机坐标系并指定相机的位置

  • 观察平面法向量(VPN:View-plane Normal)

  • 观察正向向量(VUP:View-up Vector)

其中VPN指定了相机的胶片平面,而平面是由其法向量决定的。如果只是指定了VPN,相机还可以绕VPN旋转,此时我们再加上VUP,就能完全固定一个相机的位置了。

在这里插入图片描述

  • 视点 :相机位置 e = ( e y e x , e y e y , e y e z ) e=(eye_x,eye_y,eye_z ) e=(eyex,eyey,eyez)

  • 参考点 :相机指向的另一个点 a = ( a x , a y , a z ) a=(a_x,a_y,a_z ) a=(ax,ay,az)

那么 V P N = e − a VPN = e-a VPN=ea


归一化(normalize): n = V P N ∣ V P N ∣ \mathbf{n}= \frac{VPN}{|VPN|} n=VPNVPN

正是因为归一化,后面点积这个向量,便直接得出该新坐标轴上的投影(其实除以了一个 1)

相机看向的是 ( 0 , 0 , 0 ) (0,0,0) (0,0,0)

相机的上方即VUP 一直是 ( 0 , 1 , 0 ) (0,1,0) (0,1,0)

那么做叉积×即可得出VPN


设VUP,VPN归一化后为 u \mathbf{u} u , v \mathbf{v} v

通过采用u,n,v即可定义出相机的观察变换矩阵

viewMatrix = [ u 1 u 2 u 3 0 v 1 v 2 v 3 0 n 1 n 2 n 3 0 0 0 0 1 ] \text{viewMatrix} = \begin{bmatrix} u_1 & u_2 & u_3 & 0 \\ v_1 & v_2 & v_3 & 0 \\ n_1 & n_2 & n_3 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} viewMatrix= u1v1n10u2v2n20u3v3n300001

还需要将相机从坐标原点移动到视点 (因为标架是eye在原点旋转的 —— 向量投影)

平移矩阵

T = [ 1 0 0 − x 0 1 0 − y 0 0 1 − z 0 0 0 1 ] T = \begin{bmatrix} 1 & 0 & 0 & -x \\ 0 & 1 & 0 & -y \\ 0 & 0 & 1 & -z \\ 0 & 0 & 0 & 1 \end{bmatrix} T= 100001000010xyz1

(这里的 x y z 其实就是 eye的反,不过在新的标架下,eye也要变换。(做点积,上面归一化有提及原理))

所以最终的相机观察矩阵 viewMatrix :
[ u x u y u z − x u x − y u y − z u z v x v y v z − x v x − y v y − z v z n x n y n z − x n x − y n y − z n z 0 0 0 1 ] \begin{bmatrix} u_x & u_y & u_z & -x u_x - y u_y - z u_z \\ v_x & v_y & v_z & -x v_x - y v_y - z v_z \\ n_x & n_y & n_z & -x n_x - y n_y - z n_z \\ 0 & 0 & 0 & 1 \end{bmatrix} uxvxnx0uyvyny0uzvznz0xuxyuyzuzxvxyvyzvzxnxynyznz1

在这里插入图片描述

总 - 投影变换

在经过三维物体的模-视变换后,场景中的三维物体即被放在了相机能够观察到的位置。
而投影变换的目的则是定义一个视景体(View Volume),使得视景体外多余的部分被裁减掉,最终进入到投影平面上的只是视景体内的部分

投影包含正交投影(Orthographic Projection)和透视投影(Perspective Project)两种。




【正交投影】 - Orthographic Projection

将在世界坐标系所有单位的 z 坐标变为 0 ,那他们就在 x 轴和 y轴所在的平面上了

或者将 x 轴和 y轴所在的平面 平移,移动到哪里,就只能看到哪里的“切面”


那么假如有一个球,你只要不切到这个球,那么你看到的永远是一个圆。

在这里插入图片描述

视景体(裁剪体)

在这里插入图片描述

投影规范化(Projection Normalization)

在OpenGL的渲染管线中定义了一个标准视景体 :

x = ± 1 ; y = ± 1 ; z = ± 1 x=±1;y=±1;z=±1 x=±1;y=±1;z=±1

在这里插入图片描述

(使用的投影矩阵)

在这里插入图片描述




【透视投影】 - Perspective Projection

人类看到的,相机拍到的二维平面却能看出三维的效果

如下图

在这里插入图片描述

比如左上角的正方体,红色边应该是平行的,但是无限延长,会交于一点:

在这里插入图片描述

你可以去楼道观察两边的墙壁,或者拍张照比划比划。




【视椎体】怎么理解:

这就是视椎体(Frustum):
在这里插入图片描述
表示相机能看到的区域。

(你可以用左右手张开地挡在自己的头前方模拟这个视野,其实汽车车灯照明效果就是这样的)

相比于正交投影的视景体,对于透视投影,我们也需要设置一个视景体来裁剪三维物体如下,
也就是说在视景体内部的三维物体才能被投影到投影平面上,剩下超出的部分则被裁减掉。
在透视投影中,由于投影中心在理想情况下是一个点,所以形成的视景体构成一个截头椎体(Frustum)。

在这里插入图片描述

两种定义透视投影视见体

类似于正交投影的棱台视见体 【frustum】

在这里插入图片描述

利用视域(FoV,Field of View)定义的视见体 【perspective】

在这里插入图片描述

投影规范化

在这里插入图片描述




【四种正方体对比】:模型变换 ,正交投影,棱台指定视见体的透视投影 ,视域指定视见体的透视投影

类:各种参数放在一起喽
在这里插入图片描述

相机视角及运动轨迹:

在这里插入图片描述

观察:

在这里插入图片描述

  • 左上 : 模型变换
  • 右上 : 正交投影
  • 左下 : 棱台指定视见体的透视投影
  • 右下 : 视域指定视见体的透视投影

我们不断加大 scale,对于 模型变换 来说,是增大尺寸,即靠近物体甚至穿透。由于相机始终看向中心,最终会穿过中点看回来。如图,现在看到的是背面。

而对于 正交投影来说 ,是“减小”可视空间(“选择更小的区域并铺满窗口”,即只看这区域,即放大了)。减为负的,可视空间"反向放大",看到的即如图,x和y都变为 -x -y

对于下面两个透视投影,左边棱台可见看起来更大一点,正是因为near离得近。
(见本文的“两种定义透视投影视见体”)

在这里插入图片描述


http://www.ppmy.cn/news/1543118.html

相关文章

Win11GBK, idea2024.2.4, 使用Gradle8.8本地安装构建,不使用包装器, 解决utf-8乱码问题, 笔记241028

Win11GBK, idea2024.2.4, 使用Gradle8.8本地安装构建,不使用包装器, 解决utf-8乱码问题, 笔记241028 解决办法: 在 gradle.properties 配置文件中, 设置jvm启动项参数, 字符编码设为gbk, -Dfile.encodinggbk 与操作系统保持一致; -Dfile.encodinggbk如: org.gradle.jvmargs-Xm…

【Linux】信号量,线程池

目录 信号量 初始化​编辑 销毁 等待 发布 基于环形队列的生产消费模型 问题解答: 代码: 线程池 线程池的实现 (1)初始化,构造大致框架 (2)创建线程 (3)创建任…

单细胞数据分析(三):单细胞聚类分析

文章目录 介绍目的加载R包数据链接导入数据可视化聚类选择聚类分辨率值输出结果系统信息介绍 单细胞聚类分析是一种用于解析单细胞RNA测序(scRNA-seq)数据的方法,旨在将成千上万个单细胞根据它们的基因表达模式分组到不同的类别或“簇”中。每个簇代表了具有相似基因表达特…

rnn/lstm

tip:本人比较小白,看到july大佬的文章受益匪浅,现在其文章基础上加上自己的归纳、理解,以及gpt的答疑,如果有侵权会删。 july大佬文章来源:如何从RNN起步,一步一步通俗理解LSTM_rnn lstm-CSDN博…

微服务的发布策略与设计约束

分布策略微服务架构中的蓝绿发布和金丝雀发布策略是两种常见的版本控制和发布管理方法,旨在提高软件的发布安全性和可用性。 蓝绿发布 概念:蓝绿发布是一种将两个相同的环境(蓝和绿)进行交替使用的发布策略。在某个时刻,只有一个环境在处理用户请求,而另一个环境则处于…

EJB项目如何升级SpringCloud

记录某金融机构老项目重构升级为微服务过程1 如何从EJB架构拆分微服务 这个非常有趣的过程,整个过程耗时大致接近半年时光,需要考虑到重构升级保留原来的业务线,而且还要考虑后续的维护成本,保留现有的数据库表结构,…

vue3父组件控制子组件表单验证及获取子组件数值方法

1、关键部分的代码如下&#xff0c;我努力交代清楚了&#xff0c;希望能让大家看懂。 <template><KeepAlive><component ref"comp" :is"compNames[steps[compIndex].comp]" /></KeepAlive><el-button click"prevBtn"…

流媒体协议.之(RTP,RTCP,RTSP,RTMP,HTTP)(三)

本文&#xff0c;分析&#xff0c;贴出一些博主的关键源码 git地址&#xff1a;https://github.com/ireader/media-server?tabreadme-ov-file 网络上也有开源的库&#xff0c;可以用这些。 推流协议库有&#xff0c;librtmp&#xff0c;librtp&#xff0c;jrtplib等&#xf…