经纬志
首页 / three.js / 使用示例

自定义属性点云

三万个采样点除了位置,还带 aSize、aTint、aPhase 三条自定义属性。顶点着色器决定点在屏幕上的像素大小,片元着色器负责抠圆与混色。

three.js 0.160.0 · 更新 2026-10-28
源码与运行效果
运行效果

顶点着色器要点

gl_PointSize 以像素为单位,不是世界单位。要让点看起来符合透视, 需要除以视图空间的 -mv.z,也就是距离相机的深度。 示例里再乘一个 uPixel 用来调基础大小,乘以 aSize 体现每个点的差异。

浓度属性 aTint 直接传给片元着色器,在蓝到橙两个颜色之间插值。 顶部还按 aPhase 做了正弦偏移,让烟羽有缓慢起伏。 这类动画要在着色器里做,放到 CPU 上改三万次 position 会掉到十几帧。

属性类型用途
positionvec3顶点的世界位置
aSizefloat单点尺寸倍率,0.6 – 2.2
aTintfloat浓度色标,0 为稀薄、1 为浓密
aPhasefloat动画相位,打散同步起伏

为什么用叠加混合

AdditiveBlending 让重叠的点越叠越亮,很接近烟尘、热力、夜光散布这类数据的观感。 代价是不做深度排序,靠近相机的点不会遮住后面的点。 需要正确遮挡时改用 NormalBlending 并打开 depthWrite,但边缘会出现一圈硬边,得靠 alphaTest 收掉。

属性名不要和内置冲突。自定义属性以 a 开头命名,避免与 position、normal、uv 这些内置名混淆。 另外 ShaderMaterial 不会自动处理色彩空间,颜色值按线性空间写入。