为什么透视投影矩阵中要用z的倒数进行插值。

先说一些闲话,为什么考虑到了这个问题。今天本来想看看这个shader怎么做。

如上图,就是圆球和立方体相交的地方会发亮这种shader该怎么实现。然后看到了这个shader中有这么一个函数LinearEyeDepth,由于本人刚学shader不久,对图形学也一直处于一知半解的状态,所以不知道这个函数是什么意思。先贴上搜到的结果:

LinearEyeDepth 负责把深度纹理的采样结果转换到视角空间下的深度值,也 就是我们上面得到的Z(visw)。而 Linear01Depth 则会返回一个范围在[0, 1]的线性深度值,也就是我们上面得到的Z(01),这两个函数内部使用了内置的_ZBufferParams变量来得到远近裁剪平面的距离。

这个结果先不多讲了,(感觉学习总是跑偏,在解决一个问题时,会引出一大堆问题),在搜索透视投影矩阵的推导过程中看见了这么一句话:因为在光栅化之前,我们需要对z坐标的倒数进行插值。不明白为什么要这么做,也推不出来透视投影矩阵。遂翻看unity shader 入门精要。一句话:推导部分详见扩展阅读。(令人头大)于是乎去看Mathematics for 3D Game Programming and Computer Grahpics,感觉这真是本好书啊。越看越感觉什么opengl 什么unity shader 统统都是浮云,都是工具,这才是真理啊。

好了,进入正题,下面就说说为什么要这么做:

原谅我才学疏浅,写文章从来不是我的强项,but,今天我就是想写。可是又不知到怎么写,就这么把看到的这节翻译一下吧。

(话说不知道这么直接截图有没有侵犯到版权,有的话,请告诉我,我会马上删除。原来我粘的这么不规整)

就不逐字翻译了,直接看图,大黑点代表相机,水平的线代表投影平面,斜着的线代表真实的物体,那水平线上的小黑点代表的是真实物体投影到平面上的点。你们发现什么了没?对了,就是当在投影平面上线性插值时,反推到真实物体上,深度值不是线性的(听懂了没?没听懂看下图,下图还看不懂就放弃看这篇吧,主要赖我表述能力太差)

看见了没,d1,d2,d3,d4越来越小了,所以显然不能去Z值直接进行插值,so?那该怎么取值嘞?

继续看图,假设就这么建立了一个坐标系,(x1,z1)(x2,z2)是真实物体的两端,两端在投影面上的投影分别为(p1,-e) (p2,-e) 你们又发现什么了没?

红色三角形和蓝色三角形相似啊,而且我在直线上任意取一个点都是相似的啊,好强啊。

接下来就充分发挥初中数学能力了。下面的推导就不用再解释了吧,就根据相似三角形来就可以了

当然,我们还要进行线性插值,这里还没有插值的公式,莫怕,就差最后一点了。

这个也没什么好说的了,就是把(x1,z1) (x2,z2) (p1,-e) (p2,-e)代入就可以了。

perfect!告辞!

猜你喜欢

转载自blog.csdn.net/MQLCSDN/article/details/88560837