Метод lookAt является встроенным инструментом в Three.js
для управления ориентацией объектов в 3D-пространстве. Он позволяет
направить объект на заданную точку, автоматически вычисляя необходимый
поворот вокруг осей. Используется преимущественно с объектами типа
Mesh, Camera или любыми объектами,
наследующимися от Object3D.
Синтаксис:
object.lookAt(x, y, z);
или
object.lookAt(vector);
где vector — экземпляр THREE.Vector3.
Ключевой момент: lookAt не перемещает объект. Он
изменяет только ориентацию, поворачивая объект так,
чтобы его локальная ось Z смотрела на указанную точку.
Three.js использует правостороннюю систему координат. Локальная ось Z
объекта считается направлением “вперед”. Метод lookAt
строит матрицу поворота, выравнивая эту ось в направлении целевой точки.
Важно помнить, что ось Y объекта в Three.js ориентирована вверх
(up по умолчанию (0,1,0)), и метод будет
учитывать это при вычислении вращения.
Пример базового использования:
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 0, 0);
const target = new THREE.Vector3(10, 5, -7);
mesh.lookAt(target);
В этом примере объект mesh будет повернут так, чтобы его
“лицо” (ось Z) было направлено на координаты
(10, 5, -7).
Метод lookAt часто применяется для камеры:
const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.set(0, 2, 5);
camera.lookAt(new THREE.Vector3(0, 0, 0));
Здесь камера направлена на центр сцены. Это позволяет легко реализовать сцену с фиксированным фокусом, например, слежение за объектом.
Для динамических сцен lookAt может обновляться в каждом
кадре. Например, при слежении за движущимся объектом:
function animate() {
requestAnimationFrame(animate);
movingSphere.position.x += 0.05;
camera.lookAt(movingSphere.position);
renderer.render(scene, camera);
}
animate();
В этом случае камера будет непрерывно следить за сферой,
перемещающейся по сцене. Аналогично можно использовать
lookAt для любого объекта, который должен “смотреть” на
другой объект в реальном времени.
upСвойство object.up определяет вектор “вверх” для
объекта. По умолчанию (0,1,0). Изменение этого вектора
позволяет создавать наклонные или необычные ориентации:
mesh.up.set(0, 0, 1);
mesh.lookAt(target);
Теперь объект будет выравниваться так, чтобы локальная ось Z смотрела на цель, а ось Z сцены будет восприниматься как “вверх” для объекта.
При использовании lookAt могут возникать эффекты gimbal
lock — потеря одной степени свободы вращения, если цель расположена
точно по вертикали относительно объекта. Для обхода этого используется
комбинация Quaternion и lookAt:
mesh.lookAt(target);
mesh.quaternion.normalize();
Использование кватернионов обеспечивает плавное и корректное вращение без артефактов, особенно при анимациях с поворотами на 360°.
lookAt может использоваться и на объектах типа
THREE.Group. В этом случае все дочерние объекты
группы поворачиваются вместе, сохраняя локальные координаты.
Это удобно для сцен с несколькими элементами, которые должны совместно
ориентироваться на цель:
const group = new THREE.Group();
group.add(mesh1, mesh2);
group.position.set(0,0,0);
group.lookAt(target);
lookAt всегда ориентирует объект по локальной оси
Z. Если требуется использовать другую ось в качестве “лица” объекта,
необходимо предварительно повернуть геометрию.lookAt
в цикле рендеринга, чтобы сохранить синхронизацию с динамическими
объектами.rotation, так как
это может вызвать некорректные повороты.const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 10, 7.5);
scene.add(light);
camera.position.set(10, 5, 10);
function animate() {
requestAnimationFrame(animate);
cube.rotation.y += 0.01;
// Камера следит за кубом
camera.lookAt(cube.position);
renderer.render(scene, camera);
}
animate();
В этом примере камера динамически следит за вращающимся кубом,
демонстрируя комбинацию анимации и использования lookAt для
реального 3D взаимодействия объектов.