赞
踩
在之前的文章中,我们实现了对深度图的使用。因为,深度图不是线性的。所以,在使用时,我们使用了 Linear01Depth 函数对其进行了线性转化。
但是,对深度图进行线性转化 还有其他函数。
在这篇文章中,我们来看一下深度图线性转化的 Linear01Depth函数 和 LinearEyeDepth 函数 干了什么。
在OpenGL下
在类DirectX下
对采样的深度图纹理进行线性转化
转化后的值,就是原来物体的深度 Z 值
float4 cameraDepthTex = SAMPLE_TEXTURE2D(_CameraDepthTexture,sampler_CameraDepthTexture,uv);
float depthTex = LinearEyeDepth(cameraDepthTex,_ZBufferParams);
frac(depthTex)
Z v i e w = 1 1 − f n f d + f n f Z_{view}=\frac{1}{\frac{1-\frac{f}{n}}{f}d+\frac{\frac{f}{n}}{f}} Zview=f1−nfd+fnf1
Z v i e w = 1 ( n n − f n ) 1 f d + 1 n Z_{view}=\frac{1}{(\frac{n}{n}-\frac{f}{n})\frac{1}{f}d+\frac{1}{n}} Zview=(nn−nf)f1d+n11
Z v i e w = 1 ( n − f n ) 1 f d + 1 n Z_{view}=\frac{1}{(\frac{n-f}{n})\frac{1}{f}d+\frac{1}{n}} Zview=(nn−f)f1d+n11
Z v i e w = 1 n − f n f d + 1 n Z_{view}=\frac{1}{\frac{n-f}{nf}d+\frac{1}{n}} Zview=nfn−fd+n11
OpenGL
[
2
n
w
0
0
0
0
2
n
h
0
0
0
0
n
+
f
n
−
f
2
n
f
n
−
f
0
0
−
1
0
]
DirectX
[
2
n
w
0
0
0
0
2
n
h
0
0
0
0
n
f
−
n
n
f
f
−
n
0
0
−
1
0
]
由观察空间转化到裁剪空间矩阵可得
Z
c
l
i
p
=
n
+
f
n
−
f
Z
v
i
e
w
+
2
n
f
n
−
f
W
v
i
e
w
Z_{clip}=\frac{n+f}{n-f}Z_{view}+\frac{2nf}{n-f}W_{view}
Zclip=n−fn+fZview+n−f2nfWview
W
c
l
i
p
=
−
Z
v
i
e
w
W_{clip}=-Z_{view}
Wclip=−Zview
做透视除法可得
Z
n
d
c
=
Z
c
l
i
p
W
c
l
i
p
=
n
+
f
n
−
f
Z
v
i
e
w
+
2
n
f
n
−
f
−
Z
v
i
e
w
=
n
+
f
f
−
n
+
2
n
f
(
f
−
n
)
Z
v
i
e
w
Z_{ndc} = \frac{Z_{clip}}{W_{clip}} = \frac{\frac{n+f}{n-f}Z_{view}+\frac{2nf}{n-f}}{-Z_{view}}=\frac{n+f}{f-n}+\frac{2nf}{(f-n)Z_{view}}
Zndc=WclipZclip=−Zviewn−fn+fZview+n−f2nf=f−nn+f+(f−n)Zview2nf
d
=
0.5
⋅
Z
n
d
c
+
0.5
d=0.5·Z_{ndc}+0.5
d=0.5⋅Zndc+0.5
d
=
0.5
⋅
(
n
+
f
f
−
n
+
2
n
f
(
f
−
n
)
Z
v
i
e
w
)
+
0.5
d = 0.5·(\frac{n+f}{f-n}+\frac{2nf}{(f-n)Z_{view}})+0.5
d=0.5⋅(f−nn+f+(f−n)Zview2nf)+0.5
我们由
d
d
d 公式化简,即可得到
Z
v
i
e
w
Z_{view}
Zview
Z
v
i
e
w
=
1
f
−
n
n
f
d
−
1
n
Z_{view} = \frac{1}{\frac{f-n}{nf}d-\frac{1}{n}}
Zview=nff−nd−n11
为了得到正的Z值,需要取反
Z
v
i
e
w
=
−
1
f
−
n
n
f
d
−
1
n
Z_{view} =- \frac{1}{\frac{f-n}{nf}d-\frac{1}{n}}
Zview=−nff−nd−n11
Z
v
i
e
w
=
1
n
−
f
n
f
d
+
1
n
Z_{view}=\frac{1}{\frac{n-f}{nf}d+\frac{1}{n}}
Zview=nfn−fd+n11
对采样的深度图纹理进行线性转化
转化后的值,是Z值在[0,1]区间的值
float4 cameraDepthTex = SAMPLE_TEXTURE2D(_CameraDepthTexture,sampler_CameraDepthTexture,uv);
float depthTex = Linear01Depth(cameraDepthTex,_ZBufferParams);
这是LinearEyeDepth下推导出来的
Z
v
i
e
w
=
1
n
−
f
n
f
d
+
1
n
Z_{view}=\frac{1}{\frac{n-f}{nf}d+\frac{1}{n}}
Zview=nfn−fd+n11
Z v i e w Z_{view} Zview的取值范围 [ n e a r , f a r ] [near,far] [near,far]
使其除以一个
f
f
f得到 Linear01Depth函数的结果
Z
v
i
e
w
=
1
n
−
f
n
f
d
+
1
n
⋅
1
f
=
1
n
−
f
n
f
d
f
+
f
n
=
1
(
1
−
f
n
)
d
+
f
n
Z_{view}=\frac{1}{\frac{n-f}{nf}d+\frac{1}{n}}·\frac{1}{f}=\frac{1}{\frac{n-f}{nf}df+\frac{f}{n}}=\frac{1}{(1-\frac{f}{n})d+\frac{f}{n}}
Zview=nfn−fd+n11⋅f1=nfn−fdf+nf1=(1−nf)d+nf1
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。