我有一个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
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
的距离。