Как сделать два canvas для одной сцены в three.js?
Собственно сабж. Есть одна сцена, которую нужно показывать в двух разных местах dom. Рендер привязан к событию change orbitcontrols, т.е. рендерит при повороте камеры вокруг объекта. Выводится все в указанный WebGLRenderer канвас.
Точно такая же сцена требуется в другом месте, и не хотелось бы дублировать код и создавать ту же сцену для другого канвас.
Какие есть способы дублировать всё на два канвас? Первое что пришло в голову простое дублирование канвас drawImage, а рендерить сцену посредством слушателя канвас mousemove при зажатой ЛКМ.
Но может есть какой то встроенный функционал в threejs или более правильные и производительные варианты?
Дополнительно:
А не пробовал просто два рендерера создавать и в них передавать те же данные?
Ответы:
Точно такая же сцена требуется в другом месте, и не хотелось бы дублировать код и создавать ту же сцену для другого канвас
Сцену дублировать не обязательно. WebGLRenderer не умеет рендерить в несколько мест одновременно, но можно иметь одну сцену и много рендереров, каждый из которых будет рендерить ее в свой канвас. Это работает.
Если посмотреть с другой стороны, то возможно, что вам не нужны два канваса. Это может звучать странно, но тем не менее. Пользователь же все равно видит только один экран информации. Можно иметь один канвас на весь экран, и в нем рендерить сцены в какие-то его участки. Там есть такой функционал у рендерера, называется "ножницы" (scissor). Его можно использовать как раз для таких задач. Есть хороший пример в документации.
Но если делать именно 100% дублирование, то оба этих варианта будут не самыми толковыми с точки зрения производительности. В лоб скопировать уже готовое содержимое канваса в другой через drawImage должно быть проще, чем рендерить всю сцену еще раз. Поэтому решение, которое пришло вам в голову - очень даже ничего в текущем контексте. Хотя и выглядит топорно.
- да доки видел там канвас на весь экран, тут ситуация такая что нужны два отдельных канваса на разных страницах onepage сервиса. Гугл выдает зачастую тоже самое что в доках, поэтому пока идея такая: сделать два орбитконтролс для двух канвас и дублировать основной канвас в слушателе change вторичного канвас при помощи drawImage.
Просто думал может я что то упустил и есть способ транслировать рендер в два канвас из коробки или не задокументированным способом, но видимо нет.
Спасибо за ответ!
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для создания двух canvas для одной сцены в three.js необходимо использовать два отдельных экземпляра класса THREE.WebGLRenderer и два отдельных экземпляра класса THREE.Scene.
Пример кода на JavaScript с использованием three.js:
// Создаем сцену var scene1 = new THREE.Scene(); var scene2 = new THREE.Scene(); // Создаем два рендерера var renderer1 = new THREE.WebGLRenderer(); var renderer2 = new THREE.WebGLRenderer(); // Устанавливаем размеры канваса для каждого рендерера renderer1.setSize( window.innerWidth / 2, window.innerHeight ); renderer2.setSize( window.innerWidth / 2, window.innerHeight ); // Добавляем канвас элементы на страницу document.body.appendChild( renderer1.domElement ); document.body.appendChild( renderer2.domElement ); // Создаем камеру и добавляем ее к сцене var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); scene1.add( camera ); scene2.add( camera ); // Создаем объекты и добавляем их к сценам var geometry = new THREE.BoxGeometry(); var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); var cube = new THREE.Mesh( geometry, material ); scene1.add( cube ); var geometry2 = new THREE.SphereGeometry(); var material2 = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); var sphere = new THREE.Mesh( geometry2, material2 ); scene2.add( sphere ); // Создаем функцию анимации function animate() { requestAnimationFrame( animate ); // Вращение объектов в сцене 1 cube.rotation.x += 0.01; cube.rotation.y += 0.01; // Вращение объектов в сцене 2 sphere.rotation.x += 0.01; sphere.rotation.y += 0.01; // Рендеринг сцены 1 renderer1.render( scene1, camera ); // Рендеринг сцены 2 renderer2.render( scene2, camera ); } animate();
В данном примере создаются две сцены (scene1 и scene2), два рендерера (renderer1 и renderer2) и два канваса для отображения сцен. Каждая сцена содержит свои объекты, которые могут быть анимированы независимо друг от друга. Анимация происходит в функции animate(), где происходит вращение объектов в каждой сцене.
Таким образом, можно создать два canvas для одной сцены в three.js, используя отдельные рендереры и сцены для каждого из них.