我正在尝试制作一个自阴影对象(opengl/glsl)。我做的步骤是:
1-从灯光渲染场景以获得深度图
2-从摄影机位置渲染并计算每个点到光源的距离,如果点到灯光的距离大于深度图中存储的深度,则该点处于阴影中。
但随后出现了阴影痤疮的问题。所以,第二步应该是:
2-。。。如果(abs(DISTANCE_OF_THE_POINT_TO_LIGHT-DEPTHSTORED_IN_THE_DEPTH_MAP)>BIAS)该点处于阴影中。
但它仍然没有给我好的结果(没有合适的偏差值)。
所以,我实现了woo-trick(从光中找到第一个和第二个表面,然后将中点存储在深度缓冲区中)。为了做到这一点,我做了两次深度剥离。步骤是:
1-像往常一样,从灯光渲染场景以获得第一个深度贴图。
2-从灯光渲染场景以获得第二个深度贴图,如果一个点到灯光的距离等于第一个深度贴图中的距离,则丢弃该点(即,不渲染第一层)。
3-存储为您的最终深度图(第一个深度图+第二个深度图)/2
4-从相机位置渲染并计算每个点到光源的距离,如果点到灯光的距离大于深度图中存储的深度,则该点处于阴影中。
问题现在出现在步骤2中,与我们以前遇到的问题相同:当第一层和第二层接近时,会出现舍入误差,还会出现某种痤疮,而且也没有合适的偏差值。所以,我没有从woo算法中得到任何好处,它只是将问题转移到深度剥离部分。
你怎么能解决这个问题?
我没有从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_MAP
和DISTANCE_OF_THE_POINT_TO_LIGHT
,要么永远不要使用它们。
使用32位浮点纹理来存储深度。
尝试百分比接近过滤器PCF。
深度剥离为您提供自适应BIAS。您也可以使用自适应分辨率:级联阴影贴图。