0

我正在尝试制作一个自阴影对象(opengl/glsl)。我做的步骤是:

1- 从灯光渲染场景以获得深度图

2- 从相机位置渲染并计算每个点到光源的距离,如果点到光源的距离大于存储在深度图中的深度,则该点处于阴影中。

但随之出现了暗影粉刺的问题。所以,第二步会像:

2- ...如果(abs(DISTANCE_OF_THE_POINT_TO_LIGHT - DEPTH_STORED_IN_THE_DEPTH_MAP)> BIAS)点在阴影中。

但它仍然没有给我很好的结果(没有合适的偏差值)。

所以,我实现了 woo 技巧(从光中找到第一个和第二个表面,然后将中点存储在深度缓冲区中)。为此,我进行了两次深度剥离。步骤是:

1- 像往常一样从灯光渲染场景以获得第一张深度图。

2- 从光照渲染场景得到第二张深度图,如果一个点到光照的距离等于第一张深度图中的距离,则丢弃该点(即不渲染第一层)。

3- 存储为您的最终深度图(第一个深度图 + 第二个深度图)/2

4- 从相机位置渲染并计算每个点到光源的距离,如果点到光源的距离大于深度图中存储的深度,则该点处于阴影中。

现在问题出现在第2步,我们之前遇到的SAME问题:当第一层和第二层接近时会出现舍入误差并且还会出现某种粉刺,并且也没有合适的偏差值。所以,我没有从 woo 算法中得到任何好处,它只是将问题转移到深度剥离部分。

你怎么能解决这个问题?

4

1 回答 1

0

我没有从 woo 算法中得到任何好处,它只是将问题转移到深度剥离部分。

Z-fighting 问题存在于深度剥离和阴影映射中,但阴影映射情况更糟。

使用阴影贴图,您可以在相机空间中计算阴影贴图空间中的z和样本位置 ( x,y) 。问题是,阴影贴图空间中通常没有样本 ( ),因此您取最接近 ( ) 的样本,然后将阴影深度与您的值进行比较。x,yx,yz

与阴影贴图不同,在深度剥离中,您正在比较z相同样本位置(相同的阴影贴图空间)的值。如果您负担得起,它实际上是对抗阴影伪影的绝佳解决方案,但它并非在所有情况下都有帮助,例如:

如果你在屏幕上有一个大物体,比如说一所房子。房子在阴影贴图上的投影可能位于几个甚至单个样本(一个像素)内,在这种情况下z,为房子计算的所有值都将与z阴影贴图中的相同值进行比较。相反,屏幕上的一个像素可能对应于阴影贴图中的一个巨大区域。

改善结果的建议:

确保DEPTH_STORED_IN_THE_DEPTH_MAP计算方式与DISTANCE_OF_THE_POINT_TO_LIGHT. 特别注意隐藏的固定流水线算法。要么同时使用它们,DEPTH_STORED_IN_THE_DEPTH_MAP要么DISTANCE_OF_THE_POINT_TO_LIGHT永远不使用它们。

使用 32 位浮点纹理来存储深度。

尝试百分比更接近过滤器 PCF。

深度剥离为您提供了自适应 BIAS。您还可以有一个自适应分辨率:级联阴影贴图

于 2013-07-09T03:02:31.030 回答