计算机图形学-3D观察与图像渲染流水线-投影全解析
本文目标:
- 理清OpenGL在3D观察的整个流程。
- 清楚各个专业术语的含义。
- 对坐标系变换的数学有所掌握。
1 三维观察与观察流程
1.1 三维观察与照相观察的对比
- 三维观察过程与使用照相机拍摄照片类似
对象 | 定位 | 场景范围 | 成像 | |
---|---|---|---|---|
照相 | 自然景物 | 设定相机位置、方向、相机的正向上方向 | 改变相机焦距大小 | 胶片 |
三维观察 | 三维虚拟场景 | 设置三维观察坐标系 | 选定观察体大小 | 观察平面 |
1.2 三维观察流水线(模型渲染管线)
- 让我们先来弄清楚OpenGL中的渲染管线。管线是一个抽象的概念,之所以称之为管线是因为显卡在处理数据的时候是按照一个固定的顺序来的,而且严格按照这个顺序。就像水从一根管子的一端流到另一端,这个顺序是不能打破的。先来看看下面的图:
术语
- MC:模型坐标系
- Modelling transformation:模型变换
- WC:世界坐标系
- Viewing Transformation:视点变换
- VC:视界坐标系
- Projection Transformation:投影变换
- PC:投影坐标系
- Normalization Transformation and Clipping: 正则化变换和剪裁
- NC:正则化坐标
- View Transformation: 视窗转换
- DC: 设备坐标
图解
- 图中显示了OpenGL图形管线的主要部分,也是我们在进行图形编程的时候常常要用到的部分。
- 一个顶点数据从图的左上角(MC)进入管线,最后从图的右下角(DC)输出。
- MC是Model Coordinate的简写,表示模型坐标。DC是Device Coordinate的简写,表示设备坐标。当然DC有很多了,什么显示器,打印机等等。这里DC我们就理解成常说的屏幕坐标好了。MC是模型坐标,也说成本地坐标(相对于世界坐标)。MC要经过模型变换(Modeling Transformation)才变换到世界坐标(但是事实上这个转换时不存在的,只需要一个转换modelling转换到viewing 参考文章:https://blog.csdn.net/caoshangpa/article/details/80272903)
1.3 模型坐标系
- 这是模型在被应用任何变换之前的初始位置和方向所在的坐标系,也就是当前绘图坐标系。该坐标系不是固定的,且仅对该模型适用。
- 在默认情况下,该坐标系与世界坐标系重合。这里能用到的函数有glTranslatef(),glScalef(), glRotatef(),当用这些函数对当前绘图坐标系进行平移、伸缩、旋转变换之后, 世界坐标系和当前绘图坐标系不再重合。
- 改变以后,再用glVertex3f()等绘图函数绘图时,都是在**当前绘图坐标系进行绘图,所有的函数参数也都是相对当前绘图坐标系来讲的。**如图则是对物体进行变换后,模型坐标系与世界坐标系的相对位置。
- 模型坐标系也叫本地(局部)坐标系。
1.4 观察坐标系
- 模型变换:模型坐标系->世界坐标系
- 视变换:世界坐标系->观察坐标系
- 在OpenGL中,我们有GL_MODELVIEW矩阵,它代表着模型变换矩阵和视点变换矩阵的组合(Mview*Mmodel),它可以直接使模型坐标系转换到世界坐标系。OpenGL中不存在单独的模型变换和视点变换,所以都使用GL_MODELVIEW矩阵使模型坐标系转换到观察坐标系。
- 默认情况下,眼坐标系和世界坐标系是重合的。使用函数gluLookAt()则可以指定眼睛(相机)的位置和眼睛看的方向,函数原型:
void gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery, GLdouble centerz,GLdouble upx, GLdouble upy, GLdouble upz)
函数参数中:
点(eyex, eyey, eyez)代表眼睛所在位置 p 0 p_0 p0;
点(centerx, centery,centerz)代表眼睛看向的位置;
向量(upx, upy, upz)代表视线向上方向,其中视点和参考点的连线与视线向上方向要保持垂直关系。(这个是view-up vector,为什么我们需要这个向量呢?因为我们可以歪着头看物品)
正着头看物品
歪着头看物品
定义观察坐标系过程
- 我们现在有“眼睛所在位置”,“眼睛看向的位置”,“视线向上方向”,于是:
- 我们可以获得VPN(view-plane normal vector),是一个眼睛看向位置指向眼睛所在位置的向量(可以通过上面获取),有了它就能定义 Z v i e w Z_{view} Zview方向,我们用N来表示它的单位向量。
- 用视线向上方向就可以直接获得 Y v i e w Y_{view} Yview方向,我们用V来表示它的单位向量。
- V和N的点积可以确定 x v i e w x_{view} xview,我们称为N,这样观察坐标系就确定完成了。
注意:我们的观察物体在 Z v i e w Z_{view} Zview的负半轴上
定义观察平面
- 通常在观察坐标系中定义一个平面作为剪裁窗口所在的平面,即观察平面,它与 z v i e w z_{view} zview垂直,用一个标量设定观察平面在沿 z v i e w z_{view} zview轴方向的位置 z v p z_{vp} zvp。
- 为从观察原点沿着观察方向到观察平面的距离,常被设置在负 z v i e w z_{view} zview方向。
- 观察平面的方向用平面法向量N来定义,并与 z v i e w z_{view} zview正轴同方向,观察平面总是与平面 x v i e w y v i e w x_{view}y_{view} xviewyview平行。
(摘自三维观察:PPT)
向上向量(view-up vector)
- 我们发现,向上向量在输入
gluLookAt
的时候非常容易输入不精确(不和N严格垂直),所以观察函数一般会自动调整向量V的方向。 - 通过将其投影到观察平面上得到与观察平面法向量垂直的向量作为V。
1.4.2 世界坐标系向相机坐标系的变换(难)
步骤1: 理解齐次坐标
https://blog.csdn.net/smilejiasmile/article/details/79606234
步骤2:让我们来举个2维的例子
我们来研究从MC到WC的坐标转换
**问题:**已知MC在WC的原点坐标为(4,3),在MC坐标上有点p(1,1),求转换矩阵和这个点在WC的位置(用列向量表示)。
解:设点 p ( x , y ) p(x,y) p(x,y) 变换后的点为 p ′ ( x ′ , y ′ ) p'(x',y') p′(x′,y′),假设MC开口朝右(只是便于理解),那么我们的坐标系就不用通过旋转,那么有 x ′ = x + T x , y ′ = y + T y x'=x+T_x,y'=y+T_y x′=x+Tx,y′=y+Ty
于是转换矩阵易得为 [ x ′ y ′ 1 ] = [ 1 0 T x 0 1 T y 0 0 1 ] ⋅ [ x y 1 ] = [ x + T x y + T y 1 ] \begin{bmatrix} x'\\y'\\1 \end{bmatrix}=\begin{bmatrix} 1 & 0 & T_x\\0 & 1 & T_y\\0 & 0 & 1\end{bmatrix}\cdot \begin{bmatrix} x\\y\\1 \end{bmatrix}= \begin{bmatrix} x+T_x\\y+T_y\\1 \end{bmatrix} ⎣⎡x′y′1⎦⎤=⎣⎡100010TxTy1⎦⎤⋅⎣⎡xy1⎦⎤=⎣⎡x+Txy+Ty1⎦⎤
带入 x = 0 , y = 0 , x ′ = 4 , y ′ = 3 x = 0,y = 0,x' = 4,y' = 3 x=0,y=0,x′=4,y′=3,则求出 T x = 4 , T y = 3 T_x = 4, T_y = 3 Tx=4,Ty=3。
此时再带入 x ′ = 1 , y ′ = 1 x' = 1,y' = 1 x′=1,y′=1求出 x = 5 , y = 4 x = 5,y = 4 x=5,y=4,这不是我们想要的结果,因为MC的开口朝左。此时我们需要让WC开口逆旋转90°。
用极坐标表示点P:
{ x = r cos α y = r sin α \left\{ \begin{aligned} x =r \cos \alpha \\ y =r \sin \alpha \\ \end{aligned} \right. {x=rcosαy=rsinα
用极坐标表示点 p ′ p' p′
{ x ′ = r cos ( α + θ ) = r c o s α c o s θ − r s i n a α s i n θ y ′ = r sin ( α + θ ) = r c o s α s i n θ + r s i n α c o s θ \left\{ \begin{aligned} x' =r \cos (\alpha+\theta) = rcos\alpha cos\theta - rsina \alpha sin\theta\\ y' =r \sin (\alpha+\theta) = rcos\alpha sin\theta+rsin\alpha cos\theta \\ \end{aligned} \right. {x′=rcos(α+θ)=rcosαcosθ−rsinaαsinθy′=rsin(α+θ)=rcosαsinθ+rsinαcosθ
将上面的 x , y x,y x,y带入下面的式子即可得到
{ x ′ = x c o s θ − y s i n θ y ′ = x s i n θ + y c o s θ \left\{ \begin{aligned} x' =xcos\theta - ysin\theta\\ y' =xsin\theta+ycos\theta \\ \end{aligned} \right. {x′=xcosθ−ysinθy′=xsinθ+ycosθ
于是即可推出
[ x ′ y ′ 1 ] = [ x y 1 ] ⋅ [ c o s θ s i n θ 0 − s i n θ c o s θ 0 0 0 1 ] \begin{bmatrix} x'\\y'\\1 \end{bmatrix}=\begin{bmatrix} x\\y\\1 \end{bmatrix}\cdot \begin{bmatrix} cos\theta & sin\theta & 0\\-sin\theta & cos\theta & 0\\0 & 0 & 1\end{bmatrix} ⎣⎡x′y′1⎦⎤=⎣⎡xy1⎦⎤⋅⎣⎡cosθ−sinθ0sinθcosθ0001⎦⎤
代入 θ = 90 ° \theta = 90° θ=90°,则矩阵变成 [ 0 1 0 − 1 0 0 0 0 1 ] \begin{bmatrix} 0 & 1 & 0\\-1 & 0 & 0\\0 & 0 & 1\end{bmatrix} ⎣⎡0−10100001⎦⎤
把(1,1)乘以旋转矩阵
[ 1 1 1 ] ⋅ [ 0 1 0 − 1 0 0 0 0 1 ] = [ 1 − 1 1 ] \begin{bmatrix} 1\\1\\1 \end{bmatrix}\cdot \begin{bmatrix} 0 & 1 & 0\\-1 & 0 & 0\\0 & 0 & 1\end{bmatrix}=\begin{bmatrix} 1\\-1\\1 \end{bmatrix} ⎣⎡111⎦⎤⋅⎣⎡0−10100001⎦⎤=⎣⎡1−11⎦⎤
再把结果代入之前的平移矩阵: [ 1 0 3 0 1 4 0 0 1 ] ⋅ [ 1 − 1 1 ] = [ 4 3 1 ] \begin{bmatrix} 1 & 0 & 3\\0 & 1 & 4\\0 & 0 & 1\end{bmatrix}\cdot \begin{bmatrix} 1\\-1\\1 \end{bmatrix} = \begin{bmatrix} 4\\3\\1 \end{bmatrix} ⎣⎡100010341⎦⎤⋅⎣⎡1−11⎦⎤=⎣⎡431⎦⎤
根据二维方程,思考三维方程
推导思路是完全一样的,只是变成了从WC到MC。这个是平移矩阵,我们假定世界坐标系上有一点 p 0 ( x 0 , y 0 , z 0 ) p_0(x_0,y_0,z_0) p0(x0,y0,z0),那么我们发现转换矩阵的原点坐标变成了 p 0 p_0 p0坐标的相反数,这是因为相对 p 0 p_0 p0,世界坐标系的原点坐标就是这个位置。
2. 投影变换
2.1 平行投影
- 转换为查看坐标后,对象描述将投影到视图平面。
- 在平行投影中,坐标位置沿着平行线转移到视图平面。
- 平行投影的特点,光源无限远,可以近似为平行光
- 两种方法获得平行投影
- 沿垂直于平面的线投影(正投影)(parallel projections)
- 以与视图倾斜的角度投影(斜投影)(Oblique parallel projections)
- P平面即为观察平面
正投影实例
斜投影实例
2.2 透视投影
- 在透视投影中,对象位置沿着会聚到视图平面后面点的线转换为投影坐标。
- 透视投影不保留对象的相对比例
- 场景视图更真实,因为投影显示中的远处对象的大小减小。
透视投影图片示例
2.2.1透视投影转换坐标
- 虚线表示空间位置 ( x , y , z ) (x,y,z) (x,y,z)到 ( x p r p , y p r p , z p r p ) (x_{prp},y_{prp},z_{prp}) (xprp,yprp,zprp)的投影参考点的投影路径。
- 投影线在视图平面与坐标位置 ( x p , y p , z v p ) (x_p,y_p,z_{vp}) (xp,yp,zvp)相交,其中 z v p z_{vp} zvp是 z v i e w z_{view} zview轴上视图平面的某个选定位置(就说我们是通过确定z点来确定这些点的位置的)。
描述沿该透视投影线的坐标位置的等式以参数形式表示为:
由于z点已知,则可以用z代换u:
通过代换,我们得到了新的方程:
2.2.2 相交点(灭点)(消失点)
- 一般灭点透视就分为三种,一点透视,二点透视和三点透视
- 使用透视映射将场景投影到视图平面上时,与视图平面平行的线将投影为平行线
- 但是,场景中与视平面不平行的任何平行线都会投影到会聚线中
- 消失点是指一组投影线看起来会聚的点 - 每组投影平行线都有一个单独的消失点
- 主要消失点是一组与一个物体的主轴平行的线
- 我们用投影平面的方向控制主要消失点的数量,因此透视投影被分类为一点,两点和三点投影
- 投影中的主要消失点的数量等于与视图平面相交的主轴的数量
2.3 正交投影
- 正交投影(或正交投影)是将对象描述沿与视图平面法向量n平行的直线转换为视图平面。
- 它最常用于生成对象的前视图、侧视图和俯视图。
- 物体的前、侧和后正交投影称为立面。
- 顶部正交投影称为平面图。
- 下面是两个正方体的示例
正视图(front evaluation view)
侧视图(side evaluation view)
俯视图(plan view)
2.4 正交投影视图体(orthogonal projection view volume)
- 我们这里强调一点,观察平面是一个无限平面,通常有uv轴构成,显然无限平面不可能容纳在有限平面内,因此定义了剪裁窗口。
- ※何为正交投影视图体积,其实就是正视图(前后两面)、俯视图(上下两面)、侧视图(左右两面),总计六面围城的长方体空间就称为正交投影视图体积。可以依靠上面的三视图想象。超出这个范围的外部场景将被剪切。
2.5 透视投影视图体(Perspective-projection view volume)
有正交投影视图体积就有透视投影视图体
透视投影视图体积通常被称为视觉金字塔(pyramid of vision),因为它近似于我们眼睛的视锥或相机
通过添加垂直于 z v i e w z_{view} zview轴并平行于视图平面的近和远剪裁平面,我们切除无限透视投影视图体积的一部分,以形成截断的棱锥,或者称为棱台
我们从一个方向观察投影观察体
透视投影观察体完全可由视场角、裁剪窗口的横纵比及从投影参考点到近和远裁剪平面的距离来确定。裁剪窗口的左下角和右上角的坐标位置与棱台中心点及窗口的高、宽之间存在如下关系
x w m i n = x c − 宽 度 / 2 , x w m a x = x c + 宽 度 / 2 , y w m i n = y c − 高 度 / 2 , y w m a x = y c + 高 度 / 2 x_{wmin}=x_c-宽度/2,x_{wmax}=x_c+宽度/2,y_{wmin}=y_c-高度/2,y_{wmax}=y_c+高度/2 xwmin=xc−宽度/2,xwmax=xc+宽度/2,ywmin=yc−高度/2,ywmax=yc+高度/2
投影视图的规范化变换
- 透视投影观察体中透视投影变换,会将棱台内部的坐标位置,映射到矩形平行管道的正交投影坐标。
- 于是乎 ( x w m i n , y w m i n , z n e a r ) (x_{wmin},y_{wmin},z_{near}) (xwmin,ywmin,znear)全部映射到了 ( − 1 , − 1. − 1 ) (-1,-1.-1) (−1,−1.−1), ( x w m a x , y w m a x , z f a r ) (x_{wmax},y_{wmax},z_{far}) (xwmax,ywmax,zfar)全部映射到了 ( 1 , 1 , 1 ) (1,1,1) (1,1,1)
- 又是一个坐标系转换,无非套用上面的公式,最后得到结果
- 一旦我们完成了对标准化投影坐标的转换,剪切就可以应用于对称立方体(或单位立方体)。
- 标准化视图体积的内容可以转移成屏幕坐标。
3 总结:
- 3D场景的查看过程遵循2D查看中使用的一般方法,我们创建世界坐标场景,然后设置查看坐标参考框架和传输对象描述,3D观察需要投影例程并涉及更多空间参数
- 使用相机类比来描述3D观察参数,其中使用视图参考点(摄像机位置),视平面法线向量N(摄像机镜头方向)和查看向量V(视图向量V)建立视图坐标参考系。相机朝上)
- 可以用投影向量指定平行投影(正交或倾斜)
- 利用在投影参考点处相交的投影线获得对象的透视投影
- 平行投影保持物体比例,但透视投影减小了远处物体的尺寸
- 如果线不与视平面平行,则透视投影会使平行线收敛到消失点。
参考资料:
http://glasnost.itcarlow.ie/~powerk/GeneralGraphicsNotes/projection/orthographicprojection.html
https://blog.csdn.net/smilejiasmile/article/details/79606234
https://blog.csdn.net/Goncely/article/details/5397729
http://glasnost.itcarlow.ie/~powerk/GeneralGraphicsNotes/projection/orthographicprojection.html
https://blog.csdn.net/qq_16334327/article/details/81228679
https://blog.csdn.net/caoshangpa/article/details/80272903
《计算机图形学:原理及实践》
三维观察ppt
图片自制或取于网络素材
计算机图形学-3D观察与图像渲染流水线-投影全解析相关推荐
- 计算机那些事(8)——图形图像渲染原理
最近在 iOS 开发中做了较多动画相关的编程工作.因此想借此机会深入了解了一下 iOS 动画及渲染相关原理.随着对相关方面的深入了解,发现这里面涉及到从硬件底层到软件框架等一系列相关知识. 本文将从相 ...
- 计算机图形学 1 —— 颜色模型图像基本知识,Phong光照模型
色彩视觉 什么是色彩? 色彩是对不同波长的光的能量的感知: 不同波长的电磁波(electromagnetic waves) 对应不同的色彩: 对于人眼能感知的光(可见光),其波长范围为 380nm到7 ...
- 2、计算机图形学——3D变换
1.1.3D点和向量的齐次坐标表示 根据1中的第二部分齐次坐标可知,3D点的齐次坐标可表示为 1.2.3D仿射变换的一般形式 根据1中的第三部分变换的组合可知,3D点的仿射变换的齐次坐标方程可表示为 ...
- 计算机图形学对勾函数,高一数学 : 最全函数图像汇总,不看准后悔!
原标题:高一数学 : 最全函数图像汇总,不看准后悔! 函数的图像是高考的必考点,对于研究函数的单调性.奇偶性以及最值(值域).零点有举足轻重的作用,但是很多同学看到眼花缭乱的函数解析式,就已经晕头转向 ...
- 计算机图形学基础:光栅图像(Fundamentals of computer graphic:Raster Images) 学习笔记
<Fundamentals of computer graphics>4th edition: 3. Raster Images 本文仅仅是本人的学习笔记,由于自己能力有限,可能存在许多错 ...
- 计算机图形学 第6章 三维变换与投影
目录 # 学习要求 前置知识 三维几何变换总的式子: 平移变换 比例变换 旋转变换:绕x轴旋转 反射变换 错切变换 三维复合变换 坐标系变换 正交投影矩阵 三视图 斜投影定义 透视投影 透视变换坐标系 ...
- 计算机专业的笔记本电脑配置要求,笔记本电脑硬件配置全解析,看完让你轻松选择笔记本...
您现在用的是什么笔记本?您是否打算购买笔记本?本文章主要针对笔记本配置详细的介绍.不管是否有笔记本都可以看一下此文章,您让更清楚的了解及选择笔记本. 目前市场上有,轻薄本.游戏本.商务本等分类.一般便 ...
- python计算机图形学_图形图像学习随笔:计算机图形学的一些基本概念
本文内容摘抄于:<计算机图形学的概念> 一.计算机图形学的范畴 1.图形主要分为两类,一类是基于线条信息表示的,如工程图.等高线地形图.曲面的线框图等:另一类是明暗图,也就是通常所说的真实 ...
- 图形图像学习随笔:计算机图形学的一些基本概念
本文内容摘抄于:<计算机图形学的概念> 一.计算机图形学的范畴 1.图形主要分为两类,一类是基于线条信息表示的,如工程图.等高线地形图.曲面的线框图等:另一类是明暗图,也就是通常所说的真实 ...
最新文章
- java中的==和equals
- python中enumerate在for循环中用法_python中enumerate的用法实例解析
- Android ContentProvider的介绍
- socket跟TCP/IP 的关系,单台服务器上的并发TCP连接数可以有多少
- 日语学习-多邻国-平假名2
- linux unix mac windows,文件路径-windows上的反斜杠和Mac OS/Linux/Unix上的正斜杠,Windows,倒,以及,macOSLinuxUNIX...
- Batch Normalization 反向传播(backpropagation )公式的推导
- (day 51 - 排序+夹牌 ) 剑指 Offer 61. 扑克牌中的顺子
- font-family:微软雅黑;与font-family:Microsoft YaHei;的区别?
- ADAS工程师的成长之路——ACC法规(ISO 15622-2018 — Adaptive cruise control systems)
- 开传奇需要什么技术要什么条件
- 学习笔记(01):程序员的数学:微积分-常用导数(一):最常用到的技巧
- ASP.NET Web常用控件
- ROS pgm转jpg
- [Java][Casssandra] create column family in Casssandra version 1.1.7
- 多目标优化算法(四)NSGA3(NSGAIII)论文复现以及matlab和python的代码
- Kettle报错:Driver class org.gjt.mm.mysql.Driver could not be found
- MySQL Workbench生成数据表关系图
- 2020年深圳杯C题
- 【Android技巧】通过am完成发送开机广播等操作