渲染性能优化指南
本指南帮助在不同性能等级的设备上调优 SDK,获得流畅的 3DGS(3D Gaussian Splatting)渲染体验。
1. 关闭抗锯齿
Three.js 的 WebGLRenderer 默认不启用抗锯齿。如果你的项目中开启了 antialias: true,在性能敏感场景建议关闭:
const renderer = new THREE.WebGLRenderer({ antialias: false });
为什么可以关闭? 3DGS 的每个高斯点本身就是一个平滑衰减的半透明椭圆,大量椭圆叠加后边缘天然平滑,不需要额外的多重采样抗锯齿(MSAA)。关闭 MSAA 可减少 GPU 对每个像素的采样次数(通常从 4 次降为 1 次),提升渲染帧率。
Cesium 用户:Cesium 的 Viewer 默认不开启 MSAA,无需额外操作。
2. 降低渲染分辨率
通过降低设备像素比,可以成比例减少 GPU 需要处理的像素总数。这是对 GPU 填充率瓶颈最有效的手段。
Three.js:
// High-performance device: use native pixel ratio
renderer.setPixelRatio(window.devicePixelRatio);
// Mid-range device: cap pixel ratio
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 1.5));
// Low-end device / mobile: fixed 1x rendering
renderer.setPixelRatio(1.0);
Cesium:
const viewer = new Cesium.Viewer('container', {
// Control rendering resolution via resolutionScale
resolutionScale: 1.0 // Use 1.0 for low-end devices; use window.devicePixelRatio for high-end
});
性能差异参考(以 1080p 逻辑分辨率为例):
| 像素比 | 实际渲染像素 | 相对开销 |
|---|---|---|
| 1.0 | 1920×1080 ≈ 207 万 | 1× |
| 1.5 | 2880×1620 ≈ 466 万 | 2.25× |
| 2.0 | 3840×2160 ≈ 829 万 | 4× |
| 3.0 | 5760×3240 ≈ 1866 万 | 9× |
高 DPI 屏幕(如 Retina)的
devicePixelRatio通常为 2 或 3,降低到 1.0 可获得 4~9 倍的片元处理性能提升,代价是渲染画面变模糊。
3. 限制最大渲染点数 — setMaxSplats
这是最重要的性能调节参数。 它控制每帧参与渲染的高斯点总数上限。
lccObj.setMaxSplats(3000000); // Max 3 million splats per frame
SDK 的 LOD 调度器在每帧遍历场景的空间索引,按距离和视锥选出需要渲染的节点。当总点数超过此限制时,调度器会从远处或低优先级的节点开始丢弃,直到总点数满足限制。
取值参考:PC 端 90 万 ~ 1000 万,移动端 50 万 ~ 260 万,根据设备性能选择。详见文末设备分档推荐配置。
4. 限制单节点最大点数 — setMaxNodeSplats
控制单个空间节点的最大渲染点数。超过此阈值的节点会被自动降级到更粗糙的 LOD 等级。
lccObj.setMaxNodeSplats(1500000); // Max 1.5 million splats per node
为什么需要这个参数? 在大型场景中,建筑密集区等高密度区域的单个节点在最高 LOD 下可能包含数百万个高斯点。如果不限制,相机靠近时一个节点就会占满整个渲染预算,导致其它区域没有预算可用。这个参数让渲染预算的分配更均匀。
取值建议:通常设为 setMaxSplats 值的 1/3 ~ 2/3,具体取决于场景密度和档位。详见文末设备分档推荐配置。
5. 限制渲染起始 LOD — setStartLod
控制最高精度等级。LOD 0 为最精细,数值越大精度越低。
lccObj.setStartLod(0); // Finest quality (desktop default)
lccObj.setStartLod(1); // Skip finest level (mobile default)
lccObj.setStartLod(2); // Skip first two levels (very low-end devices)
SDK 对场景数据进行了多级 LOD 构建。LOD 0 包含完整精度数据,LOD 1 约为 LOD 0 的 1/2 点数,以此类推逐级递减。setStartLod 限制调度器可选择的最低 LOD 等级:设为 1 表示即使相机贴近物体,也不会加载 LOD 0 数据。
性能影响:
| 设置 | 近处精度 | 渲染点数减少 | 适用场景 |
|---|---|---|---|
setStartLod(0) | 最高 | — | PC 高端 |
setStartLod(1) | 中等 | 约 50% | PC 中端及以下、移动端全档位 |
setStartLod(2) | 较低 | 约 75% | PC / 移动端低端 |
6. 限制最大渲染距离 — setMaxDistance
控制从相机出发的最大渲染距离,单位为米。超出此距离的内容不会被下载、解压和渲染。
lccObj.setMaxDistance(200); // Desktop default
lccObj.setMaxDistance(100); // Mobile default
减小最大距离可以减少可见节点数量,降低网络下载、CPU 排序和 GPU 渲染的全链路开销。适合室内或近距离浏览场景。
注意:SDK 内置了高度自适应机制——当相机升至高空(> 20 米)后,会自动放宽距离限制,使俯瞰视角能看到更远的范围。
取值参考:
| 平台 | 范围 |
|---|---|
| PC | 100 ~ 240 |
| 移动端 | 80 ~ 110 |
详见文末设备分档推荐配置。
7. LOD 自动优化 — setLodAutoLevelUp
启用后,SDK 会在渲染预算有余裕时自动提升部分节点的精度。
lccObj.setLodAutoLevelUp(true); // Enable (recommended for mid-to-high-end devices)
lccObj.setLodAutoLevelUp(false); // Disable (recommended for low-end devices or stable frame rate)
当实际渲染点数低于 setMaxSplats 的限制时(比如相机看向空旷区域),自动优化机制会把剩余预算分配给近处节点,自动加载更高精度的 LOD 数据来补充细节。
权衡:开启后画质更好,但可能触发额外的数据下载和解压,在低端设备上有可能导致偶尔的帧率波动。
8. 球谐光照 — useShcoef
球谐光照(Spherical Harmonics,SH)让高斯点的颜色能够随观察角度变化,呈现更真实的反光和光泽效果。SDK 默认关闭。
// Check if data contains SH coefficients before enabling
if (lccObj.hasShcoef()) {
lccObj.useShcoef(true, (percent) => {
console.log('SH loading: ' + (percent * 100).toFixed(1) + '%');
});
}
// Disable
lccObj.useShcoef(false, () => {});
开启效果:
- 物体表面的反光、光泽随视角自然变化
- 渲染品质显著提升,尤其是对金属、玻璃、漆面等高光材质
性能代价:
- GPU 显存增加,需要额外存储 RGB 球谐系数
- GPU 顶点着色计算量增加,需要额外计算 15 个球谐基函数
- 对于LCC格式,需要额外下载 SH 数据文件
建议:仅在高端桌面设备上开启。移动端不建议使用。
9. 其它优化选项
本地缓存(IndexedDB)
通过 useIndexDB: true(默认开启)启用本地数据缓存。二次访问同一场景时直接从本地读取,大幅减少加载时间。
LOD 平滑过渡
LCC2 支持 LOD 平滑过渡(默认开启),减少 LOD 切换时的视觉跳变:
lccObj.setSmooth(true); // Enable (default)
lccObj.setSmooth(false); // Disable
该功能通过约束相邻空间节点的 LOD 差异,消除精度断层。CPU 开销极小,建议保持开启。
设备分档推荐配置
PC
| 档位 | splatCount | nodeSplatCount | distance | startLod | devicePixelRatio |
|---|---|---|---|---|---|
| High | 10,000,000 | 6,000,000 | 240 | 0 | 原生 dpr |
| MidHigh | 4,200,000 | 1,500,000 | 220 | 1 | 原生 dpr |
| Balance | 2,200,000 | 1,000,000 | 200 | 1 | dpr > 1 ? 1.4 : dpr |
| MidLow | 1,800,000 | 700,000 | 150 | 2 | 1 |
| Low | 900,000 | 400,000 | 100 | 2 | dpr > 1 ? 0.8 : 0.5 |
Mobile
| 档位 | splatCount | nodeSplatCount | distance | startLod | devicePixelRatio |
|---|---|---|---|---|---|
| High | 2,600,000 | 1,000,000 | 110 | 1 | 原生 dpr |
| MidHigh | 1,800,000 | 800,000 | 100 | 1 | 原生 dpr |
| Balance | 1,000,000 | 600,000 | 90 | 1 | dpr > 1 ? 1.2 : dpr |
| MidLow | 800,000 | 400,000 | 80 | 2 | 1 |
| Low | 500,000 | 300,000 | 80 | 2 | 0.8 |