共计 1433 个字符,预计需要花费 4 分钟才能阅读完成。
背景与痛点
在实时渲染领域,光照贴图(Lightmap)是提升场景真实感的关键技术。传统 CPU 光照贴图生成方案(如 Beast、Radiosity)存在明显性能瓶颈:

- 计算密集型 :全局光照(GI)需要多次光线反弹计算,CPU 单线程处理耗时严重
- 内存限制 :高精度贴图导致内存占用飙升,影响其他系统资源
- 迭代效率低 :美术调整参数后需等待数分钟甚至数小时重新烘焙
以 2048×2048 分辨率场景为例,CPU 方案平均耗时约 45 分钟,而同等条件下 GPU 方案可缩短至 3 - 5 分钟。这种数量级差异推动了 GPU Lightmapper 的发展。
技术选型对比
当前主流光照贴图方案可分为三类:
- 预计算方案(如 Enlighten)
- 优点:运行时动态 GI 支持好
-
缺点:烘焙质量依赖预计算,移动端支持有限
-
渐进式烘焙(如 Unity Progressive Lightmapper)
- 优点:实时预览效果
-
缺点:最终收敛速度慢,不适合大场景
-
GPU 加速烘焙(如 Bakery)
- 优点:
- 利用 CUDA/OpenCL 实现 10-20 倍速度提升
- 支持 NVIDIA OptiX 光线追踪加速
- 内存占用更可控
- 缺点:
- 需要兼容不同 GPU 架构
- 显存容量可能成为瓶颈
核心实现细节
Bakery 的核心创新在于将传统光照计算分解为可并行执行的 GPU 任务:
数据结构设计
struct GPULightmapTask {
float3* positionBuffer; // 顶点位置数据
float3* normalBuffer; // 法线数据
float2* uvBuffer; // UV 坐标
uint* atlasIndices; // 图集索引
// ... 其他元数据
};
关键算法流程
- 场景体素化
- 构建三维哈希网格加速光线求交
-
使用 Warp-level 并行减少线程分歧
-
多级光照计算
[numthreads(8, 8, 1)] void LightmapCS(uint3 id : SV_DispatchThreadID) { // 1. 采样表面属性 SurfaceData s = LoadSurface(id.xy); // 2. 蒙特卡洛积分 float3 irradiance = 0; for (int i = 0; i < NUM_SAMPLES; i++) {Ray ray = GenerateSampleRay(s); irradiance += TraceRay(ray) * BRDF(s); } // 3. 写入光照贴图 StoreResult(id.xy, irradiance / NUM_SAMPLES); } -
降噪后处理
- 基于 SVGF 的时域空域联合滤波
- 使用共享内存减少带宽压力
性能测试数据
测试环境:NVIDIA RTX 3090 vs Intel i9-12900K
| 指标 | CPU 方案 | GPU 方案 | 提升倍数 |
|---|---|---|---|
| 512×512 场景 | 4 分 12 秒 | 23 秒 | 11x |
| 2048×2048 场景 | 47 分钟 | 4 分 05 秒 | 11.5x |
| 内存峰值占用 | 9.8GB | 3.2GB | 67% 减少 |
避坑指南
显存溢出问题
- 现象 :烘焙过程中驱动崩溃
- 解决方案 :
- 启用纹理压缩(BC6H 格式)
- 分块处理超大场景
- 降低光线追踪最大深度
光照泄漏修复
- 现象 :墙壁边缘出现光斑
- 调试步骤 :
- 检查 UV 接缝处的 padding 是否足够
- 验证法线贴图是否正确的切线空间
- 增加射线偏移(ray epsilon)参数
总结与展望
当前 Bakery 在动态场景支持上仍有局限,未来可能的发展方向包括:
- 结合 RTXGI 实现混合烘焙
- 支持 Nanite 网格的 LOD 光照计算
- 基于 ML 的超级分辨率光照重建
建议团队在引入时重点关注:
- 建立自动化光照验证管线
- 制定美术资源规范(UV 密度、材质分组等)
- 与动态光照系统(如 Lumen)的兼容性测试
正文完
