文章目录
透视校正差值
好记性不如烂笔头啊,还是记录一下!
在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处,而顶点的属性信息却又都是在投影变换前的空间中指定的。
因此对像素属性信息的插值不能是简单的线性,尤其是纹理坐标在用线性插值时会出现明显的失真。那么应该怎么办呢?方法就是如下的透视校正插值
。
那么如何得到均匀的顶点属性插值呢?稍等一下,我们先看看深度插值:
假设投射的直线是:
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=z−e
解出
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=(1−t)p1+tp2(0≤t≤1),则
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(1−t)−ceap2t+cb=(−ceap3+cb)(1−t)+(ceap2+cb)t=z11(1−t)+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}}
b2−b1b3−b1=z2−z1z3−z1
根据:
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(1−t)+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(1−t)+z1tb1z2(1−t)+b2z1t=z11(1−t)+z21tz1b1(1−t)+z2b2t=z3[z1b1(1−t)+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(1−t)+z2b2t
由此可见用深度倒数来插值顶点属性是合适的。
也许有人看得比较晕,几何的证明更直观,更能使你看到结论的本质所在。
附上一个几何证明:
图中有一处错误为 E ′ F F G ′ = E F F G = k \frac{E'F}{FG'}=\frac{EF}{FG}=k FG′E′F=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
版权声明:原创技术文章,撰写不易,转载请注明出处!