It's quite easy to set up multiple views/displays and there are different ways to achieve this. The Three.js website provides an example of multiple views. If we inspect the page source code, we can see that only one canvas is used. So it's an efficient solution.
Another way to achieve the same effect is to use multiple canvas. Suppose we want to create two independent displays. We will need
- one scene
- two renderers: There will be two canvas and two
div
elements will be needed. - two cameras: Each render has its own camera.
- two controls: We need separate controls as well.
Here is the demo:
HTML File:
1234567891011
<script type="module">
import {main} from "/<path-to-js-file>/demo_multi_divs.js";
main();
</script>
<div id="demo_multi_divs">
<div style="height: 5vh"></div>
<div id="demo_multi_divs_display_1" style="margin:auto;text-align:center;"></div>
<div style="height: 5vh"></div>
<div id="demo_multi_divs_display_2" style="margin:auto;text-align:center;"></div>
</div>
Javascript File:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
import * as THREE from "/three/build/three.module.js";
import { OrbitControls } from "/three/examples/jsm/controls/OrbitControls.js";
function rand(min, max) {
if (max === undefined) {
max = min;
min = 0;
}
return min + (max - min) * Math.random();
}
function randomColor() {
return <code>hsl(${rand(360) | 0}, ${rand(50, 100) | 0}%, 50%)</code>;
}
function createDefaultRender(elementId) {
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth / 4, window.innerHeight / 4 );
document.getElementById(elementId).appendChild(renderer.domElement);
renderer.domElement.style.border = "1px solid orange";
renderer.domElement.style.margin = "auto";
return renderer;
}
function createDefaultCamera() {
const fov = 75;
const aspect = window.innerWidth / window.innerHeight;
const near = 0.1;
const far = 200;
return new THREE.PerspectiveCamera(fov, aspect, near, far);
}
function main() {
const renderer1 = createDefaultRender("demo_multi_divs_display_1");
const camera1 = createDefaultCamera();
camera1.position.z = 30;
const renderer2 = createDefaultRender("demo_multi_divs_display_2");
const camera2 = createDefaultCamera();
camera2.position.z = 30;
// Create an orbit control.
const controls1 = new OrbitControls( camera1, renderer1.domElement );
const controls2 = new OrbitControls( camera2, renderer2.domElement );
// Create the scene
const scene = new THREE.Scene();
scene.background = new THREE.Color('white');
// Create a camera pole
const cameraPole1 = new THREE.Object3D();
const cameraPole2 = new THREE.Object3D();
scene.add(cameraPole1);
scene.add(cameraPole2);
cameraPole1.add(camera1);
cameraPole2.add(camera2);
// Add a light source to the camera
const color = 0xFFFFFF;
const intensity = 1;
const light1 = new THREE.DirectionalLight(color, intensity);
const light2 = new THREE.DirectionalLight(color, intensity);
light1.position.set(0, 0, 0);
light2.position.set(0, 0, 0);
camera1.add(light1);
camera2.add(light2);
// Define the geometry of the displayed boxes.
const boxWidth = 1;
const boxHeight = 1;
const boxDepth = 1;
const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);
function makeInstance(geometry, color) {
const material = new THREE.MeshPhongMaterial({color});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
cube.position.set(rand(-20, 20), rand(-20, 20), rand(-20, 20));
cube.rotation.set(rand(Math.PI), rand(Math.PI), 0);
cube.scale.set(rand(3, 6), rand(3, 6), rand(3, 6));
return cube;
}
// Create a list of cubes
const N = 10;
const cubes = [];
for (var i = 0; i < N; ++i) {
makeInstance(geometry, randomColor());
}
function updateAll(scene, renderer, camera, controls) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
controls.update();
renderer.render(scene, camera);
}
function render(time) {
time *= 0.001;
// Rotate the camera pold. Recall that the camera is attached to the cameral pole and there is a light source
// attached to the camera.
cameraPole1.rotation.y = time * 0.5;
cameraPole2.rotation.y = time * -0.5;
cubes.forEach((cube, ndx) => {
const speed = 1 + ndx * .1;
const rot = time * speed;
cube.rotation.x = rot;
cube.rotation.y = rot;
});
updateAll(scene, renderer1, camera1, controls1);
updateAll(scene, renderer2, camera2, controls2);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
export {
main
}
----- END -----
©2019 - 2022 all rights reserved