WebGL 深度缓冲中的深度值计算及可视化

1,169 阅读2分钟

深度缓冲中的深度值计算及可视化 - 知乎 (zhihu.com)

深度值计算

渲染管线中的顶点变换中,计算得到了透视投影矩阵:

[公式]

同时,也得到了视口变换矩阵:

[公式]

首先,根据透视矩阵,计算NDC空间的Z值。这里,相机空间中的坐标经过透视矩阵变换后,还要进行齐次除法,才能得到NDC空间中的坐标。

[公式]

[公式]

由此,可以得出:

[公式]

根据上述公式,可以得出:

[公式]

根据视口变换矩阵,可以得出:

[公式]

将 [公式] 带入 [公式] ,可以得到:

[公式]

即:

[公式]

到这一步,即可以求得屏幕空间中的深度。

Learn OpenGL CN学习过的,可能对深度测试这一节的内容有些印象。它得到的深度值的公式是:

[公式]

跟 [公式] 式对比,发现有些不一样,这是怎么回事呢?

这里要注意,本文定义的 [公式] 、 [公式] 和 [公式] 是实际的坐标值,是负的。而在深度测试文中,定义的 [公式] 、 [公式] 代表了近平面和远平面,而 [公式] 代表了近、远平面之间的值,它们都是正的。将 [公式] 、 [公式] 、 [公式] 代入 [公式] 式,可得:

[公式]

深度值的线性可视化

经过上面的推导,我们得出了深度值的计算公式。

现在,反过来,我们知道了屏幕空间中的深度值,怎么求出相机空间中的深度值呢?

首先,根据 [公式] ,可以推导出:

[公式]

对于公式2,得出的是实际坐标的 [公式] 值。为了和OpenGL中的定义统一,也将 [公式] 、 [公式] 和 [公式] 代入公式 [公式] ,可以得到:

[公式]

深度测试这一节中,得出的公式是:

[公式]

对比发现,跟公式 [公式] 有些不一样。这是因为, [公式] 求出的是顶点距离相机的距离,是正值。而 [公式] 是顶点的实际坐标,是负值,将 [公式] 取反,即得到 [公式] 。

[公式]

至此,推导完成。