Three.js缓冲几何动画

Three.js Buffer Geometry Animation

我有 Three.js 场景,基本上在给定区域上散布了一堆三角形。


        geometry = new THREE.BufferGeometry();
        geometry.dynamic = true;

        positions = new Float32Array(triangles * 3 * 3);
        const normals = new Float32Array(triangles * 3 * 3);
        const colors = new Float32Array(triangles * 3 * 3);

        const color = new THREE.Color();

        const n = 200,
          n2 = n / 2; // triangle's spread distance

        const d = 1000,
          d2 = d / 2; // individual triangle size

        const pA = new THREE.Vector3();
        const pB = new THREE.Vector3();
        const pC = new THREE.Vector3();

        const cb = new THREE.Vector3();
        const ab = new THREE.Vector3();

        for (let i = 0; i < positions.length; i += 9) {
          // position

          const x = Math.random() * n - n2;
          const y = Math.random() * n - n2;
          const z = Math.random() * n - n2;

          const ax = x + Math.random() * d - d2;
          const ay = y + Math.random() * d - d2;
          const az = z + Math.random() * d - d2;

          const bx = x + Math.random() * d - d2;
          const by = y + Math.random() * d - d2;
          const bz = z + Math.random() * d - d2;

          const cx = x + Math.random() * d - d2;
          const cy = y + Math.random() * d - d2;
          const cz = z + Math.random() * d - d2;

          positions[i] = ax;
          positions[i + 1] = ay;
          positions[i + 2] = az;

          positions[i + 3] = bx;
          positions[i + 4] = by;
          positions[i + 5] = bz;

          positions[i + 6] = cx;
          positions[i + 7] = cy;
          positions[i + 8] = cz;

          if (i === 0) console.log(positions);

          // flat face normals

          pA.set(ax, ay, az);
          pB.set(bx, by, bz);
          pC.set(cx, cy, cz);

          cb.subVectors(pC, pB);
          ab.subVectors(pA, pB);
          cb.cross(ab);

          cb.normalize();

          const nx = cb.x;
          const ny = cb.y;
          const nz = cb.z;

          normals[i] = nx;
          normals[i + 1] = ny;
          normals[i + 2] = nz;

          normals[i + 3] = nx;
          normals[i + 4] = ny;
          normals[i + 5] = nz;

          normals[i + 6] = nx;
          normals[i + 7] = ny;
          normals[i + 8] = nz;

          // colors

          const vx = x / n + 0.5;
          const vy = y / n + 0.5;
          const vz = z / n + 0.5;

          color.setRGB(vx, vy, vz);

          colors[i] = color.r;
          colors[i + 1] = color.g;
          colors[i + 2] = color.b;

          colors[i + 3] = color.r;
          colors[i + 4] = color.g;
          colors[i + 5] = color.b;

          colors[i + 6] = color.r;
          colors[i + 7] = color.g;
          colors[i + 8] = color.b;
        }

        geometry.setAttribute(
          "position",
          new THREE.BufferAttribute(positions, 3)
        );
        geometry.setAttribute("normal", new THREE.BufferAttribute(normals, 3));
        geometry.setAttribute("color", new THREE.BufferAttribute(colors, 3));

        geometry.computeBoundingSphere();

        let material = new THREE.MeshPhongMaterial({
          color: 0xaaaaaa,
          specular: 0xffffff,
          shininess: 250,
          side: THREE.DoubleSide,
          vertexColors: true,
        });

        mesh = new THREE.Mesh(geometry, material);
        scene.add(mesh);

我想做的是让三角形开始靠得很近,然后随机向各个方向扩展。

如何创建更新三角形位置的动画循环?

我一直在使用 three.js 网站上的示例代码: https://github.com/mrdoob/three.js/blob/master/examples/webgl_interactive_buffergeometry.html

编辑:我可以用 this.mesh.scale.z += 0.005 扩大三角形,但三角形本身也会变大。有没有办法保持三角形大小相同但改变覆盖面积?

您可以使用变形目标。

在此处提供代码笔:
https://codepen.io/cdeep/pen/WNENOmK

代码灵感来自three.js例子:
https://threejs.org/examples/?q=morph#webgl_morphtargets.

在为每个顶点分配初始位置的同时,还要分配顶点展开后必须结束的最终位置。

本质上,

const positions = new Float32Array( triangles * 3 * 3 );
const morphedPositions = new Float32Array(triangles * 3 * 3);
...
...
geometry.morphAttributes.position = [];
geometry.morphAttributes.position[ 0 ] = new THREE.BufferAttribute( morphedPositions, 3);
mesh.morphTargetInfluences[ 0 ] = morphValue;

morphValue 设置动画以影响 position 属性与 morphedPositions 的接近程度。