我需要通过非常精细的细节来增强某些机械部件的视觉感知,所以我现在正在使用不同的screen.space环境遮挡实现。
到目前为止,我正在使用gl.TRIANGLES
将画布分辨率与上的抗锯齿一起使用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 );
}
将我的几何图形直接绘制到屏幕上,例如,让我说我的画布样式是800x600 px,然后我的画布宽度/高度设置为1600x1200。只有使用屏幕抗锯齿以及如此高的分辨率,我才能获得所需的视觉质量。
通过使用渲染缓冲区,我无法接近所需的质量,即使渲染分辨率提高了一倍,因为缺少抗锯齿。我试图在一个额外的后处理步骤中实现许多不同的抗锯齿技术,但无论如何我无法获得干净,流畅的线条。这是我的意思的一个例子:看到图像底部的长而略微旋转的部分。
是否有任何方法可以在屏幕空间后处理期间通过在后备缓冲区中绘制来获得干净的,抗锯齿的线条?任何有关其他策略/技术的额外提示都将受到赞赏。
有人成功实施 - 仅举一例 - FXAA,或类似的东西,在SSAO通过期间,获得平滑的抗锯齿长对角线,没有锯齿?
以下是与上图相关的片段着色器:
groupby
修改
下面我正在使用John Chapman所描述的SSAO技术SSAO Tutorial。
保持四倍分辨率,正好处于全分辨率,具有分离的高斯模糊。
请注意,通过使用一些经典的“有机”或“弯曲”模型,例如茶壶,斯坦福龙,这些文物不会令人不安或快乐佛。这些工件在常规的几何长物体,典型的机械或建筑形状上都很明显。
是否有任何方法可以通过保持质量并保留高频细节来增强深度感知,而不使用画布分辨率的四倍?
EDIT2:
最终结果在视网膜显示器上的全画布尺寸看起来非常好,例如在iPad上,每英寸分辨率为264像素。然而,在桌面显示器上,锯齿状线条清晰可见且令人不安,通常为70或92 DPI。
我发现这篇文章:来自ÍñigoQuílez的multiresolution ambient occlusion,其中包含一些关于高频遮挡 - 程序遮挡的提示,以增强微小细节,但我无法理解这是否可以也适用于直的几何形状。有人已经尝试过这个吗?
EDIT3:
这是迄今为止我发现的关于此主题的最有用的参考:来自 GPU Gems 2 的Fast Prefiltered Lines。 有人已经与SSAO一起实施了这里描述的技术吗?
答案 0 :(得分:2)
Screen Space Ambient Occlusion
捕获低频照明。它不会捕捉锐利的阴影或漫反射或高光照明。因此,SSAO通常与漫反射和高光照明相结合,以创建完整的照明解决方案。
SSAO在3D渲染场景中展示全局光照效果作为后期效果。它可以快速逼近昂贵的光线跟踪全局照明。因此,工件可能会出现在某些情况下(如您的)。
SSAO很少开箱即用,但需要进行一些调整。设置过程涉及调整Kernel Radius
和Number Of Samples
以获得所需的效果。 Kernel Radius
取决于场景的自然scale
。最初可能根本没有SSAO。此时,Kernel Radius
太小或太大,必须找到工作值。请记住:SSAO在CPU上运行速度非常慢,但在GPU上运行得更好。
解:
将多个SSAO渲染通道与不同的Kernel Radii
组合在一起可以产生更好的效果。
看看图片的右下角:
(三个相乘的图像生成具有某些细节的最终图像)
答案 1 :(得分:1)
SSAO是一种基于样本的技术,因此它本质上倾向于输出中的椒盐噪声。
您可以通过对不同像素使用可变采样模式来降低SSAO输出本身的噪声,因此不会出现结构误差谐波。
你也可以增加样本数量,但这可能会非常昂贵而且并没有真正解决问题,虽然SSAO可以在大多数时间以半分辨率处理而不会有明显的质量损失。
通常的解决方法是使用高斯模糊滤波器进一步对SSAO输出进行多次后处理,以消除高频噪声。环境光无论如何都不会有高频成分,所以质量损失很小。