基于Babylonjs的WEBGPU渲染器源码架构

WebGPU 实时光线追踪渲染器实现原理

基于 BabylonJS + WebGPU 的浏览器端路径追踪渲染器,支持 PBR 材质、全局光照,无需安装任何插件。

编辑器演示视频:www.bilibili.com/video/BV1dZ...

编辑器在线地址:webgpu.moyunhe.com/


一、整体架构

渲染器分为五个核心层:

复制代码
┌─────────────────────────────────────────┐
│           GPUEditor3D(对外接口)         │
├─────────────────────────────────────────┤
│     GPUEditor(编辑器逻辑 + 插件管理)    │
├─────────────────────────────────────────┤
│   WebgpuPreview(WebGPU 引擎 + 场景管理)│
├──────────────┬──────────────────────────┤
│ GPURayTrace  │  BVHBuilderPlugin        │
│ (路径追踪)  │  (加速结构构建)          │
├──────────────┴──────────────────────────┤
│         GPUAssetManager(资源管理)       │
└─────────────────────────────────────────┘
模块 职责
WebgpuPreview WebGPU 引擎初始化、场景管理、渲染循环
GPURayTrace 路径追踪计算着色器、采样、降噪调度
BVHBuilderPlugin BVH 加速结构构建(BLAS + TLAS)、材质打包
GPUAssetManager glTF 模型加载、HDR 环境贴图、纹理管理
TileRender 自适应分块渲染,防止 GPU 超时

二、WebGPU 引擎初始化

引擎使用 BabylonJS 的 WebGPUEngine,开启全部 WebGPU 特性:

typescript 复制代码
new WebGPUEngine(canvas, {
  enableAllFeatures: true,   // 开启所有 WebGPU 扩展
  setMaximumLimits: true,    // 使用最大资源限制
  antialias: true,
  useHighPrecisionMatrix: true
})

用到的 WebGPU 特性:

  • Compute Shader --- 路径追踪主管线
  • Storage Buffer --- BVH 节点、三角形、法线、材质、光源数据
  • Storage Texture --- 累积帧缓冲(ping-pong 双缓冲)
  • Texture Array --- 材质纹理图集
  • Uniform Buffer --- 相机矩阵、采样参数、光源数量
  • Command Encoder --- GPU buffer 拷贝与后处理

三、BVH 加速结构

光线追踪的性能核心是 BVH(Bounding Volume Hierarchy,层次包围盒)。本渲染器采用两级 BVH

3.1 BLAS(Bottom-Level AS,网格级)

每个网格独立构建一棵 BVH,流程如下:

css 复制代码
网格顶点数据
    │
    ▼
计算每个三角形的 AABB
    │
    ▼
计算 Morton Code(Z-order 曲线,空间编码)
    │
    ▼
GPU Radix Sort(按 Morton Code 排序)
    │
    ▼
构建 Radix Tree(确定父子关系)
    │
    ▼
自底向上合并 AABB(BVH 内部节点)
    │
    ▼
重排三角形数据(缓存友好布局)

Morton Code 将三维空间坐标编码为一维整数,排序后相邻三角形在空间上也相邻,BVH 遍历时缓存命中率更高。

GPU Radix Sort 是整个构建流程中最复杂的部分,通过多趟 GPU Compute Shader 完成,避免 CPU-GPU 数据回传。

3.2 TLAS(Top-Level AS,场景级)

将所有 BLAS 合并为场景级 BVH,每个节点存储:

  • 网格实例的世界矩阵 / 逆矩阵
  • 对应 BLAS 的索引
  • 材质 ID

光线先与 TLAS 求交,命中后再进入对应 BLAS 精确求交,大幅减少无效计算。


四、材质系统与纹理图集

4.1 纹理图集(Texture Atlas)

场景中所有材质的纹理被打包进 2D Texture Array,每层 1024×1024,按属性分组:

图集 内容
Albedo Atlas 基础色 + 透明度
Normal Atlas 法线贴图
Emission Atlas 自发光
MRCC Atlas 金属度 / 粗糙度 / 清漆
Sheen Atlas 光泽颜色 / 强度
Transmission Atlas 透射 / 次表面散射

这样在着色器中只需一次纹理绑定,通过材质 ID 和 UV 变换矩阵索引任意材质属性,避免了频繁切换纹理绑定的开销。

4.2 材质数据打包

每个材质的参数(粗糙度、金属度、IOR、各图集层索引等)被打包进 Storage Buffer,着色器通过材质 ID 直接读取,支持完整的 PBR 材质模型:

  • 漫反射 / 镜面反射
  • 清漆(Clearcoat)
  • 光泽(Sheen)
  • 透射(Transmission)
  • 次表面散射(Subsurface)

五、路径追踪核心

5.1 采样策略

