3D数学-透视校正插值

文章目录

透视校正差值

好记性不如烂笔头啊,还是记录一下!


3D渲染中,输入数据是一些primitive信息,包括顶点位置、颜色、纹理坐标等等。在光栅化阶段,primitive(一般为三角形)被转化成一系列的fragment(或者称为像素),这些fragment接下来要做ps操作,此时每个fragment都有位置、颜色、纹理坐标这些属性信息,这些属性信息通过顶点属性用插值方法得到的。

如下图所示对投影面上相等的空间步长 L L L R R R,它们在三角形面上对应的步长会随着离摄像机的距离的增加而变长,即 L ′ > R ′ L'>R' L>R。因此对于处于 L L L R R R之间的那个像素点,虽然在投影面上其坐标处于 p 1 p_{1} p1 p 2 p_{2} p2之间的 3 4 \frac{3}{4} 43处,但是其在眼空间中的对应点并非处于 x 1 x_{1} x1 x 2 x_{2} x2之间的 3 4 \frac{3}{4} 43处,而顶点的属性信息却又都是在投影变换前的空间中指定的。

因此对像素属性信息的插值不能是简单的线性,尤其是纹理坐标在用线性插值时会出现明显的失真。那么应该怎么办呢?方法就是如下的透视校正插值

avatar

那么如何得到均匀的顶点属性插值呢?稍等一下,我们先看看深度插值:

avatar

假设投射的直线是:
a x + b z = c ax+bz=c ax+bz=c
对于该直线上的一点 < x , z > <x,z> <x,z>,从O点(相机位置)发出一束光线照射到该点,则光线与投影平面的交点为 < p , − e > <p,-e> <p,e>(投影平面的z值始终为-e),由于三角形相似原理可得出以下关系式:
p x = − e z \frac{p}{x}=\frac{-e}{z} xp=ze
解出 x x x得:
x = − p z e x=-\frac{pz}{e} x=epz
带入道直线方程 a x + b z = c ax+bz=c ax+bz=c中可得:
( − a p e + b ) z = c (-\frac{ap}{e}+b)z=c (eap+b)z=c
转化为:
1 z = − a p c e + b c \frac{1}{z} = -\frac{ap}{ce} + \frac{b}{c} z1=ceap+cb
考虑线段的两个端点 < x 1 , z 1 > <x_{1},z_{1}> <x1,z1> < x 2 , z 2 > <x_{2},z_{2}> <x2,z2>,以及它们在投影平面上得对应点 < p 1 , − e > <p_{1},-e> <p1,e> < p 2 , − e > <p_{2},-e> <p2,e>,假设 p 3 = ( 1 − t ) p 1 + t p 2 ( 0 ≤ t ≤ 1 ) p_{3}=(1-t)p_{1}+tp_{2}(0 \le t \le 1) p3=(1t)p1+tp2(0t1),则 p 3 p_{3} p3是点 < p 1 , − e > <p_{1},-e> <p1,e> < p 2 , − e > <p_{2},-e> <p2,e>在投影平面上得线性插值点的 x x x值,则 z z z值为:
1 z 3 = − a p 3 c e + b c      = − a p 1 c e ( 1 − t ) − a p 2 c e t + b c = ( − a p 3 c e + b c ) ( 1 − t ) + ( a p 2 c e + b c ) t     = 1 z 1 ( 1 − t ) + 1 z 2 t \frac{1}{z_{3}} = -\frac{ap_{3}}{ce} + \frac{b}{c} \\ \qquad \qquad \qquad \quad \; \; = -\frac{ap_{1}}{ce}(1-t) - \frac{ap_{2}}{ce}t + \frac{b}{c} \\ \qquad \qquad \qquad \qquad \qquad \quad =(-\frac{ap_{3}}{ce} + \frac{b}{c})(1-t) + (\frac{ap_{2}}{ce} + \frac{b}{c})t \\ \qquad \quad \; \, = \frac{1}{z_{1}}(1-t) + \frac{1}{z_{2}}t z31=ceap3+cb=ceap1(1t)ceap2t+cb=(ceap3+cb)(1t)+(ceap2+cb)t=z11(1t)+z21t
可见, z z z的倒数是线性插值,所以我们可以用顶点的 z z z值来插值求得primitive内部fragment的属性值,比如颜色等等。
假定 < x 1 , z 1 > <x_{1},z_{1}> <x1,z1>的颜色为 b 1 b_{1} b1, < x 2 , z 2 > <x_{2},z_{2}> <x2,z2>的颜色为把 b 2 b_{2} b2,则 < x , z > <x,z> <x,z>的颜色为 b 3 b_{3} b3为:
b 3 − b 1 b 2 − b 1 = z 3 − z 1 z 2 − z 1 \frac{b_{3}-b_{1}}{b_{2}-b_{1}} = \frac{z_{3}-z_{1}}{z_{2}-z_{1}} b2b1b3b1=z2z1z3z1
根据:
z 3 = 1 1 z 1 ( 1 − t ) + 1 z 2 t z_{3} = \frac{1}{\frac{1}{z_{1}}(1-t) + \frac{1}{z_{2}}t} z3=z11(1t)+z21t1
可解得:
b 3 = b 1 z 2 ( 1 − t ) + b 2 z 1 t z 2 ( 1 − t ) + z 1 t = b 1 z 1 ( 1 − t ) + b 2 z 2 t 1 z 1 ( 1 − t ) + 1 z 2 t     = z 3 [ b 1 z 1 ( 1 − t ) + b 2 z 2 t ] b_{3} = \frac{b_{1}z_{2}(1-t)+b_{2}z_{1}t}{z_{2}(1-t)+z_{1}t} \\ = \frac{\frac{b_{1}}{z_{1}}(1-t)+\frac{b_{2}}{z_{2}}t}{\frac{1}{z_{1}}(1-t)+\frac{1}{z_{2}}t} \;\,\\ \quad = z_{3}[\frac{b_{1}}{z_{1}}(1-t)+\frac{b_{2}}{z_{2}}t] b3=z2(1t)+z1tb1z2(1t)+b2z1t=z11(1t)+z21tz1b1(1t)+z2b2t=z3[z1b1(1t)+z2b2t]
转化一下为:
b 3 z 3 = b 1 z 1 ( 1 − t ) + b 2 z 2 t \frac{b_{3}}{z_{3}} = \frac{b_{1}}{z_{1}}(1-t)+\frac{b_{2}}{z_{2}}t z3b3=z1b1(1t)+z2b2t
由此可见用深度倒数来插值顶点属性是合适的。

也许有人看得比较晕,几何的证明更直观,更能使你看到结论的本质所在。

附上一个几何证明:

avatar

图中有一处错误为 E ′ F F G ′ = E F F G = k \frac{E'F}{FG'}=\frac{EF}{FG}=k FGEF=FGEF=k

本节教程就到此结束,希望大家继续阅读我之后的教程。

谢谢大家,再见!


饮水思源

参考文献:

《3D游戏与图形学中得数学方法》

https://www.cnblogs.com/arenak/archive/2008/03/13/1103532.html
https://www.cnblogs.com/mikewolf2002/archive/2012/11/25/2787480.html
https://www.cnblogs.com/cys12345/archive/2009/03/16/1413821.html


版权声明:原创技术文章,撰写不易,转载请注明出处!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值