Atlaslog / Field Notes / three.js rendering
Field note · three.js rendering
Twenty million points freeze the tab at 3 fps
Quick answer
A 1.8 GB PLY loads as one Points object, pushing tab memory to 3.1 GB and the frame rate to 3 fps. All vertices go through a single draw call, saturating the vertex stage and fill rate.
Symptom
- position.count reports 19874321 and the tab uses 3.1 GB with 3 fps while dragging.
- Chrome occasionally throws 'Array buffer allocation failed'.
- Zooming stalls the page, and on a devicePixelRatio 3 phone the fill cost triples again.
Checklist
- Print geometry.attributes.position.count to size the dataset.
- Read renderer.info.render.points and .calls to confirm one giant call.
- Call renderer.setPixelRatio(1) and check whether fps doubles, which indicates a fill-rate limit.
- Compare heap usage before and after parsing to see whether object overhead dominates.
Fix
Use PointsMaterial with size 2, sizeAttenuation false and cap the pixel ratio at 2, tile the cloud into 500 m chunks with frustumCulled and a bounding sphere, or move to Potree with pointSizeType ADAPTIVE.
Code
console.log(points.geometry.attributes.position.count); // 19874321
console.log(THREE.WebGLRenderer.info ? '' : '');
console.log(renderer.info.render.points, renderer.info.render.calls);var mat = new THREE.PointsMaterial({
size: 2,
sizeAttenuation: false,
vertexColors: true,
transparent: false,
depthWrite: true
});
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
Watch out
- Lowering point size alone does nothing when the whole cloud is one draw call holding 300 MB of attributes.
- Loading all 20 million points and only setting visible = false keeps the memory and upload cost.
English edition written for Atlaslog from the original Chinese field note. Code is unchanged and runs as-is.
Atlaslog (2026). Twenty million points freeze the tab at 3 fps. https://www.jingweizhi.com/en/cookbook/three-pointcloud-lag.html (accessed 2026-11-03).