4

我需要用非常精细的细节来增强一些机械部件的视觉感知,所以我现在正在玩 screen.space 环境光遮蔽的不同实现。

到现在为止,我一直在前向渲染中将我的几何图形直接绘制到屏幕上,方法是使用gl.TRIANGLES双倍的画布分辨率和抗锯齿功能,例如,假设我的画布样式是 800x600 像素,然后我的画布宽度/高度设置为 1600x1200 . 只有将屏幕抗锯齿与如此高分辨率一起使用,我才能获得所需的视觉质量。

通过使用渲染缓冲区,由于缺少抗锯齿,即使以双倍分辨率渲染,我也无法接近所需的质量。我尝试在额外的后处理步骤中实现许多不同的抗锯齿技术,但无论如何我无法获得干净、流畅的线条。这是我的意思的一个示例:查看图像底部的长而略微旋转的部分。

渲染缓冲区中缺少抗锯齿

有什么方法可以通过在屏幕空间后处理期间绘制后缓冲区来获得干净、抗锯齿的线条?任何关于其他策略/技术的额外提示将不胜感激。

是否有人成功实施——仅举一个例子——FXAA 或类似的东西,在 SSAO 过程中,以获得平滑的抗锯齿长对角线,没有锯齿?


这是与上图相关的片段着色器:

float compareDepths(in float depth1,in float depth2, in float aoMultiplier) {
    float aoCap = 1.0;
    float diff = sqrt( clamp(1.0-(depth1-depth2) / (u_aoRange/(u_zFar-u_zNear)),0.0,1.0) );
    float ao = min(aoCap,max(0.0, depth1 - depth2 - u_depthTolerance) * aoMultiplier) * diff;
    return ao;
}
void main(void) {
    vec2 UV = v_texCoord.st;
    float depth = readDepth(UV);
    float d;
    float pw = 1.0 / u_resolution.x;
    float ph = 1.0 / u_resolution.y;
    float aoCap = 1.0;
    float ao = 0.0;
    float aoMultiplier = u_aoMultiplier;

    // 4 samples w/out loop
    float aoscale=1.0;
    d=readDepth( vec2(UV.x+pw,UV.y+ph));
    ao+=compareDepths(depth, d, aoMultiplier)/aoscale;
    d=readDepth( vec2(UV.x-pw,UV.y+ph));
    ao+=compareDepths(depth, d, aoMultiplier)/aoscale;
    d=readDepth( vec2(UV.x+pw,UV.y-ph));
    ao+=compareDepths(depth, d, aoMultiplier)/aoscale;
    d=readDepth( vec2(UV.x-pw,UV.y-ph));
    ao+=compareDepths(depth, d, aoMultiplier)/aoscale;

    pw*=2.0;
    ph*=2.0;
    aoMultiplier/=2.0;
    aoscale*=1.2;
    d=readDepth( vec2(UV.x+pw,UV.y+ph));
    ao+=compareDepths(depth, d, aoMultiplier)/aoscale;
    d=readDepth( vec2(UV.x-pw,UV.y+ph));
    ao+=compareDepths(depth, d, aoMultiplier)/aoscale;
    d=readDepth( vec2(UV.x+pw,UV.y-ph));
    ao+=compareDepths(depth, d, aoMultiplier)/aoscale;
    d=readDepth( vec2(UV.x-pw,UV.y-ph));
    ao+=compareDepths(depth, d, aoMultiplier)/aoscale;

    pw*=2.0;
    ph*=2.0;
    aoMultiplier/=2.0;
    aoscale*=1.2;
    d=readDepth( vec2(UV.x+pw,UV.y+ph));
    ao+=compareDepths(depth, d, aoMultiplier)/aoscale;
    d=readDepth( vec2(UV.x-pw,UV.y+ph));
    ao+=compareDepths(depth, d, aoMultiplier)/aoscale;
    d=readDepth( vec2(UV.x+pw,UV.y-ph));
    ao+=compareDepths(depth, d, aoMultiplier)/aoscale;
    d=readDepth( vec2(UV.x-pw,UV.y-ph));
    ao+=compareDepths(depth, d, aoMultiplier)/aoscale;

    pw*=2.0;
    ph*=2.0;
    aoMultiplier/=2.0;
    aoscale*=1.2;
    d=readDepth( vec2(UV.x+pw,UV.y+ph));
    ao+=compareDepths(depth, d, aoMultiplier)/aoscale;
    d=readDepth( vec2(UV.x-pw,UV.y+ph));
    ao+=compareDepths(depth, d, aoMultiplier)/aoscale;
    d=readDepth( vec2(UV.x+pw,UV.y-ph));
    ao+=compareDepths(depth, d, aoMultiplier)/aoscale;
    d=readDepth( vec2(UV.x-pw,UV.y-ph));
    ao+=compareDepths(depth, d, aoMultiplier)/aoscale;

    ao/=16.0;',
    gl_FragColor = vec4( vec3(1.0-ao), 1.0 );
}

