首页 > 解决方案 > 对深度缓冲区进行采样并归一化为 [0,1] (DirectX)

问题描述

我正在尝试可视化(出于调试目的)纹理四边形上场景的深度(我想将水池的深度显示到水面上)。所以我正在做的是在深度缓冲区中从相机的角度渲染场景,然后将相同的深度缓冲区作为着色器资源绑定到水着色器。但是当我对纹理进行采样时,我总是得到一个完整的白色纹理。我使用pow(value, 100.0)并且得到了一些变化,它正确地遵循了水下地形的深度,所以我必须假设存在一些值,但它们在 1.00 左右的小范围内。因此,我尝试通过使用以下等式反转 z 的透视变换(从剪辑空间回到眼睛空间)来标准化这些值:

float linearDepth = near * far / (far - depth * (far - near));

但同样,全白。这个公式对我来说似乎是正确的(我在 Frank Luna 的书中找到了它,即使我自己计算投影矩阵我也能得到它)。远近平面在 0.1 300.0 范围内,但即使使用这些值也不能让我到任何地方。

所有这一切都是因为我想在我的水面上实现软边缘并且我需要深度值,但我想在之前将它们可视化,所以我知道我做对了。

标签: directx-11depthdepth-bufferprojection-matrix

解决方案


没错,使用标准投影矩阵,深度值的分布都将非常接近 1 的值(只有非常接近的物体才会显示出明显的差异)。除非远平面真的非常接近,否则您不会看到明显低于 1 的值。人眼几乎看不到明亮颜色和深色之间的小增量(所以你不太能够看到变化)。

您对深度缓冲区的线性化绝对走在正确的轨道上。在过去,我得到了这个工作(在 OpenGL 中,所以 YMMV),其内容如下:

float lineardepth = (2.0f * near) / (far + near - depth * (far - near));

这也应该非常接近于在 D3D 中工作的东西。


推荐阅读