我几乎按照John Chapman的教程here来使用SSAO,实际上,使用的是Sascha Willems Vulkan示例。一个区别是碎片位置与线性深度一起直接保存到G缓冲区(因此有x、y、z和w坐标,w是线性深度,在G缓冲区着色器中计算。深度的计算方法如下:
float linearDepth(float depth)
{
return (2.0f * ubo.nearPlane * ubo.farPlane) / (ubo.farPlane + ubo.nearPlane - depth * (ubo.farPlane - ubo.nearPlane));
}我的场景通常由一个大的、平坦的地板组成,中间有一个模型。我说的“大”指的是比远剪辑距离大得多的距离。
在高深度值(例如,在我的例子中,在地平线上),SSAO在本应没有遮挡的地方生成遮挡-除了一个完全平坦的表面之外,什么都没有。伴随着这种遮挡,也会出现一些条带。
对于如何防止这些闭塞的发生,有什么想法吗?
发布于 2021-01-13 08:15:10
我在写这个问题的时候找到了这个解决方案,它之所以有效,是因为我的地板是平的。
我查找每个内核样本位置的法线值,并与当前的法线值进行比较,丢弃任何点积接近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;https://stackoverflow.com/questions/65693934
复制相似问题