Three.js is a JavaScript library that renders graphics on the web using WebGL.
In Three.js, a camera represents the viewpoint or perspective through which we observe and capture the 3D scene. It determines what is visible and how the scene is rendered on the screen.
The camera class is abstract. We can't use it directly but can inherit from it to access common properties and methods. There are mainly two classes that inherit from the camera class:
The PerspectiveCamera is like our eyes, making 3D scenes look more realistic. It's the most commonly used camera type because it creates a natural sense of depth and makes the experience more immersive.
Few camera classes also inherit the functionality of PerspectiveCamera
class:
ArrayCamera
CubeCamera
StereoCamera
This class allows us to create an array of PerspectiveCameras, each representing a different viewpoint or perspective.
Click here to see a live demonstration of ArrayCamera
It captures six 2D images from the inside of a cube, useful for creating realistic reflections or environment mapping in 3D scenes.
Click here to see a live demonstration of CubeCamera
It employs two PerspectiveCameras, one for the left eye and another for the right eye, to render separate views. This technique replicates human binocular vision.
Click here to see a live demonstration of StereoCamera
Here is the syntax for creating PerspectiveCamera in three.js:
const camera = new THREE.PerspectiveCamera(fov, aspect_ratio, near, far);
fov
: It refers to the "Field of Vision." It determines the visible part of the scene on the display. A typical range for FOV in games is between 60 to 90 degrees, with 50 often used as a good default value.
aspect_ration
: It is the ratio between the width and height of the rendering area. It ensures proper display proportions. A common approach is to set the aspect ratio as window.innerWidth / window.innerHeight
, which adapts to the current size of the browser window.
near
: It specifies the minimum distance from the camera where objects are rendered. A value of 1
can be a good default choice.
far
: It determines how far an object can be seen. A value of 1000
can be a good default choice.
We can follow the instructions below to set up a PerspectiveCamera.
Firstly, we will import the three.js library in a variable three
in the script tag.
<script type="importmap">
{
"imports": {
"three":"https://unpkg.com/three/build/three.module.js"
}
}
</script>
We can initialize the scene as shown below.
//scene
const scene = new THREE.Scene();
We can now use scene.add
to add elements to our scene after initializing them. We will start with the camera.
We can initialize the camera with the default values and then set up its position and then simply add it to the scene.
// initializing the PerspectiveCamera
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// Set up the position of the camera
camera.position.set(0, 0, 15);
// simple add it to the scene
scene.add(camera);
We can create a WebGL renderer using the provided <canvas>
element. The renderer's size is set to match the window's inner dimensions.
//Renderer
const canvas = document.getElementById("c");
const renderer = new THREE.WebGLRenderer({canvas:canvas});
renderer.setSize(window.innerWidth, window.innerHeight);
We can add two shapes by defining their geometry differently and adding colors to distinguish between them. We can also position them accordingly by using .position
property so they can be far from each other and we can see them apart. Then simply add them to the scene.
//Shape 1 (Cube)
const geometry1 = new THREE.BoxGeometry(5, 5, 5);
const material1 = new THREE.MeshPhongMaterial();
material1.color = new THREE.Color(0x0ffff0);
const cube = new THREE.Mesh(geometry1, material1);
cube.position.y = 5;
scene.add(cube);
//Shape 2 (Sphere)
const geometry2 = new THREE.SphereGeometry(3, 32, 32);
const material2 = new THREE.MeshPhongMaterial();
material2.color = new THREE.Color(0xff0000);
const sphere = new THREE.Mesh(geometry2, material2);
sphere.position.z = -15;
sphere.position.y = -10;
scene.add(sphere);
Placing a light source is a crucial part of setting up the scene. It illuminates the space and makes the objects visible. Firstly, we will initialize the kind of light we are using. By default, light
is placed at coordinates: (0,0,0). We can position the light according to the camera's position by using .set()
method.
//Light
const light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.set(0, 0, 5);
scene.add(light);
If we are creating a scene with moving objects, we need to create a function that updates to render the animation we require. To do that, we will need to use the window.requestAnimationFrame
method. For a more detailed explanation, you can visit this Answer.
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
We get the following output by putting together the code explained above. We have one cube and one sphere of the same size but fifteen points apart from each other on the z-axis. We are using a perspective camera for the scene, in which the camera identifies both objects as natural eyes and can see the distant object much smaller than the near one.
It captures a scene with parallel projection, resulting in objects appearing the same size regardless of their distance from the camera. It is commonly used for 2D and isometric rendering and precise object measurements in 3D scenes.
Here is the syntax for creating OrthographicCamera in three.js:
const camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far)
All the parameters, left, right, top, bottom, near, far
are just integers values defining the border of the box. Any object outside this box, will not be rendered on the camera.
The code to set up the scene for the OrthographicCamera is almost the same as PerspectiveCamera. Still, the minor change we have to make is to initialize the camera as OrthographicCamera, as shown in the code below.
// Initializing the OrthographicCamera instead of PerspectiveCamera
const camera = new THREE.OrthographicCamera(window.innerWidth / -10, window.innerWidth / 10, window.innerHeight / 10, window.innerHeight / -10, 0.1, 1000);
// Set up the position of the camera
camera.position.set(0, 0, 15);
// simple add it to the scene
scene.add(camera);
After making the above change in the code, we still have both cube and a sphere of the same size but fifteen points apart from each other on the z-axis. While this time, we are using the orthographic camera for the scene, in which both the objects look the same size no matter how far they are from each other.
Free Resources