0

我几乎按照 John Chapman 的教程在这里使用 SSAO ,事实上,使用 Sascha Willems Vulkan 示例。一个区别是片段位置与线性深度一起直接保存到 G-Buffer(因此有 x、y、z 和 w 坐标,w 是线性深度,在 G-Buffer 着色器中计算。深度计算如下这个:

float linearDepth(float depth)
{   
    return (2.0f * ubo.nearPlane * ubo.farPlane) / (ubo.farPlane + ubo.nearPlane - depth * (ubo.farPlane - ubo.nearPlane)); 
}

我的场景通常由一个大而平坦的地板组成,中间有一个模型。大我的意思是比远剪辑距离大得多。

在高深度值下(即在我的示例中的地平线处),SSAO 会在本应没有遮挡的地方生成遮挡 - 除了完全平坦的表面之外什么都没有。除了这种遮挡,还有一些条带。

关于如何防止这些遮挡发生的任何想法?

4

1 回答 1

0

我在写这个问题时找到了这个解决方案,它只是因为我有一个平坦的地板。

我在每个内核样本位置查找法线值,并与当前法线进行比较,丢弃任何点积接近 1 的值。这意味着平面不能自遮挡。

任何关于我为什么不应该这样做的评论,或者更好的选择,都将非常受欢迎!它适用于我目前的情况,但如果我碰巧在地板上有非平面几何图形,我会寻找不同的解决方案。

vec3 normal = normalize(texture(samplerNormal, newUV).rgb * 2.0 - 1.0);
<snip>
for(int i = 0; i < SSAO_KERNEL_SIZE; i++)
    {
        <snip>
        float sampleDepth = -texture(samplerPositionDepth, offset.xy).w; 
        vec3 sampleNormal = normalize(texture(samplerNormal, offset.xy).rgb * 2.0 - 1.0);   
        if(dot(sampleNormal, normal) > 0.99)
            continue;
于 2021-01-13T00:15:09.773 回答