文章目录

  • 一些术语
    • 齐次坐标可除性
    • 简单的线性插值
  • 透视投影变换
    • 1. 用透视变换矩阵把顶点从视锥体中变换到裁剪空间的CVV中。
    • 2. CVV裁剪完成后进行透视除法
  • 重要的简化
  • 程序处理与理论的不同
  • 参考链接
  • 转载请注明出处

一些术语

  • fov即视野,是视锥体在xz平面或者yz平面的开角角度,具体哪个平面都可以。OpenGLD3D都使用yz平面。
  • aspect即投影平面的宽高比。
  • far是远裁剪平面的距离。

左边是在xz平面计算视锥体,右边是在yz平面计算视锥体:


xz平面计算视锥体, top = right / aspect使用了除法, 在yz平面计算视锥体, right = top x aspect, 这也许就是为什么图形APIs采用yz平面的原因


齐次坐标可除性

对于一个普通坐标的点P=(Px, Py, Pz),有对应的一族齐次坐标 (wPx,wPy,wPz,w)(wPx, wPy, wPz, w)(wPx,wPy,wPz,w),其中 www 不等于零。比如,P(1,4,7)P(1, 4, 7)P(1,4,7) 的齐次坐标有 (1,4,7,1)、(2,8,14,2)、(−0.1,−0.4,−0.7,−0.1)(1, 4, 7, 1)、(2, 8, 14, 2)、(-0.1, -0.4, -0.7, -0.1)(1,4,7,1)、(2,8,14,2)、(−0.1,−0.4,−0.7,−0.1) 等等。因此,如果把一个点从普通坐标变成齐次坐标,给 x,y,zx,y,zx,y,z 乘上同一个非零数 www,然后增加第4个分量 www;如果把一个齐次坐标转换成普通坐标,把前三个坐标同时除以第4个坐标,然后去掉第4个分量

简单的线性插值

基本思想是:给一个x属于*[a, b],找到y属于[c, d],使得xa的距离比上ab长度所得到的比例,等于yc的距离比上cd*长度所得到的比例,用数学表达式描述很容易理解:

此外,如果x不在[a, b]内,比如 x<ax < ax<a 或者 x>bx > bx>b,则得到的y也是符合y < c或者y > d,比例仍然不变,插值同样适用。

透视投影变换

透视投影是3D固定流水线的重要组成部分,是将相机空间中的点从视锥体(frustum) 变换到 规则观察体(Canonical View Volume)

  • 透视投影变换由两步组成:
1. 用透视变换矩阵把顶点从视锥体中变换到裁剪空间的CVV中。
2. CVV裁剪完成后进行透视除法

上图是右手坐标系中顶点在相机空间中的情形。设 P(x,z) 是经过相机变换之后的点(是处于相机坐标系中),视锥体由eye——眼睛位置,np——近裁剪平面,fp——远裁剪平面组成。N是眼睛到近裁剪平面的距离F是眼睛到远裁剪平面的距离投影面可以选择任何平行于近裁剪平面的平面,这里我们选择近裁剪平面作为投影平面。设 P’(x’,z’) 是投影之后的点,则有 z’ = -N。通过相似三角形性质,我们有关系:

这样,我们便得到了P投影后的点P’

从上面可以看出,投影的结果 z’z’z’ 始终等于 −N-N−N,在投影面上。实际上,z’z’z’ 对于投影后的 P’P’P’ 已经没有意义了,这个信息点已经没用了。但对于3D图形管线来说,为了便于进行后面的片元操作,例如z缓冲消隐算法,有必要把投影之前的 zzz 保存下来,方便后面使用。因此,我们利用这个没用的信息点存储 zzz,处理成:

  • 上面的操作是只用普通投影变换, 下面结合CVV进行思考,假入能够把上面写成这个形式

  • 这里我可以理解成是在透视投影的前提下向CVV靠拢, 通过这个变换, 想把 z 限制在 -1~1 之间, 下面就可以非常方便的用矩阵以及齐次坐标理论来表达投影变换:

其中 P’代表的是 P 映射到单位立方体后的投影点

把 (Nx,Ny,az+b,−z)T(N_x, N_y, az+b, -z)^T(Nx​,Ny​,az+b,−z)T 变为 (−Nx/z,−Ny/z,−(az+b)/z,1)T(-N_x/z, -N_y/z, -(az+b)/z, 1)^T(−Nx​/z,−Ny​/z,−(az+b)/z,1)T 这一步是使用齐次坐标变普通坐标的规则完成的, 在透视投影过程中称为透视除法(Perspective Division), 经过这一步,就丢弃了原始的z值(得到了CVV中对应的z值)

