Скелетная анимация в Three.js позволяет создавать сложные деформации объектов, управляемые системой костей. Основные строительные блоки — это Skeleton, Bone и SkinnedMesh. Их правильная комбинация обеспечивает реалистичное движение персонажей и других объектов с гибкой структурой.
Bone — это элементарный объект скелета. Он
наследуется от Object3D и обладает всеми его свойствами:
положением (position), вращением (rotation),
масштабом (scale). Каждая кость может иметь дочерние кости,
образуя иерархическую структуру.
Ключевые моменты:
SkeletonHelper.Пример создания кости и добавления дочерней:
const rootBone = new THREE.Bone();
rootBone.position.set(0, 0, 0);
const childBone = new THREE.Bone();
childBone.position.set(0, 5, 0);
rootBone.add(childBone);
Skeleton — это структура, которая хранит массив костей и управляет их влиянием на меш. Она обеспечивает связь между костями и вершинами меша через skinning.
Основные свойства Skeleton:
bones — массив объектов Bone.boneInverses — массив матриц обратного преобразования
костей, используемых для правильного позиционирования вершин.pose() — метод, который возвращает скелет в исходное
положение (bind pose).Создание скелета:
const bones = [rootBone, childBone];
const skeleton = new THREE.Skeleton(bones);
Скелет может быть передан SkinnedMesh, чтобы управлять
деформацией вершин.
SkinnedMesh — это разновидность Mesh,
который поддерживает скелетную анимацию. Для правильной работы
требуется:
skinIndices и skinWeights для
каждой вершины.Skeleton), который контролирует
деформацию.Skinning позволяет вершинам меша плавно перемещаться под влиянием одной или нескольких костей.
Пример создания SkinnedMesh:
const geometry = new THREE.BoxGeometry(2, 2, 2);
const material = new THREE.MeshStandardMaterial({ color: 0x00ff00, skinning: true });
const skinnedMesh = new THREE.SkinnedMesh(geometry, material);
skinnedMesh.add(rootBone);
skinnedMesh.bind(skeleton);
Для работы скелетной анимации вершины геометрии должны содержать данные:
geometry.attributes.skinIndex = new THREE.Uint16BufferAttribute([0, 1, 0, 1], 4);
geometry.attributes.skinWeight = new THREE.Float32BufferAttribute([0.8, 0.2, 0.5, 0.5], 4);
Эти атрибуты позволяют вершинам смешивать воздействие нескольких костей, создавая плавные изгибы.
Для отладки и визуализации структуры костей используется
SkeletonHelper. Он отображает линии между костями, что
помогает проверять и настраивать анимацию.
const helper = new THREE.SkeletonHelper(skinnedMesh);
scene.add(helper);
Three.js поддерживает анимацию скелета через
AnimationClip и KeyframeTrack. Каждый трек
описывает изменение свойств кости (position,
rotation, scale) во времени.
Пример создания анимации вращения кости:
const times = [0, 1, 2];
const values = [0, 0, 0, 0, Math.PI/2, 0, 0, Math.PI, 0];
const track = new THREE.QuaternionKeyframeTrack('.bones[1].quaternion', times, values);
const clip = new THREE.AnimationClip('rotateBone', 2, [track]);
const mixer = new THREE.AnimationMixer(skinnedMesh);
const action = mixer.clipAction(clip);
action.play();
AnimationMixer обновляется в основном цикле
рендеринга:
const clock = new THREE.Clock();
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta();
mixer.update(delta);
renderer.render(scene, camera);
}
animate();
skinIndex и skinWeight должны
иметь минимальное количество влияющих костей на вершину (обычно 4).SkeletonUtils.clone при
дублировании моделей, чтобы сохранить независимые скелеты.Эта структура костей и мешей является основой для создания персонажей, животных и объектов с гибкой анимацией в Three.js, обеспечивая высокую реалистичность и контроль над движениями.