Appearance
WebGL 渲染覆盖率 30% → 93%
通过 KTX2 纹理压缩 + Draco 几何压缩 + 异步分帧加载 + 后台机型分级,将 3D 虚拟形象覆盖率从 30% 提升至 93%。
背景
B 站用户虚拟形象 1.5 版本选型 Three.js(而非 Unity WebGL),原因是渲染效果可塑性高。但上线后面临两个问题:
- 低端机无法加载:模型文件太大,内存不足直接崩溃
- 首次加载时间过长:用户打开页面需要等 5-10 秒才能看到虚拟形象
问题分解
| 子问题 | 影响 |
|---|---|
| 模型体积大(原始 GLTF > 20MB) | 下载慢、内存占用高 |
| 纹理体积大(PNG 贴图多张) | 显存占用高、加载慢 |
| 同步加载阻塞主线程 | 白屏时间长 |
| 低端机 WebGL 特性不支持 | 直接无法渲染 |
方案
KTX2 纹理压缩
- 将 PNG 贴图转换为 KTX2 格式(GPU 原生支持的压缩纹理格式)
- 在 GPU 上直接解压,节省 CPU 和带宽
- 收益:纹理体积减少 60-80%
Draco 几何压缩
- GLB/GLTF 的 Mesh 几何数据用 Draco 算法压缩
- 浏览器端 JS 异步解压
- 收益:模型体积减少 50-70%
异步分帧加载
- 不阻塞主线程:模型加载放入 Web Worker
- 分批加载:先加载骨架 + 基础 Mesh(用户立即看到模型轮廓),再异步加载贴图和细节
- 收益:首帧展示时间从 5-10 秒降至 < 2 秒
后台机型分级策略
- 服务器根据设备型号返回不同精度的模型
- 高端机 → 完整模型 + 高清贴图
- 低端机 → 简化模型 + 压缩贴图 + 减少配件
- 收益:低端机也能加载 3D(覆盖率从 30% → 93%)
结果
| 指标 | 优化前 | 优化后 |
|---|---|---|
| 3D 机型覆盖率 | 30% | 93% |
| 模型体积 | > 20MB | < 3MB(压缩后) |
| 首次加载 | 5-10s | < 2s |
| 内存峰值 | > 512MB | < 200MB |
教训
- "Web 端不如原生"是偏见——WebGL 优化空间巨大
- 机型分级不是技术问题,是策略问题——需要后台配置支持
- KTX2 兼容性需要测试多个浏览器(Safari 支持较晚)