但是为什么要把z写成 −az+bz-\frac{az+b}{z}−zaz+b​ , 因为:

  1. 后面投影之后的光栅化阶段,要通过x’和y’对z进行线性插值,以求出三角形内部片元的z,进行z缓冲深度测试。在数学上,投影后的x’和y’,与z不是线性关系,与1/z才是线性关系。 −az+bz-\frac{az+b}{z}−zaz+b​ 正是 1/z1/z1/z 的线性关系。即 -a+b/z
  2. 后面的CVV是一个x,y,z的范围都为 [-1,1] 的规则体,便于进行多边形裁剪。而我们可以适当的选择系数ab, 使得 −az+bz-\frac{az+b}{z}−zaz+b​ 这个式子在z = -N的时候值为 -1,而在z = -F的时候值为 1,从而在z方向上构建CVV
  • 接下来我们就求出ab

这样我们就得到了透视投影矩阵的初始限制z得到的投影矩阵:

但是xy方向仍然没有限制在 [-1,1] 中, 为了能在xy方向把顶点从Frustum 情形 变成CVV情形,我们开始对 xy 进行处理, 现在得到的是:

我们知道 -Nx / z 的有效范围是投影平面的左右边界值 [left, right], -Ny / z[bottom, top] , 现在使用线性插值把 -Nx / z 属于 [left, right] 映射到 x 属于 [-1, 1] 中,-Ny / z 属于 [bottom, top] 映射到 y 属于 [-1, 1]

  • 线性插值就是说 x 属于 [a, b],找到y属于 [c, d],使得xa的距离比上 ab 长度所得到的比例

上图中 ,左边的x代表的是相机坐标系中的x, 右边是立方体投影下的 x, 对 y 同理。 所谓立方体的投影就是说 在保证透视投影关系的情况下,再变换到立方体范围内, 后续再用正交投影啥的,所以开头的透视投影只是个约束

  • 经过线性插值, 我们得到了最终的投影点:

这里的 P’ 只变化了 xy 分量的形式,az+b-z 是不变的,则我们做透视除法的逆处理–> 给 P’每个分量乘上-z,得到:

而这个结果又是这么来的:

  • 也就是我们通过一个透视变换矩阵M从 视锥体相机坐标系的点 变到了透视投影约束立方体 内的点 , 改写下M, 得到:

  • 变换矩阵也就是这样:

重要的简化

上述矩阵时一般的视见体矩阵,如果视见体是对称的,即满足r=−l,t=−b,则矩阵P可以简化为:

注意到M的最后一行不是***(0 0 0 1)而是 (0 0 -1 0),因此可以看出透视变换不是一种仿射变换,它是非线性的, 但是现在存在的问题是 CVV的宽高是相同的,即宽高比永远是1。容易造成多边形的失真现象, 比如一个投影面上的正方形在CVV的面上可能变成了一个长方形, 解决这个问题的方法就是在对多变形进行透视变换、裁剪、透视除法之后,在归一化的设备坐标(Normalized Device Coordinates)上进行的视口(viewport)变换中进行校正,它会把归一化的顶点之间按照和投影面上相同的比例变换到视口中,从而解除透视投影变换带来的失真现象*。进行校正前提就是要使投影平面的宽高比和视口的宽高比相同

程序处理与理论的不同

假如是理论推导的话, 应该从世界坐标系出发, 通过 R,t 变换到相机坐标系, 然后到图像物理坐标系再到图像像素坐标系, 但是这个并不是程序中使用的方法, 它没有变换到正方体再视口变换这一步, 推荐 B站讲透视投影的一个up的视频

  • 下面是一般程序中使用的透视变换的完整流程图

参考链接

透视投影
视口变换

