В A-Frame каждая сущность (<a-entity>)
представляет собой обёртку над объектом Three.js. Основной способ
взаимодействия с низкоуровневыми объектами сцены Three.js осуществляется
через свойство object3D. Оно позволяет напрямую
манипулировать геометрией, материалами, позициями, поворотами и другими
свойствами объектов 3D-графики.
object3DКаждый элемент A-Frame содержит несколько ключевых объектов Three.js
в object3D:
object3D – основной объект типа
THREE.Object3D, представляющий сущность.
object3DMap – объект, хранящий
разные версии визуальных представлений:
mesh – геометрия с материалами
(THREE.Mesh) для рендеринга.collision – объект для физического взаимодействия, если
подключены системы физики.camera – объект камеры (THREE.Camera),
если элемент является камерой.light – объект освещения (THREE.Light),
если элемент — источник света.Пример доступа к основному мешу:
const entity = document.querySelector('#myBox');
const mesh = entity.object3DMap.mesh;
mesh.position.set(1, 2, 3);
mesh.rotation.y = Math.PI / 4;
Если object3DMap.mesh отсутствует (например, объект ещё
не создан), можно использовать общий объект object3D,
который всегда присутствует:
entity.object3D.position.set(0, 1, -5);
object3D использует стандартные методы Three.js:
object3D.position.set(x, y, z) или
object3D.position.x += 1.object3D.rotation.set(x, y, z) в радианах.object3D.scale.set(sx, sy, sz).Пример динамического изменения позиции с анимацией:
AFRAME.registerComponent('move-up', {
tick: function (time, timeDelta) {
this.el.object3D.position.y += 0.001 * timeDelta;
}
});
Через object3DMap.mesh.material можно менять цвет,
текстуру, прозрачность:
const mesh = document.querySelector('#mySphere').object3DMap.mesh;
mesh.material.color.set(0xff0000);
mesh.material.transparent = true;
mesh.material.opacity = 0.5;
Изменение геометрии требует создания нового объекта
THREE.Geometry или THREE.BufferGeometry:
const mesh = document.querySelector('#myBox').object3DMap.mesh;
mesh.geometry = new THREE.BoxGeometry(2, 2, 2);
Через object3D можно создавать сложные иерархии:
const parent = document.querySelector('#parentEntity');
const child = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshStandardMaterial({ color: 0x00ff00 })
);
parent.object3D.add(child);
Дочерние объекты наследуют позицию, поворот и масштаб родителя.
Если используется физический движок (например,
aframe-physics-system), object3D позволяет
синхронизировать визуальное представление с физикой:
const entity = document.querySelector('#dynamicBox');
const body = entity.body; // физическое тело, созданное движком
entity.object3D.position.copy(body.position);
entity.object3D.quaternion.copy(body.quaternion);
object3DМожно отслеживать изменения или анимацию объектов:
entity.object3D.traverse((obj) => {
if (obj.isMesh) {
obj.material.color.set(Math.random() * 0xffffff);
}
});
Метод traverse проходит по всем потомкам объекта,
включая вложенные меши, камеры и светильники.
При использовании компонентов A-Frame часто удобнее обновлять
object3D напрямую, чтобы добиться сложных эффектов,
недоступных стандартным компонентам:
THREE.AnimationMixer.material.onBeforeCompile.Пример применения кастомного шейдера:
const mesh = document.querySelector('#myPlane').object3DMap.mesh;
mesh.material.onBeforeComp ile = function (shader) {
shader.fragmentShader = shader.fragmentShader.replace(
'#include <dithering_fragment>',
'gl_FragColor.rgb *= 0.5;'
);
};
object3D всегда доступен, даже если меш ещё не создан.
Для визуальных изменений лучше проверять наличие
object3DMap.mesh.model-loaded для моделей GLTF.traverse удобно для массового изменения
дочерних мешей.object3D предоставляет полную свободу, позволяя сочетать
возможности Three.js с удобной сценографией A-Frame.