Beginning with 3D WebGL (pt. 1) - The Scene
This is part 1 in a series for beginners wanting to get in to using 3D WebGL. If you haven't checked out the other post be sure to have a look:
- pt 1. The Scene
- pt 2. Geometry
- pt 3. Materials
- pt 4. Animation
Before I started working for CodePen I worked for a digital shop that has made some of the most impressive WebGL projects on the web in recent years. For that reason people have mistaken me for being some sort of WebGL wizard when the truth is I have always been pretty uncomfortable with 3D work. Sure I helped build the little pieces within those projects but it was always someone else who put the total scene together.
In all the subjects I studied at University there were only two that I truly sucked at no matter how hard I tried. Introduction to Microelectronic Engineering and Introduction to 3D Modelling. I was just soooo bad at 3D modelling. I think this is why I've been intimidated by 3D work in my web development career.
This trepidation ends now! I am going to get over my aversion to 3D and try and build a proper understanding of this medium. And I figure I may as well blog about it as I go along, so you can understand it with me.
Three.js as a library and API totally makes sense to me. JavaScript I can handle. It has always been the "three deeness" that leaves me scratching my head - thinking in terms of the third dimension, lighting, cameras & projection. So we're going to start this series with taking a closer look at the pieces that come together to make a 3D scene, as well as the Three.js code required to create those pieces.
The Scene
A scene is the 3D space in which you can place objects, cameras and lighting. The space can be as small or large as you need it to be.
Code for a Three.js scene
var scene = new THREE.Scene();
The camera
A (perspective) camera simulates the behaviour of a film camera in real life. The position of the camera and the direction it is facing will determine the parts of your scene that get rendered to the screen. When you set up a camera you need to pass in a vertical field of view (fov), an aspect ratio, a near plane, and a far plane. These 4 values dictate the 3D space (viewing frustum) that can be captured by your camera.
fov: The vertical field of view. This dictates the size of the vertical space your camera's view can reach.
aspect: This is the aspect ratio you use to create the horizontal field of view based off the vertical.
near: This is the nearest plane of view (where the camera's view begins).
far: This is the far plane of view (where the camera's view ends).
Where your objects are within the viewing fustrum will effect how they appear rendered in your screen. Speaking of rendering, you'll need to add a Three.js renderer - a view that contains your camera's "picture".
Code for a Three.js camera and renderer
// add a camera
// THREE.PerspectiveCamera(fov, aspect, near, far)
var camera = new THREE.PerspectiveCamera(
75,
window.innerWidth/window.innerHeight,
0.1,
1000
);
// place the camera at z of 100
camera.position.z = 100;
// add a renderer
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
// add the renderer element to the DOM so it is in our page
document.body.appendChild( renderer.domElement );
Lighting
You can imagine your scene now as a "room" with a camera and absolutely no light. If you were to place an object in the room, you still wouldn't be able to see it! You would need to shine a light on the object to get it to show up in the camera's view.
There are different kinds of lights and they have different effects. For a comprehensive description of each kind of lighting you can check out this really great article but to break it down to their simplest descriptions:
Directional Lights: a large light from far away that shines from one direction (think of the sun).
Ambient Lights: less of a light source and more of a soft color tint for the scene.
Point Lights: think of a lightbulb - shines in every direction & has a limited range.
Spot Lights: just like a spotlight works in real life.
Hemisphere Lights: an ambient (non directional) light coming from the ceiling and floor of the scene.
Code to add Three.js lighting
/* we're creating a cube to put in our scene - don't worry
if you don't follow this part, we'll cover geometry and materials
in future posts */
var geometry = new THREE.BoxGeometry(20, 20, 20);
var material = new THREE.MeshLambertMaterial({color: 0xfd59d7});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
/* we need to add a light so we can see our cube - its almost
as if we're turning on a lightbulb within the room */
var light = new THREE.PointLight(0xFFFF00);
/* position the light so it shines on the cube (x, y, z) */
light.position.set(10, 0, 25);
scene.add(light);
And with these parts, you can construct a basic Three.js scene! I've put this code in a pen and added some dat.gui so you can change the position of the camera, lighting and field of view to get a sense of how they affect the image.
In future articles we'll look at geometry, materials, user input, 3d vector math, shaders, and more! If you have any questions, corrections or any suggestions on what to include as always I love to read your comments below.
Check out part 2: Geometry
Your questions and suggestions give me ideas for what to write about next! So if you have any questions please comment below, send me a tweet @rachsmithtweets, submit to my AMA, or flick me an email at contact at rachsmith dot com.