SAOPass核心参数需平衡质量与性能:kernelRadius建议40–70,minDistance/maxDistance按场景深度设(如房间Z范围0–5米则maxDistance=6),aoClamp推荐0.35起调;必须关闭renderToScreen避免破坏后处理链。

SAOPass 的核心参数怎么调才不糊也不卡
Three.js 的 SAOPass 是基于屏幕空间的环境光遮蔽实现,不是“开了就变真实”,参数稍不合理就会出现噪点、拖影、边缘撕裂或帧率骤降。关键在于平衡采样质量与性能开销。
-
kernelRadius:控制采样半径(像素单位),默认 100。值越大遮蔽越柔和但模糊感越强;低于 30 时容易漏掉小缝隙,建议在 40–70 区间试;超过 80 基本就是“糊成一片” -
minDistance和maxDistance:决定深度比较的有效范围。若场景深度跨度大(比如室内+远景窗景),minDistance=0.01+maxDistance=100容易让远距离物体产生虚假遮蔽;更稳妥的是按主模型包围盒尺寸设,例如房间模型 Z 范围是 0–5 米,则设maxDistance=6 -
aoClamp:限制遮蔽强度上限,默认 0.5。调太高(如 0.9)会让暗部死黑、丢失细节;低于 0.2 又几乎看不出效果;推荐从 0.35 开始微调
为什么加了 SAOPass 后边缘发虚、模型像蒙了层灰
这不是渲染错误,而是 SSAO 本身对法线/深度缓冲敏感导致的典型伪影。尤其当模型使用 MeshStandardMaterial 且未提供 normalMap 或 roughnessMap 时,SAOPass 会把平滑插值的顶点法线误判为几何凹陷。
- 确保所有参与 SSAO 的 Mesh 都有有效法线 —— 加载 GLB 时用
gltf.parser.setMaterials(true),避免法线被丢弃 - 如果模型本身法线精度低(比如低模烘焙贴图没带法线),在
SAOPass初始化时显式关闭法线校验:new THREE.SAOPass(scene, camera, false, true)(第三个参数useNormalBuffer=false) - 不要把
SAOPass直接叠在UnrealBloomPass后面 —— Bloom 会放大 AO 噪点。正确顺序是:RenderPass→SAOPass→FXAA→Bloom
SAOPass 和预烘焙 AO 贴图能一起用吗
能,但必须分层控制,否则会双重遮蔽、暗部过重。预烘焙 AO(即 material.aoMap)作用于材质级,模拟静态遮蔽;SAOPass 是动态屏幕级,响应相机移动和实时几何变化 —— 二者定位不同,混用反而破坏物理合理性。
- 若已用
aoMap,建议把SAOPass的aoIntensity降到 0.1–0.2,仅补动态区域(如人物走过墙角时产生的临时遮蔽) - 禁用
material.aoMapIntensity的同时开启 SAOPass,等于放弃静态精度换动态表现,室内小场景可接受,大世界或建筑可视化不推荐 - 注意:SAOPass 不读取
aoMap,它只依赖 G-Buffer 中的 depth/normal;所以即使你删了aoMap,SAOPass 效果也不会变
EffectComposer 中 SAOPass 的 renderToScreen 必须关
这是最容易被忽略的致命配置。SAOPass 默认 renderToScreen = true,一旦启用,它会直接把 AO 结果写到屏幕,跳过后续所有后处理 Pass —— 导致 Bloom/FXAA 全失效,画面发灰、锯齿明显,且无法叠加其他效果。
- 初始化时务必显式传
false:new THREE.SAOPass(scene, camera, true, false, 0.1)(第四个参数是renderToScreen) - 确认
EffectComposer的render()调用链里没有手动renderer.render()—— 混用会导致双缓冲冲突,AO 效果闪烁或残留 - 调试时可用
composer.passes[?].renderToScreen = true临时单独看 SAOPass 输出,但上线前必须关掉
实际项目里,SAOPass 的价值不在“有没有”,而在“在哪一帧、对哪部分、以多轻的力度介入”。多数视觉问题根源不在参数数值,而在它是否被当作独立特效塞进管线,而非作为深度感知环节嵌入渲染逻辑。











