Skip to content

269. 点云(二)

Published:

上节实现了点云的效果:

2025-10-11 19.20.11.gif

这节我们继续完善。

首先,同一种颜色的点太单调了,我们可以指定不同的顶点颜色:

顶点位置是 geometry.attribute.position

顶点颜色是 geometry.attribute.color

image.png

我们生成一个和顶点一一对应的 colors 数组,设置随机的颜色。

let colors = [];
const colorArr = [
    new THREE.Color('red'),
    new THREE.Color('blue'),
    new THREE.Color('green'),
    new THREE.Color('pink'),
    new THREE.Color('yellow')
];
for (let i = 0; i < vertices.length; i++) {
    const color = colorArr[Math.floor(Math.random() * colorArr.length)];
    colors.push(color.r, color.g, color.b);
}
bufferGeometry.setAttribute(
    'color',
    new THREE.Float32BufferAttribute(colors, 3),
);
const pointMaterial = new THREE.PointsMaterial({
    size: 0.5,
    // color: 'orange'
    vertexColors: true
});

指定 PointsMaterial 开启 vertexColors

然后设置 geometry.attributes.color 数组

看下效果:

2025-10-11 22.40.58.gif

现在,点云的每个点的颜色就是随机的了。

此外,你也可以不断增加采样点,而不是固定的 10000 个采样点:

初始 1000 个采样点:

image.png

后续每秒增加 1000 个:

image.png

setInterval(() => {
    gltf.scene.traverse(obj => {
        if(obj.isMesh) {
            const sampler = new MeshSurfaceSampler(obj).build();

            const position = new THREE.Vector3();
            for (let i = 0; i < 1000; i++) {
                sampler.sample(position);
                position.multiplyScalar(50);
                vertices.push(position.x, position.y, position.z);
            }
            bufferGeometry.setAttribute(
                'position',
                new THREE.Float32BufferAttribute(vertices, 3),
            );
        }
    })
}, 1000);

看下效果:

2025-10-11 23.31.36.gif

刚开始采样点是不断增加的,后面就渲染报错了:

image.png

这是因为顶点颜色数量和顶点对应不上了。

我们顶点颜色数组也要同步修改:

image.png

for (let i = 0; i < vertices.length; i++) {
    const color = colorArr[Math.floor(Math.random() * colorArr.length)];
    colors.push(color.r, color.g, color.b);
}
bufferGeometry.setAttribute(
    'color',
    new THREE.Float32BufferAttribute(colors, 3),
);

加上顶点颜色的修改,把增加频率加大。

但也不能无限增加,当 vertices 数组元素数量大于 6w 就 return,不再增加

image.png

if(vertices.length >= 60000) {
    return;
}

2025-10-11 23.38.55.gif

案例代码上传了小册仓库

总结

这节我们给点云效果加上了随机顶点颜色,以及逐渐增加顶点的效果。

这里的点云数据是从模型上采样的,实际上的点云是用物理设备扫描出来的一些点。

但如果你自己要实现这种点云效果,就可以用 MeshSurfaceSampler 网格模型表面采样器实现。

评论