两千万点点云,打开就卡死
PLY 文件 1.8 GB,加载后浏览器内存涨到 3 GB,帧率 3 fps,动一下鼠标要等两秒。
现象
点云一次性全部载入,首屏白屏 40 秒后出现点阵。
帧率稳定在 3 fps,Chrome 任务管理器显示标签页内存 3.1 GB。
缩放时画面卡住,偶尔弹出 Array buffer allocation failed。
原因
两千万个点,每个点位置 12 字节、颜色 3 字节,仅顶点数据就 300 MB;
加上解析阶段的中间对象,很容易超过 2 GB。
THREE.Points 一次 draw call 绘制全部顶点,GPU 顶点处理阶段完全饱和。
如果把 PointsMaterial.size 设为固定像素并关闭
sizeAttenuation,近处点会大到糊满屏幕,overdraw 再叠加一层压力。
移动端 devicePixelRatio 为 3 时,填充率还要再乘九倍。
排查过程
- 先算清顶点数:
geometry.attributes.position.count。 - 用
renderer.info看points与calls的数量,确认是单次大调用还是多次调用。 - 把
renderer.setPixelRatio(1)试一下,帧率若明显提升,瓶颈在填充率。
console.log(points.geometry.attributes.position.count); // 19874321
console.log(THREE.WebGLRenderer.info ? '' : '');
console.log(renderer.info.render.points, renderer.info.render.calls);
解决方案
方案一:降低绘制成本。点大小固定为 2 像素,关闭尺寸衰减,像素比封顶 2:
var mat = new THREE.PointsMaterial({
size: 2,
sizeAttenuation: false,
vertexColors: true,
transparent: false,
depthWrite: true
});
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
方案二:按空间分块,只加载视野内的块。把点云切成 500 米的瓦片,
每块一个 Points 对象,配合 frustumCulled 自动裁剪:
var tiles = {};
function loadTile(key, positions, colors) {
var geo = new THREE.BufferGeometry();
geo.setAttribute('position', new THREE.BufferAttribute(positions, 3));
geo.setAttribute('color', new THREE.BufferAttribute(colors, 3));
var pts = new THREE.Points(geo, mat);
pts.frustumCulled = true;
pts.computeBoundingSphere();
scene.add(pts);
tiles[key] = pts;
}
// 相机移动后只保留半径 2 公里内的块
function updateTiles(center) {
Object.keys(tiles).forEach(function (k) {
tiles[k].visible = tiles[k].position.distanceTo(center) < 2000;
});
}
方案三:换用自带 LOD 的点云渲染方案。Potree 按八叉树分块, 每块有多级精度,千万级点云也能保持 30 fps 以上:
var potree = new Potree.loadPointCloud('/pointcloud/metadata.json', function (e) {
scene.add(e.pointcloud);
e.pointcloud.material.size = 1.5;
e.pointcloud.material.pointSizeType = Potree.PointSizeType.ADAPTIVE;
});
验证
首屏内存在 800 MB 以内,加载时间降到 5 秒级。
在 1080p 分辨率下拖动视角,帧率保持在 30 fps 以上。
把相机移到视野外再移回,只有附近的块被绘制,
renderer.info.render.points 数值随视野变化。
先降像素比再谈分块:很多“点云卡死”其实是高分屏填充率问题,
setPixelRatio(Math.min(dpr, 1.5)) 一行就能让帧率翻倍,
代价只是轻微变糊,成本远低于重构数据。
经纬志(2026)。《两千万点点云,打开就卡死》。https://www.jingweizhi.com/cookbook/three-pointcloud-lag.html(访问日期 2026-11-03)。