WebGL中实现环境光遮蔽(AO)主要采用屏幕空间环境光遮蔽(SSAO),依赖深度和法线缓冲,在后处理阶段通过G-buffer采样、遮挡计算、距离衰减及双边模糊等步骤生成AO纹理,并乘入漫反射与环境光项。

WebGL 中实现环境光遮蔽(Ambient Occlusion,AO)通常不直接使用原生 WebGL API 完成,而是借助着色器(GLSL)在 GPU 上通过屏幕空间或几何空间算法近似计算。最常用、性能与效果较平衡的是 屏幕空间环境光遮蔽(SSAO),它仅依赖深度缓冲和法线缓冲,在后处理阶段实时生成 AO 效果。
准备必要渲染目标(G-buffer)
SSAO 需要两个关键输入:线性深度值和世界/视图空间法线。需在前向渲染或延迟渲染中提前输出:
- 将深度值写入一个
RGBA或R32F纹理(推荐用R32F避免精度损失),并确保深度已转为线性(如从gl_FragDepth或z/w转换) - 将插值后的法线归一化后写入另一张纹理(如
RGBA8,法线分量映射到 [0,1] 区间:vec4(0.5 + normal * 0.5)) - 注意:法线和深度必须在同一空间(推荐视图空间),否则采样会错位
SSAO 核心着色器逻辑
在全屏四边形的 fragment shader 中,对每个像素执行以下步骤:
- 从 G-buffer 读取当前像素的视图空间位置和法线
- 在半球方向(以法线为轴)随机采样多个点(通常 4–16 个),使用旋转的 Hammersley 序列或预存噪声纹理提升质量
- 对每个采样点:重建其视图空间坐标 → 计算与当前像素的距离 → 若该点深度比当前像素更远(即被遮挡),则贡献 AO 值
- AO 值 = 1 − 平均遮挡度(遮挡度越高,AO 越强,越暗)
- 加入距离衰减(如
1.0 / (1.0 + d * d * scale))避免远处误判
降噪与模糊优化
原始 SSAO 噪点明显,需后处理增强视觉稳定性:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 使用双边模糊(bilateral blur):按深度和法线相似性加权平均,保留边缘细节
- 或简单地做两次横向+纵向高斯模糊(注意:纯高斯易导致 AO “溢出”到不该暗的区域)
- 可叠加时间累积(TAA 思路):用帧间抖动采样 + 权重混合历史帧,但需维护速度/运动矢量缓冲
集成到渲染管线
SSAO 是后处理效果,应插入光照计算之后、最终合成之前:
- 渲染场景 → 输出 G-buffer(深度 + 法线)
- 绑定 SSAO FBO,绘制全屏 quad,运行 SSAO shader → 得到 AO 纹理
- 在最终光照 pass 中,将 AO 纹理采样结果乘到漫反射/环境光项上(例如:
finalColor *= vec3(1.0 - ao)) - 注意 AO 一般不作用于镜面高光,只影响漫反射和环境光部分
不复杂但容易忽略:SSAO 效果强弱高度依赖采样半径、强度系数和模糊参数,建议提供 runtime 调节面板快速验证;移动端慎用高采样数,可降至 4–8 样本并配合低分辨率 AO buffer。

















