(1)问题:为什么透视投影矫正后z插值会错呢?
答案:因为投影矩阵变换后,线性关系变了。
假设矩阵变换前,b是a和c两个点的线性插值,b = ta + (1-t)c,其中b是由a和c插值而来的。。
变换后a变成了a’,c变成了c’。直接将b进行透视变换成了b’.
变换前即使【b = ta + (1-t)c】,三个点各自变换后,发现b’!= ta’+ (1-t)c’。
推导过程不难,我看了两种。
第一种
其实英文版更推荐大家看,可以参考《perspective correct interpolation kokLimLow》两页的文章
第二种
但是国内教程也有挺不错的。
《3D游戏与计算机图形学中的数学方法》的66页也有解释为什么1/z才是线性相关,也能看懂推导,但是远没有上面的英文文献思路清晰。
(2)问题:既然发现变换后1/z的线性关系没变,为什么现代引擎却不用1/z呢?
其实现代引擎的开发者发现其实1/w’更好用,因此都是对1/w’进行插值。【假设你还用1/z,代码里面需要保存z,因为经过变换后,我们能轻易地获得变换后的x’,y’以及z’,对变换后的属性插值的时候,发现z没了,已经变成了z’,这时候又发现’w的数值恰好和变换前的z一样,w’=z(或者w’=-z符号不重要,反正分子分母同时消掉),因此索性直接用w】
参考https://www.cnblogs.com/arenak/archive/2008/03/13/1103532.html
写引擎代码的各位大佬不想专门临时保存变换前的z,因此小技巧就是,利用w’变换后的数值等于z变换前的值【根据不同坐标系,可能是-z】
扩展
有空会展示一下github上哪些引擎是用了这个技巧,【等我有空回来补充】