图形学投影

一、概述

投影可以理解为空间到平面的映射。同现实中阳光将事物投影到地面上一样,投影变换将整个向量空间映射到它的其中一个子空间,并且在这个子空间中是恒等变换。

二、图形学中常见投影

透视投影与正交投影示意图

透视投影与正交投影示意图

三、投影规范化(projection normalization)

在这里插入图片描述
使用平移和缩放变换将照相机坐标系下的顶点变换的默认的视见体(部分教程称为视景体)的内部( [ − 1 , 1 ] 3 [-1, 1]^3 [1,1]3,即 x , y , z x,y,z xyz 的取值范围为 [ − 1 , 1 ] [-1, 1] [1,1]),该过程称为投影规范化(projection normalization)。
我们采用这种方法是因为最终由 GPU 执行的投影是固定的,投影规范化使我们能够在同一绘制流水线中执行平行投影和透视投影。

规范化矩阵的数学表示

1、定义:

M n o r m a l M_{normal} Mnormal :规范化矩阵
T T T:平移矩阵
S S S :缩放矩阵
l l l:为视见体最左边的坐标(Left)
r r r :为最右边的坐标(Right)
t t t :为最顶的坐标(Top)
b b b :为最底坐标(Botton)
n n n :最近坐标(Near),由于相机是看向负 Z 轴,这里的 n > f,且都为负数
f f f :最远坐标(Far)

2、操作步骤:

  • 平移:把中心移到原点
  • 缩放:进行放缩从而使视见体的边长为 2
    在这里插入图片描述

四、正交投影

在这里插入图片描述
正交投影(orthographic projection,亦称正投影)是平行投影的一种特殊情况,正交投影的投影线垂直于投影平面。
在这里插入图片描述
这里定义投影平面(projection plane)为 z = 0 z = 0 z=0,根据平行投影的定义可得 点 p ( x , y , z ) p(x, y, z) p(x,y,z) 投影后得到的点 p ′ ( x p , y p , z p ) p'(x_p, y_p, z_p) p(xp,yp,zp),其 x x x y y y 坐标保持不变 z p z_p zp 等于 0,因此正交投影的方程可表示为
在这里插入图片描述
可得正交变换矩阵为
在这里插入图片描述
转换为齐次坐标为

在这里插入图片描述

最终正交投影变换矩阵可表示为
在这里插入图片描述

五、透视投影

在这里插入图片描述
透视投影(Perspective Projection),透视投影是所有投影线相交于投影中心(COP)(图形学中指单点透视),变换后使得物品呈现出近大远小的效果,更接近人眼观察的结果。
在这里插入图片描述
计算透视投影步骤

  • 将透视投影的四棱台转换为立方体
  • 重复正交投影的变换
    在这里插入图片描述

根据相似三角形可得 y ′ = n z y , x ′ = n z x y' = \frac{n}{z} y, x' = \frac{n}{z}x y=znyx=znx
转换为齐次坐标表示,并寻找点p(x, y, z)变换之后的关系,
在这里插入图片描述

可得将视锥体转换为立方体的变换矩阵为
在这里插入图片描述

由于 近裁剪面上面的点 x x x y y y z z z 坐标变换后值不变,远裁剪面的 z z z 坐标变换后值不变,变换后 x = x ′ x = x' x=x y = y ′ y = y' y=y,这里简称变换矩阵为 M M M,可得
在这里插入图片描述

近裁剪面的点变换后位置不变,且有 z z z 坐标等于 n n n,将 n n n 替换 z z z 可得
在这里插入图片描述

因此变换矩阵的第三行与点 p p p 的乘积为 n 2 n^2 n2,且这里 x x x y y y 可为任意值,可得 n 2 n^2 n2 x x x y y y 无关
即变换矩阵的第三行可表示为 [ 0 , 0 , A , B ] [ 0, 0, A, B ] [0,0,A,B]
在这里插入图片描述
展开可得

在这里插入图片描述
将远平面中心点 (0, 0, f) 代入可以得
在这里插入图片描述
展开可得
在这里插入图片描述
解方程可得
在这里插入图片描述
综上可得变换矩阵
在这里插入图片描述
最终透视投影变换矩阵可表示为
在这里插入图片描述

