Three.js: Как создать новую "изменяющуюся" геометрию, если у меня есть все необходимые буферы?
Я использую веб-работника, чтобы загрузить .json
файл анимированной 3D модели. Для каждого из больших массивов (вершин, нормалей и т. Д.) Я передаю Float32Array
Буфер обратно в поток пользовательского интерфейса. Поскольку такие буферы являются переносимыми объектами, это займет (почти) нулевое время.
Теперь выясняется, что WebGL (и, следовательно, Three.js) используют Float32Array
Внутренние буферы тоже. Это означает, что я мог бы загрузить эту 3D-анимацию, ничего не копируя, потратив почти нулевое время в основном потоке. Разве это не мило?
Но не ясно, как это сделать: в главном потоке у нас есть буферы массивов для вершин, нормалей (основных и морфовых) и граней. Как мне создать рабочий Geometry
(или же BufferGeometry
) из этих, без перевода или копирования данных?
var scene,
vertices, normals, faces,
morphVertices, morphNormals; // <-- we have all these as typed arrays
var geometry = ...; // <-- insert code here
var material = new THREE.MeshLambertMaterial({ morphTargets: true });
var object3D = new THREE.MorphAnimMesh(geometry, material);
scene.add(object3D);
Этот ответ дает подсказку, но только пункт 7 представляется актуальным, он предполагает, что уже есть некоторые Geometry
экземпляр, и он не обрабатывает морф-цели.
1 ответ
Вот пример, основанный на части загрузки сетки в THREE.GLTF2Loader.
// Create BufferGeometry and assign vertices and normals.
var geometry = new THREE.BufferGeometry();
geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
geometry.setIndex( new THREE.BufferAttribute( faces, 3 ) );
// Create material.
var material = new THREE.MeshStandardMaterial({
morphTargets: true,
morphNormals: true
});
// Set up morph target attributes.
var posAttr = new THREE.BufferAttribute( morphVertices, 3 );
var normAttr = new THREE.BufferAttribute( morphNormals, 3 );
for (var i = 0; i < posAttr.array.length; i++) {
posAttr.array[i] += geometry.attributes.position.array[i];
}
for (var j = 0; j < normAttr.array.length; j++) {
normAttr.array[j] += geometry.attributes.normal.array[j];
}
// Assign morph target attributes.
geometry.morphAttributes.position = [ posAttr ];
geometry.morphAttributes.normal = [ normAttr ];
// Create Mesh.
var mesh = new THREE.Mesh(geometry, material);
mesh.updateMorphTargets();
// Apply 50/50 blend of morph targets and default position/normals.
mesh.morphTargetInfluences[0] = 0.5;
three.js r86-dev.