提问者:小点点

阴影贴图,woo技巧,深度剥离


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

1-从光线渲染场景,获取深度图

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

所以,第二步应该是这样的:

2-如果(abs(DISTANCE_OF_THE_POINT_TO_LIGHT-DEPTH_STORED_IN_THE_DEPTH_MAP)

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

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

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

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

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

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

问题现在出现在步骤2中,我们之前遇到的相同问题:当第一层和第二层接近时,会出现舍入误差,也会出现某种粉刺,也没有合适的偏差值。

你怎么解决这个问题?


共1个答案

匿名用户

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

深度剥离和阴影映射都存在Z战斗问题,但阴影映射情况要糟糕得多。

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

与阴影映射不同,在深度剥离中,您将比较相同示例位置(相同阴影映射空间)的z值。如果您负担得起,它实际上是对抗阴影工件的绝佳解决方案,但它不会在所有情况下都有帮助,例如:

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

改善结果的建议:

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

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

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

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