渲染器使用分层采样(Stratified Sampling)结合抖动(Jitter)

复制代码
每像素 → 预计算分层采样表 → 加噪声纹理抖动 → 低差异序列
  • 每次弹射使用 11 个采样维度(方向、材质、光源选择等)
  • 最大弹射深度:11 次
  • 深度 ≥ 2 后启用**俄罗斯轮盘赌(Russian Roulette)**随机终止路径,无偏估计能量

5.2 光照采样

直接光照(Next Event Estimation):

  • 支持最多 100 个光源
  • 按光源强度加权随机选择,减少方差

环境光照(Environment Map Importance Sampling):

  • 预计算环境贴图的 CDF(累积分布函数)
  • 采样时用二分查找 CDF,优先采样亮区,大幅降低噪声

5.3 Ping-Pong 累积缓冲

渲染器维护两张累积纹理(A / B),每帧交替作为读写目标:

css 复制代码
第 N 帧:读 A,写 B(混合新采样)
第 N+1 帧:读 B,写 A

相机静止时,帧数不断累积,画面逐渐收敛到无噪声的最终结果。相机移动时立即重置累积。

5.4 Tone Mapping

最终输出使用 ACES Filmic 色调映射曲线,还原电影级色彩表现,并进行 sRGB Gamma 校正。


六、自适应分块渲染

WebGPU 的 GPU 超时机制(TDR)会在单次提交耗时过长时强制重置设备。为此,渲染器将每帧的计算任务拆分为多个小块(Tile)分批提交:

自适应算法:

ini 复制代码
目标:每块耗时 ≈ 21ms

实际耗时 > 21ms → 缩小 pixelsPerTile
实际耗时 < 21ms → 扩大 pixelsPerTile

调整公式:
pixelsPerTile += strength × sign(error) × √|error|
(strength = 5000,快速收敛)

范围限制:[8192, 全屏像素数]

这样在不同性能的 GPU 上都能保持流畅,既不会触发超时,也不会因块太小而浪费调度开销。


七、渲染流程总览

markdown 复制代码
用户打开场景
    │
    ▼
GPUAssetManager 加载 glTF 模型
    │
    ▼
BVHBuilderPlugin 构建 BLAS(每个网格)
    │
    ▼
BVHBuilderPlugin 构建 TLAS(场景级)
    │
    ▼
打包材质纹理图集 → Storage Buffer
    │
    ▼
渲染循环开始
    │
    ├─ 相机移动?→ 重置累积缓冲
    │
    ▼
TileRender 分块调度
    │
    ▼
GPURayTrace Compute Shader(路径追踪)
    │
    ├─ BVH 求交
    ├─ 材质采样(PBR)
    ├─ 直接光照 + 环境光照
    └─ 写入累积缓冲
    │
    ▼
Tone Mapping(ACES)→ 输出到屏幕

八、关键技术亮点

  1. 纯 WebGPU 实现:所有计算(BVH 构建、路径追踪、后处理)全部在 GPU 上完成,CPU 只负责调度,无需 CPU-GPU 数据回传。

  2. GPU Radix Sort:BVH 构建中的排序完全在 GPU 上执行,避免了传统 CPU 排序的性能瓶颈。

  3. 自适应分块:动态调整每块像素数,在任意 GPU 上都能保持流畅,不触发 TDR 超时。

  4. CDF 环境光采样:预计算环境贴图亮度分布,采样时优先选择高亮区域,相比均匀采样噪声降低数倍。

  5. 完整 PBR 支持:支持清漆、光泽、透射、次表面散射等高级材质,与 glTF 2.0 扩展完全兼容。


相关推荐
浇头面加面2 小时前
📊 流式输出实现总结
前端
qq_12084093712 小时前
Three.js 与前端框架集成实战:Vue/React 生命周期对齐与热更新避坑
javascript·vue.js·前端框架
donecoding2 小时前
对象模型与内存的“钥匙理论”:TS 切入的 Go 的结构体与指针
javascript·typescript·go
阿正的梦工坊2 小时前
JavaScript 函数组合(Compose & Pipe)详解
开发语言·javascript·网络
IT_陈寒2 小时前
Java集合的这个坑,我调试了整整3小时才爬出来
前端·人工智能·后端
前端老石人3 小时前
前端网站换肤功能的 3 种实现方案
开发语言·前端·css·html
冴羽yayujs3 小时前
2026 年的 JavaScript 已经不是你认识的 JavaScript 了
前端·javascript
小灰灰搞电子3 小时前
PyQt QWebChannel详解-C++与Web页面的无缝双向通信
前端·pyqt
M ? A3 小时前
你的 Vue v-for,VuReact 会编译成什么样的 React 代码?
前端·javascript·vue.js·经验分享·react.js·面试·vureact