Opengl es SSAO深度后处理中的抗锯齿

Opengl es SSAO深度后处理中的抗锯齿,opengl-es,html5-canvas,webgl,antialiasing,ssao,Opengl Es,Html5 Canvas,Webgl,Antialiasing,Ssao,我需要用非常精细的细节来增强一些机械部件的视觉感知,因此我现在正在使用screen.space环境遮挡的不同实现 到目前为止,我一直使用gl在正向渲染中直接将几何图形绘制到屏幕上。在启用抗锯齿的情况下,三角形的分辨率是画布分辨率的两倍,例如,假设我的画布样式是800x600 px,那么我的画布宽度/高度设置为1600x1200。只有使用屏幕抗锯齿和如此高的分辨率,我才能获得我所需要的视觉质量 通过使用renderbuffer,我无法接近所需的质量,即使是以两倍的分辨率渲染,因为缺少抗锯齿。我试图

我需要用非常精细的细节来增强一些机械部件的视觉感知,因此我现在正在使用screen.space环境遮挡的不同实现

到目前为止,我一直使用
gl在正向渲染中直接将几何图形绘制到屏幕上。在启用抗锯齿的情况下,三角形的分辨率是画布分辨率的两倍,例如,假设我的画布样式是800x600 px,那么我的画布宽度/高度设置为1600x1200。只有使用屏幕抗锯齿和如此高的分辨率,我才能获得我所需要的视觉质量

通过使用renderbuffer,我无法接近所需的质量,即使是以两倍的分辨率渲染,因为缺少抗锯齿。我试图在附加的后处理步骤中实现许多不同的抗锯齿技术,但无论如何,我无法获得干净、平滑的线条。这里有一个例子,我的意思是:看到长,稍微旋转的部分在底部的图像

在屏幕空间后处理期间,是否有任何方法通过在backbuffer中绘制来获得干净的抗锯齿线?如对其他策略/技术有任何其他提示,将不胜感激

是否有人在SSAO过程中成功地实现了FXAA或类似的功能,以获得平滑的抗锯齿长对角线,而不会产生锯齿


以下是与上述图片相关的片段着色器:

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 );
}
编辑:

下面我使用的是约翰·查普曼在这本伟大的著作中描述的SSAO技术

左为四倍分辨率,右为完全分辨率,分离高斯模糊

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

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

EDIT2:

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

我发现了这篇文章:来自Íñigo Quílez,其中也包含了一些关于高频遮挡-程序遮挡的提示,以增强微小细节,但我无法理解这是否也适用于直线几何形状。有人已经用这个做过实验了

EDIT3:

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

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

您可以通过对不同像素使用可变采样模式来降低SSAO输出本身中的噪声,这样就不会得到结构误差谐波

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


通常的解决方法是使用高斯模糊滤波器进一步对SSAO输出进行多次后处理,以平滑高频噪声。环境光通常没有高频成分,因此质量损失非常小。

屏幕空间环境光遮挡
捕获低频照明。它不捕捉锐利的阴影或漫反射或镜面反射照明。因此,SSAO通常与漫反射和镜面反射照明相结合,以创建完整的照明解决方案

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

SSAO很少开箱即用,但需要一些调整。设置过程包括调整
内核半径
样本数
,以获得所需效果。
内核半径取决于场景的自然
比例。最初可能根本没有SSAO。此时,
内核半径
太小或太大,必须找到工作值。请记住:SSAO在CPU上的速度非常慢,但在GPU上的性能要好得多

解决方案: 将多个SSAO渲染过程与不同的
内核半径相结合可以产生更好的效果。

请看图片的右下角:

(三个相乘的图像生成具有特定细节的最终图像)


感谢您的时间,您的时间是对SSAO的经典描述。。。有什么办法可以解决这个问题?我用更多的细节编辑了我的问题。你不能“解决”这个问题——算法的本质就是噪音。它不是为精确的高频输出而设计的(考虑到模糊的正常使用),通常在游戏中,您将SSAO输出应用于顶部,例如高频漫反射贴图和其他颜色数据,这将隐藏一些人工制品。你真的是在用SSAO做它不是为之设计的东西。@rabbi76:请看我的编辑,我添加了一些细节。显然,应用如此高的分辨率是负担不起的。你知道如何在保持高频细节的同时平滑长的几何线条吗?@rabbi76:正确,谢谢你指出这一点。4*4线性模糊也在我的测试套件中。SSAO的力量也被夸大了。无论如何,我无法摆脱这种人工制品(锯齿线),仍然在研究我能做什么