For Three.js to render a scene, it needs scene, camera, and renderer. In JavaScript, you have to import Three.js depending on the installation options as mentioned in the previous article.
// main.js
import * as THREE from 'three'
In HTML, to display the rendering result of Three.js, you have to create or designate <canvas>
element to which Three.js renders the scene.
const canvas = document.createElement("canvas");
document.body.appendChild(canvas);
The renderer fetches canvas
as domElement
and options
such as alpha, anti-alias. If you want the app to fill the screen, you can set the size of renderer as window.innerWidth
and window.innerHeight
.
const renderer = new THREE.WebGLRenderer({canvas: canvas, alpha: true, antialias: true});
renderer.setSize( window.innerWidth, window.innerHeight );
Next, camera can be defined as PerspectiveCamera
or OrthographicCamera
. In the example, I’ve chosen a perspective camera. The perspective camera needs field of view, aspect ratio, near and far depth values as arguments.
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(1, -5, 5);
camera.lookAt(new THREE.Vector3(0,0,0));
After generating an empty scene, renderer.render(scene, camera)
renders the scene with the camera.
const scene = new THREE.Scene();
renderer.render(scene, camera);
Furthermore, in order to construct a 3D scene, we also need objects and lights. A 3D object requires geometry, material, and mesh properties to be created. In the below, we define cube geometry and basic material. BoxGeometry(1,1,1)
constructs a cube with a length of 1. MeshBasicMaterial
constructs the material of the object, and does not affect by lighting.
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({color: 0xff0000});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
If we use MeshLambertMaterial
, then you should add a light into the scene.
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshLambertMaterial({color: 0xff0000});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
const light = new THREE.PointLight(0xffffff, 50);
light.position.set(2, -3, 5);
light.lookAt(new THREE.Vector3(0,0,0));
scene.add(light);
If you want to animate the scene, you have to run renderer.render(scene, camera)
iteratively. Similar to canvas animation, it would be better to use requestAnimationFrame()
rather than to use setInterval()
.
function animate () {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
Let’s rotate the cube to see the animation. Insert cube.rotateX(0.02)
inside animate()
function.
function animate () {
requestAnimationFrame(animate);
cube.rotateX(0.02);
renderer.render(scene, camera);
}
animate();
To control the pose of the camera using mouse interaction, you can use an add-on of Three.js. It provides several versatile controls. Particularly, orbit controls allow the camera to move along its orbit around a target.
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
...
const controls = new OrbitControls(camera, canvas);
If you want to enable damping effect of orbit controls, set controls.enableDamping = true
and revise the animate()
function
function animate () {
requestAnimationFrame(animate);
cube.rotateX(0.02);
controls.update();
renderer.render(scene, camera);
}
animate();
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
const canvas = document.createElement("canvas");
document.body.appendChild(canvas);
const renderer = new THREE.WebGLRenderer({canvas: canvas, alpha: true, antialias: true});
renderer.setSize( window.innerWidth, window.innerHeight );
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(1, -5, 5);
camera.lookAt(new THREE.Vector3(0,0,0));
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshLambertMaterial({color: 0xff0000});
const cube = new THREE.Mesh(geometry, material);
const light = new THREE.PointLight(0xffffff, 50);
light.position.set(2, -3, 5);
light.lookAt(new THREE.Vector3(0,0,0));
const scene = new THREE.Scene();
scene.add(cube);
scene.add(light);
const controls = new OrbitControls(camera, canvas);
controls.enableDamping = true;
function animate () {
requestAnimationFrame(animate);
cube.rotateX(0.02);
controls.update();
renderer.render(scene, camera);
}
animate();