ThreeJs入门29-WebGl性能篇:高效地绘制50万个点数据

「这是我参与2022首次更文挑战的第33天,活动详情查看:2022首次更文挑战

示例代码采用three.js-r73版本: cdnjs.cloudflare.com/ajax/libs/t…

  • 在webgl当中,对于点的操作是比较频繁的,比如数据的热点,粒子效果,都需要绘制比较小的点或者面的数据。所以我们需要了解如何高效地绘制点数据。让我们来看看吧。

  • 渲染点的过程和渲染三角形过程是一样的,只是创建点的方法不一样。为了让没有看过之前文章同学也能看懂,我们还是按照创建过程写一遍。

初始化场景

  • 我们给场景添加雾效果
function initScene() {
    scene = new THREE.Scene();
    scene.fog = new THREE.Fog(0x050505, 2000, 3500);
}
复制代码

初始化相机

  • 把相机添加到场景中
const near = 1;
const far = 3500;

function initCamera() {
    camera = new THREE.PerspectiveCamera(27, width / height, near, far);
    camera.position.z = 2750;
    scene.add(camera);
}
复制代码

初始化灯光

  • 创建一个环境光,两个平行光
function initLight() {
    scene.add(new THREE.AmbientLight(0x444444));
    light = new THREE.DirectionalLight(0xffffff, 0.5);
    light.position.set(1, 1, 1);
    scene.add(light);

    var light2 = new THREE.DirectionalLight(0xffffff, 1.5);
    light2.position.set(0, -1, 0);
    scene.add(light2);
}
复制代码

绘制50万个点,帧数载30帧以上

初始化存储空间

 // 点
var particles = 50 * 10000;

var geometry = new THREE.BufferGeometry();
// 生成 50万个点需要的存储空间
var positions = new Float32Array(particles * 3);

// 每个顶点一种颜色
var colors = new Float32Array(particles * 3);

var color = new THREE.Color();
复制代码

限定点出现的范围

var n = 800, n2 = n / 2; // 限定点出现的范围是[-400,400]这么一个立方体中,n2表示直径的一半
复制代码

遍历存储空间长度,生成随机点

for (var i = 0; i < positions.length; i += 9) {
  // 通过随机数生成点的位置

  // 生成一个顶点,范围是[-400,400]
  var x = Math.random() * n - n2;
  var y = Math.random() * n - n2;
  var z = Math.random() * n - n2;

  // 随机生成点
  positions[i] = x;
  positions[i + 1] = y;
  positions[i + 2] = z;
}
复制代码

为每个点赋值颜色

// 为每个顶点赋值颜色
// x / n得到范围[-0.5,0.5],加0.5得到[0,1]范围的颜色
var vx = (x / n) + 0.5
var vy = (y / n) + 0.5
var vz = (z / n) + 0.5

color.setRGB(vx, vy, vz)

colors[i] = color.r
colors[i + 1] = color.g
colors[i + 2] = color.b
复制代码

给几何体添加点位和颜色属性

geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3))
geometry.addAttribute('color', new THREE.BufferAttribute(colors, 3))
// 计算几何体的包围盒
geometry.computeBoundingSphere();
复制代码

创建点材质和点几何体

// 创建点材质
var material = new THREE.PointsMaterial({
    size: 10,
    vertexColors: THREE.VertexColors
})

// 创建点
particleSystem = new THREE.Points(geometry, material);
scene.add(particleSystem);
复制代码
  • 完成的效果

image.png codepen示例代码

新的API学习

点材质PointsMaterial

PointsMaterial是一个点材质,主要和粒子系统一起使用。

  • size:点的大小
  • vertexColors:点的颜色

THREE.Points点几何体

  • point是一个显示点的粒子系统
  • Points(geometry, material)
  • 如果觉得不过,可以点点赞。

猜你喜欢

转载自juejin.im/post/7066230349386219550