关于透视投影的深入理解相关推荐

  1. osg-3D世界到屏幕

    标题 前面记录了3D世界如何绘制,今天讨论一下3D世界怎么呈现到屏幕? 1.(模型视图矩阵)model-view matirx 模型矩阵: 用于描述物体在3D世界中的位置,原理是:把模型上所有的顶点从 ...

  2. 相机标定(三)—— 正交投影和透视投影变换

    正交投影和透视投影变换 1. 概述 2. 视锥体 3. 透视投影的目的 4. 透视投影的理解和推导 4.1 透视基本原理 4.2 一点透视 4.3 多点透视 4.4 生成透视投影图的方法 5. 图像处 ...

  3. 人体姿态2018(五)Can 3D Pose be Learned from 2D Projections Alone?

    <Can 3D Pose be Learned from 2D Projections Alone?>论文解读 Abstract 1. Introduction 2. Weakly sup ...

  4. three相机在模型上_深入理解Three.js中透视投影照相机PerspectiveCamera

    前言 在开始正式讲解透视摄像机前,我们先来理理three.js建模的流程.我们在开始创建一个模型的时候,首先需要创建我们模型需要的物体,这个物体可以是three.js中已经为我们封装好的,比如正方体, ...

  5. 【OpenGL学习笔记⑦】——键盘控制镜头的平移【3D正方体 透视投影 观察矩阵 对LookAt的理解】

  6. 从像素坐标到相机坐标_多视图几何基础——深入理解相机内外参数

    上一篇:前言(comming soon) 关键词:相机模型,多视图几何,相机内参数,相机外参数,skew畸变 1. 针孔相机模型 Figure 1 针孔相机模型是一种理想化的简单相机模型,也是成像的最 ...

  7. CSS3 Transform变形理解与应用

    CSS3 Transform变形理解与应用 Transform:对元素进行变形: Transition:对元素某个属性或多个属性的变化,进行控制(时间等),类似flash的补间动画.但只有两个关键贞. ...

  8. 摄像机投影成像 matlab,使用matlab仿真三维物点的透视投影成像.doc

    使用matlab仿真三维物点的透视投影成像.doc 使用matlab仿真三维物点的透视投影成像 ⒈仿真的目的和要求: 理解摄像机透视投影模型中的每一个参数的意思,然后在matlab中仿真三维物点根据摄 ...

  9. (01)ORB-SLAM2源码无死角解析-(37) EPnP 算法原理详解→理论基础一:控制点选取、透视投影约束

    讲解关于slam一系列文章汇总链接:史上最全slam从零开始,针对于本栏目讲解的(01)ORB-SLAM2源码无死角解析链接如下: (01)ORB-SLAM2源码无死角解析-(00)目录_最新无死角讲 ...

最新文章

  1. R语言使用ggplot2包使用geom_density()函数绘制密度图(连续色彩、离散色彩、梯度色彩)实战(density plot)
  2. 计算公式1!+2!+3!+...+10!的和
  3. 分享Kali Linux 2017年第18周镜像文件
  4. 为炒股每天只花3元 MM从贷款上学到掌控千万
  5. python socket 书籍_Python学习之路——socket
  6. Product description search in opportunity line item
  7. 20050405:什么都要会啊
  8. 【操作系统/OS笔记04】内存分层体系、地址生成、连续内存分配概论
  9. Cocos2d-x动作CCAction
  10. rstudio server docker 部署_Docker环境运行Spring Cloud项目
  11. html一边自动宽度,有2列,希望右侧固定宽度,左侧自动宽度。_html/css_WEB-ITnose...
  12. VSphere服务器ESXI4.1.0设置虚拟主机来电开机自启动
  13. 普通蓝牙防丢器已过时,onn推出支持苹果 Find My 防丢器
  14. python爬虫批量下载“简谱”
  15. 数据库隔离级别解决脏读、不可重复读、幻读
  16. 推荐系统实践——什么是推荐系统
  17. 计算机盖,盖珂珂_北京理工大学计算机学院
  18. 31.3 Java进阶之lambda方法引用
  19. 广义回归神经网络(GRNN) 讲解的较好的博客
  20. conj在c语言中什么意思,关于conj是什么词性

热门文章

  1. Netty SocketIO如何在客户端发起链接时验证token是否合法?
  2. 网段划分和IP地址范围
  3. 清华大学发布珠算:一个用于生成模型的Python库
  4. kafka 入门概念和架构,以及应用场景
  5. pandas用法总结
  6. 系统的更新服务器地址,系统更新服务器地址
  7. ACM训练系统 1023 [编程入门] 选择排序 C
  8. node.js毕业设计基于微信小程序的健康管理系统(源码+程序+LW+部署)
  9. 刘庆生:学术需要批判氛围
  10. 负荷计算(文字版) | Revit MEP