Three.js позволяет создавать сложные сцены с несколькими камерами, что открывает возможности для многопользовательских игр, инструментов визуализации и специальных эффектов. Работа с несколькими камерами требует правильной организации рендеринга и управления их параметрами.
В Three.js обычно используются три типа камер: PerspectiveCamera, OrthographicCamera и CubeCamera. Для сплит-экрана чаще всего применяются перспективные камеры.
const camera1 = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera1.position.set(0, 5, 10);
const camera2 = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera2.position.set(10, 5, 0);
camera2.lookAt(0, 0, 0);
Ключевой момент: каждая камера имеет собственное
поле зрения, аспектное соотношение и положение в сцене. Для корректного
отображения на экране необходимо правильно задавать aspect
при изменении размеров окна.
window.addEventListener('resize', () => {
camera1.aspect = window.innerWidth / window.innerHeight;
camera1.updateProjectionMatrix();
camera2.aspect = window.innerWidth / window.innerHeight;
camera2.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
Для отображения нескольких камер на одном экране используется метод рендера с указанием viewport. Это позволяет разделить экран на зоны, каждая из которых отображает сцену с определенной камеры.
function render() {
renderer.setScissorTest(true);
// Левая половина экрана
renderer.setViewport(0, 0, window.innerWidth / 2, window.innerHeight);
renderer.setScissor(0, 0, window.innerWidth / 2, window.innerHeight);
renderer.render(scene, camera1);
// Правая половина экрана
renderer.setViewport(window.innerWidth / 2, 0, window.innerWidth / 2, window.innerHeight);
renderer.setScissor(window.innerWidth / 2, 0, window.innerWidth / 2, window.innerHeight);
renderer.render(scene, camera2);
renderer.setScissorTest(false);
}
Важно: использование setScissor
гарантирует, что каждая камера рендерит только в своей области,
предотвращая наложение изображения другой камеры.
Сплит-экран можно реализовать различными способами:
Пример горизонтального сплита:
// Верхняя половина
renderer.setViewport(0, window.innerHeight / 2, window.innerWidth, window.innerHeight / 2);
renderer.setScissor(0, window.innerHeight / 2, window.innerWidth, window.innerHeight / 2);
renderer.render(scene, camera1);
// Нижняя половина
renderer.setViewport(0, 0, window.innerWidth, window.innerHeight / 2);
renderer.setScissor(0, 0, window.innerWidth, window.innerHeight / 2);
renderer.render(scene, camera2);
Камеры могут быть независимыми или синхронизированными. Для синхронизации положения или вращения удобно использовать общий контроллер, например OrbitControls:
const controls1 = new THREE.OrbitControls(camera1, renderer.domElement);
const controls2 = new THREE.OrbitControls(camera2, renderer.domElement);
function animate() {
requestAnimationFrame(animate);
controls1.update();
controls2.update();
render();
}
Для игровых приложений камеры можно привязать к разным игрокам или объектам сцены, обновляя их позиции внутри цикла анимации.
Каждая камера может иметь свои постобработки, например EffectComposer. Это позволяет на одной сцене отображать различную цветокоррекцию, размытие или эффекты глубины на отдельных участках экрана.
const composer1 = new THREE.EffectComposer(renderer);
const composer2 = new THREE.EffectComposer(renderer);
// Настройка рендер-процессов отдельно для каждой камеры
Многокамерная система в Three.js с правильной организацией viewport и scissor-тестов обеспечивает гибкий сплит-экран, позволяя создавать интерактивные сцены с несколькими точками зрения и сложными визуальными эффектами.