opengl从画三角形到画一个立方体(四)

小孔成像
图片到底是怎么形成的?如下图所示:
这里写图片描述
如上图所示,坐标真实的蜡烛,透过红色面板上的点,最终形成一个倒立的蜡烛。我们可以自己做一个图看看,利用相似三角形的原理,即可看到成像的规律。
这里写图片描述
如上图所示,如果投影面与小孔面距离比较近,那么蜡烛投影之后得到了一个比较小的投影结果;如果投影面距离小孔明比较大,那么投影后,发现投影之后,得到了一个比较大的结果。自然,如果是投影面距离小孔面和小孔面距离蜡烛相等,那么投影的结果为等比。

小孔成像与我们的透视有什么关系呢?为什么我们把投影面移动到了摄像机的前面呢?
透视的图如下:
这里写图片描述
如上图所示,左图中,真实的蜡烛,透过小孔得到了倒立的绿色的蜡烛,而红色的蜡烛为绿色的蜡烛的再次倒立就为正确的投影了。而我们的眼睛就是小孔,所以我们可以把右图中的视锥体平移到小孔的右侧,以确保得到正立的投影。

下面我们来讲下什么是透视除法。
我们前面讲过将视锥体中的物体通过相似三角形的知识,把它映射到近平面上去。这个坐标的转换过程如下:
这里写图片描述
上图中,我们视锥体中的P点,经过相似三角形的知识,得到了P’点,我们看到了P’点的x和y坐标分别是-xn/z,以及-yn/z,而z坐标用于是-n。
我们来解释一下,为什么这里有一个负号,因为在opengl中采用的是右手坐标系,而摄像机的整朝向是指向z的负方向的。这里的P点的(x,y,z)都是带有符号的,而n的这个距离是近平面的距离,这里是正值,而又因为我们经常讲摄像机放在原点处,所以近平面的距离应该为-n,而远平面自然是-f了。这样才不会导致,在映射平面上之后,得到一张x和y左右颠倒的图。
ok,到这里,我们解释了为什么把小孔成像中的投影面移到了右侧,以及小孔在透视中就相当于人的眼睛或者是摄像机。那么我们有没有发现,到这里我们已经解决了,透视的变换了。答案为是的。但是也不是的。
所谓的是,其实透视到这里的确结束了,我们仅仅需要的就是相似三角形的知识,把每个点都除以-n就得到了透视这是的平面上的点了。而近平面上的点的z坐标都是-n。
说没有结束,是因为我们这里还要做一个映射。
在讲到映射之前,我们先来看看近平面相当于什么?近平面就是小孔成像中的投影面,你可以把它理解为就是画布或者电影的那个幕布。那么一个幕布是有大小的,这里我们的近平面就是那个幕布,那么近平面也是有大小的,比如我们限定它的大小在x(l,r),以及y(b,t),可以是一个正方形,也可以是一个矩形。
所以上一步中,通过相似三角形变换之后得到的近平面上的点为:
l<=-xn/z<=r
b<=-yn/z<=t
问题到这里,也就加了一个限定的范围而已,似乎和最后的透视矩阵没有半毛钱关系。对的,你的感觉是正确的。到这里的确没有透视矩阵的影子。

接下来就是引入一个设备坐标的知识了。
上面的幕布的大小,可以任意的改变,你可以是一个矩形、可以是正方形,也就是长宽不定。
那么我们这个和我们的屏幕分别率有什么关系呢?比如说我们的幕布大小为800*600,你可以用800*600的像素填充,也可以用1600*1200的像素填充,很显然,用后者填充的更加清晰。所以这就是幕布的尺寸和分辨率大小的区别了。
那么我们的幕布是就是近平面,你可以将近平面设计成任意的宽高比。
到这里我们依然没有引入-1到1的ndc空间,是的,非常牵强,非常困难。

再来回顾一下,我们知道了近平面的大小、知道了近平面的z,就可以通过相似三角形得到视锥体中的点在近平面山的对应坐标。下面的问题是,如何将这个坐标画到屏幕上去,而且要应用到不同的分辨率的屏幕下。

我们可以反推一个东西,这里引入光栅坐标系外文中叫raster space。raster space的坐标系如下所示:
这里写图片描述
右侧的Raster Space和Screen Space有一个明显的区别就是y轴是反着来的。而NDC空间硬生生的设置为了-1到1的范围。之所以有负号,是因为和Canvas Space中的lt、tb的符号相同,因为我们的透视到画布上的点的xy是有正负的。

ok,我们的目标现在明确了,就是左边Canvas Space一路将点映射到Raster Space中去。只有得到了Raster Space中的点的坐标,我们的图像才能最终的显示出来。

首先来补充一个知识,就是映射的知识。
这里写图片描述
直线AB上的任意一点P,都能在-1到1上找到一个对应的点P’。下面我们通过不等式的变换来确定这个点到底是什么表示方式。
l<=-xn/z<=r,这里l一定小于r
两边同时减去l得到:
0<=-xn/z-l<=r-l
两边同时乘以2得到:
0<=2*(-xn/z-l)<=2(r-l)
两边同时减去r-l得到:
-(r-l)<=-2xn/z - (r-l)<=r-l
两边同时除以r-l得到:
-1<=-2xn/z(r-l) - (r+l)/(r-l) <= r-l
到这里,我们把中间的点叫做x’,此x’就是最后映射到-1到1上的点了。
我们写的好看一点,用下图所示:
这里写图片描述
上图中,我们z坐标出现在了分母中,这个不太好写成最后的矩阵形式,为啥呢?因为矩阵通过乘以某些点的坐标x或者y或者z,这种线性的形式,所以我们需要将坟墓中的z去掉,而如果我们将不等式的两边同时乘以z,我们就会得到如下等式:
这里写图片描述
ok,我们看到了新得到x”为-2nx/(r-l) - (r+l)z/(r-l)。
同理,老是同理,我们同样可以得到y”的表示为:
这里写图片描述
我们写成矩阵形式得到:
这里写图片描述
下面,来看看z的映射是怎么回事。我们知道近平面上的点的z都是-n,而到这一步,其他的网址中,一般会这么说,z即深度的映射有别于x和y的映射,z即平截头体中的点的z,在范围-n到-f之间,而我们需要把这其中的z映射到-1到1或者-到1之间,并且这个z与x和y的是无关系的,所以我们需要寻找两个系数,使得其满足:
z”=Az+B
也就是此时,矩阵变乘以向量变为如下形式:
这里写图片描述
然后此时,我们知道当z=-n的时候,-A-B/-n=-1;而当z=-f的时候,-A-B/-f = 1。
此时我们有如下的方程组:
这里写图片描述
将上面得到的A和B代入矩阵,可以得到:
这里写图片描述
我们的矩阵最后写成这样的形式:
这里写图片描述
此时,我们知道,齐次空间的点,其第四维一定为1,所以我们的矩阵:
这里写图片描述

最终我们就得到了透视矩阵的形式为:
这里写图片描述
到这里,我们就一步一步的展示了透视矩阵的推导过程,并且我们知道了,其实透视矩阵乘以点的坐标,其实并没有把点映射到-1到1的范围内,而此时只有在透视除法之后才是映射到了-1到1的空间内,才最终得到了-1到1空间内的点。儿透视除法是什么,是的,是把3D空间的点,投射到近平面的步骤,上面的相似三角形不要忘记了,那里需要一个除以z的步骤的哦,综上,就是透视的基本原理了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值