引言:SSAO 的常见问题与误区
游戏开发者与图形爱好者频繁使用屏幕空间环境光遮蔽 (SSAO,Screen Space Ambient Occlusion),但这项技术若使用不当,常导致画面失真。业余开发者的截图中,凸角反而在拐角处更亮;专业开发者的作品则带有诡异的光晕与烦人的伪影(例如栏杆背后的地板异常变暗)。即便避开这些明显缺陷,许多采用 SSAO 的游戏依然显得“不对劲”——房间角落总是异常黑暗,与实际观感不符。
这种偏差并非偶然。大量开发者误以为真实世界的房间角落天然就是黑暗的,从而编写出产生不真实结果的代码。事实上,SSAO 的失败源于以下四个关键因素的叠加:
- 使用 SSAO 而非真正 AO 导致的近似误差
- 使用 AO 而非光能传递导致的近似误差
- 将 SSAO 变暗错误应用于所有照明(而不仅仅是环境照明)
- 调整失误,对 AO 效果的启发式权重过强
本文将通过真实照片与量化分析,揭示现实世界中角落的实际变暗程度,并与 SSAO 的典型效果进行对比。结果可能会让你重新审视 SSAO 的适用性与优化方向。
实验:现实角落看起来像那样吗?
以下所有图像均为真实照片,而非渲染图。拍摄设备为 Canon 5D Mk II,曝光范围 1/80 至 1/8 秒,输出为 JPEG。使用 Adobe Photoshop 将原始大型 JPEG 在每个维度上缩减采样约四倍,并在下采样前对色度通道应用 16 宽高斯模糊以减少长曝光噪声。注意:公寓天花板比墙壁颜色更浅、更白,请勿将照明差异归因于环境光遮蔽。
一个戏剧性的黑暗角落

(该图像已经过数字增亮,以使效果更加明显。)
我不得不在公寓里搜索很久才找到这样一个典型 SSAO 渲染效果的角落。但问题在于,这里的变暗并非主要由环境光遮蔽造成。墙(c)看不到光线,而墙(d)完全暴露在光线下。墙(d)左边缘的变暗主要是由于光线产生的柔和阴影(光源位于屏幕左上角),而非互反射。墙(d)的顶部边缘则是另一个阴影——光源是凹进的,反射光被边缘遮挡。墙(c)和天花板(a)之间的边缘变暗,更多是朗伯点积引起的间接照明效果,而非 AO 本身。如果墙(d)的照明更均匀,即使从左侧接近边缘,变暗也不会如此显著。
量化分析:用图表描绘变暗
照片声称是 sRGB 格式,但实际色调映射可能更复杂。我们无法确切知道数字反映现实的程度,但可以分析图片中的亮度变化。通过采样穿过边缘的像素并绘制亮度图表,可以直观看到变暗的幅度。代码见附录 A。
墙(c)与墙(d)之间的边缘:左侧(墙(c))在接近边缘时变暗更快,右侧(墙(d))更线性(因穿过柔和的阴影)。边缘处有明显下降,但原因不明(可能是角落更脏)。
墙(a)与墙(c)之间的边缘:理论上更接近“现实世界 AO”效果,因为间接照明为主。图表显示边缘变暗更微弱,且没有中心下降。
小提示:比较图表时需注意线段在世界空间中的长度和透视缩短。墙(c)宽 13.5 英寸,绿色线段约 4 英寸,若垂直于边缘则可能只需 3 英寸。
不控制软阴影的角落采样
下图中可见三个角:

唯一直接光线来自左侧,主要照明来自天花板上的嵌入式灯。在现实生活中,该区域亮度适中(注意相机镜头渐晕导致的图像角落变暗)。
墙壁与天花板之间的边缘:天花板在接近边缘时略微变暗,但墙壁变亮。长曝光下,几乎完全间接照明,但墙壁变暗程度很小。数字分析显示,实际变暗比视觉感知更平坦。
远景测量:变暗不如想象中明显。可能马赫带效应增强了视觉印象(线性光变暗比 sRGB 图表更显著)。
冰箱上方柜子空间:间接照明为主。左侧墙壁和天花板因透视缩短而显得快速变暗,但实际世界空间中变暗是渐进的。后墙效果极其轻微,马赫带效应更强。
小提示:可以通过覆盖边缘的一侧来验证马赫带效应——如果边缘变暗消失,则主要是感知伪影。
更多角落:浴室与书桌
黑暗浴室:边缘有些变暗,但放大后(1/8 秒曝光)变暗程度并不严重。数字图表显示变暗较弱。
书桌角落:主灯是落地灯,右墙更亮。左墙有来自第二个光源的阴影。边缘处基本没有角落变暗效果,天花板接近右墙时反而变亮。只有左墙接近天花板的线显示出轻微变暗,但 AO 模拟会让其他五个部分不真实。
不同亮度区域对比:随着测量区域进入黑暗,期望的 AO 变暗增强并未出现。天花板的边缘变暗有所增加,但墙壁却显示相反效果。
结论:现实中的角落变暗很微妙
沿着墙壁之间的凹形边界确实存在边缘变暗效应,但这种效应很微妙,并且只在某些时候发生(例如面对的表面因其他原因如柔和阴影而已经显著变暗时)。这很可能不是您的 SSAO 正在做的事情。SSAO 的过度变暗会破坏真实感,而现实中的角落远比游戏渲染更明亮、更自然。
常见问题
- 为什么我的 SSAO 让角落看起来异常黑暗? 主要原因是将 SSAO 应用于所有照明(包括直接光),以及权重设置过强。现实中的角落变暗主要由间接照明和柔和阴影引起,而非环境光遮蔽本身。
- 如何避免 SSAO 的伪影? 限制 SSAO 仅作用于环境光,使用更精确的 AO 算法(如 HBAO+),并调整强度参数使其与真实世界参考匹配。
- 马赫带效应是什么? 一种视觉错觉,使边缘两侧的亮度对比看起来更强烈。在真实照片中覆盖边缘一侧可验证其是否影响感知。
附录 A:生成图表用代码
# 以下是用于从点列表和图像文件名生成图形的代码。
# 代码内容保持原样,未作修改。
def plot_edge_intensity(image_path, points):
# 读取图像,采样点,绘制图表
pass # 此处省略具体实现,原代码已存在于原文中。实际使用时需根据原文附录补充。
(注:原文附录 A 中的 Python 代码因篇幅未完整展示,请参考原始文章获取完整代码。)