六、OpenGL中的实现

1、正交投影

在透视投影中,将截锥形的视锥中的 3D 点(眼坐标)映射到立方体(NDC)。 x x x 坐标从 [ l , r ] [l,r] [lr] [ − 1 , 1 ] [-1,1] [11] 的范围, y y y 坐标从 [ b , t ] [b,t] [bt] [ − 1 , 1 ] [-1,1] [11] 的范围, z z z 坐标从 [ − n , − f ] [-n,-f] [nf] 的范围到 [ − 1 , 1 ] [-1,1] [11] z z z坐标与上面的映射刚好相反,上面为 n n n 映射到 1, f f f 映射到 -1)。
注意:眼坐标是在右手坐标系中定义的,但是NDC使用左手坐标系。也就是说,原点的相机在眼睛空间中沿 − Z -Z Z 轴看,但在NDC中沿 + Z + Z +Z 轴看。
在这里插入图片描述

正交视见体转换为标准化设备坐标示意图

为了推导过程与上面的区分,我们定义 − n e a r -near near 为近裁剪面, − f a r -far far 为远裁剪面。注意红色的负号,这里将右手系翻转为左手系,即将 [ 1 , − 1 ] [1, -1] [1,1] 翻转为 [ − 1 , 1 ] [-1, 1] [1,1],所以需要乘以 -1

正交投影的规范化矩阵
在这里插入图片描述
代码实现

inline mat4 Ortho(const GLfloat left, const GLfloat right,
		const GLfloat bottom, const GLfloat top,
		const GLfloat zNear, const GLfloat zFar)
{
    mat4 c;
	c[0][0] = 2.0 / (right - left);
	c[1][1] = 2.0 / (top - bottom);
	c[2][2] = 2.0 / (zNear - zFar);
	c[3][3] = 1.0;
	c[0][3] = -(right + left) / (right - left);
	c[1][3] = -(top + bottom) / (top - bottom);
	c[2][3] = -(zFar + zNear) / (zFar - zNear);
	return c;
}

2、透视投影

在这里插入图片描述

透视视见体与标准化设备坐标转换示意图

透视投影的规范化矩阵
推导过程与 第五小节中的 透视矩阵计算 相同
根据相似三角形可得 (注:这里 n e a r near near 为正数, z z z 为负数所以需要乘以 -1

在这里插入图片描述
根据齐次坐标特性可得
在这里插入图片描述
因此可得变换矩阵为
在这里插入图片描述
代入 ( 0 , 0 , − n e a r ) (0, 0, -near) (0,0,near) ( 0 , 0 , − f a r ) (0, 0, -far) (0,0,far),可得
在这里插入图片描述

在这里插入图片描述
综上可得:
在这里插入图片描述

代码实现

inline mat4 Frustum(const GLfloat left, const GLfloat right,
	const GLfloat bottom, const GLfloat top,
	const GLfloat zNear, const GLfloat zFar)
{
	mat4 c;
	c[0][0] = 2.0 * zNear / (right - left);
	c[0][2] = (right + left) / (right - left);
	c[1][1] = 2.0 * zNear / (top - bottom);
	c[1][2] = (top + bottom) / (top - bottom);
	c[2][2] = -(zFar + zNear) / (zFar - zNear);
	c[2][3] = -2.0 * zFar * zNear / (zFar - zNear);
	c[3][2] = -1.0;
	c[3][3] = 0.0;
	return c;
}

源码地址:https://github.com/WarZhan/Graphics-Demo/blob/master/Octahedra/mat.h

参考资料:
[1] GAMES101_Lecture_04:https://sites.cs.ucsb.edu/~lingqi/teaching/resources/GAMES101_Lecture_04.pdf
[2] 中科大图形学教程:http://staff.ustc.edu.cn/~zhuang/cgi/lectures/cg6.pdf
[3] OpenGL投影矩阵:http://www.songho.ca/opengl/gl_projectionmatrix.html

欢迎关注个人公众号,实时推送最新博文!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值