编辑:

下面我将使用 John Chapman 在这个伟大的SSAO 教程中描述的 SSAO 技术。

左边是四倍分辨率,右边是全分辨率,带有分离的高斯模糊。

比较

请注意,使用一些经典的更“有机”或“弯曲”的模型(例如茶壶斯坦福龙快乐佛陀)不会令人不安。这些人工制品在规则的几何长物体、典型的机械或建筑形状中很明显。

有没有什么方法可以增强深度感知,通过保持质量和保留高频细节,而不使用四倍的画布分辨率?

编辑2:

最终结果在视网膜显示器上的全画布尺寸下看起来非常好,例如在 iPad 上,它的分辨率为每英寸 264 像素。但是,锯齿状线条在桌面显示器上清晰可见且令人不安,通常为 70 或 92 DPI。

我发现了这篇文章:来自 Íñigo Quílez 的多分辨率环境光遮蔽,其中还包含一些关于高频遮蔽的提示 - 程序遮蔽以增强微小细节,但我无法理解这是否也适用于直线几何形状。有人已经对此进行了实验吗?

编辑3:

这是迄今为止我找到的关于这个主题的最有用的参考资料:GPU Gems 2中的Fast Prefiltered Lines。有人已经将这里描述的技术与 SSAO 一起实现了吗?

4

2 回答 2

2

Screen Space Ambient Occlusion捕捉低频照明。它不会捕捉锐利的阴影或漫反射或镜面反射照明。出于这个原因,SSAO 通常与漫反射和高光照明相结合,以创建完整的照明解决方案。

SSAO 在 3D 渲染场景中展示全局光照效果作为后期效果。它可以快速逼近昂贵的光线追踪全局照明。因此,工件可能会出现在某些情况下(例如您的情况)。

SSAO 很少开箱即用,但需要一些调整。设置过程涉及调整Kernel RadiusNumber Of Samples以获得所需的效果。这Kernel Radius取决于scale场景的自然情况。最初可能看起来根本没有 SSAO。此时,要么Kernel Radius太小,要么太大,必须找到工作值。请记住:SSAO 在 CPU 上的速度非常慢,但在 GPU 上的性能要好得多。

解决方案: 将多个 SSAO 渲染通道与不同的组合Kernel Radii可以产生更好的效果。

看图片的右下角:

(三个相乘的图像产生具有某些细节的最终图像)

在此处输入图像描述

于 2018-02-08T20:18:28.400 回答
1

SSAO 是一种基于样本的技术,因此就其本质而言,它倾向于在输出中产生椒盐噪声。

您可以通过对不同像素使用可变采样模式来减少 SSAO 输出本身中的噪声,因此不会出现结构误差谐波。

您也可以增加样本的数量,但这可能会变得非常昂贵并且并不能真正解决问题,尽管 SSAO 可以在大多数时间以半分辨率处理而不会造成明显的质量损失。

通常的解决方法是使用高斯模糊滤波器对 SSAO 输出进行多次后期处理,以消除高频噪声。无论如何,环境光往往没有高频分量,因此质量损失非常小。

于 2018-02-02T11:25:01.567 回答