Page 1: The THREE.js library

CS559 Spring 2023 Sample Solution

On this page, we’ll just deal with the mechanics of using the THREE.js library, and some of the issues specific to using the library in the way we’ve been programming in class.

Box 1: Check that things work

Just to make sure that things work, here is a simple scene made with the THREE library ( 06-01-01.html and 06-01-01.js). You should see a spinning green cube.

06-01-01

If you don’t see the picture (a spinning cube), something is wrong.

The THREE.js library (or, rather, all of the parts of it that we will need for class) is included in the libs/CS559-Three folder of the workbook.

The main parts of THREE are packaged as a JavaScript module. We can load it with:

import * as THREE from "../libs/CS559-Three/build/three.module.js";

This creates a symbol (kind of like a variable) that allows us to access everything built in to THREE. Here, we’ve decided to call it THREE , but we could pick a different variable name if we wanted to. In most of the examples it is called T to save typing. You will see:

import * as T from "../libs/CS559-Three/build/three.module.js";

Some pieces of THREE (that we’ll see later in this workbook, such as the OrbitControl) are not part of the THREE module and, therefore, need to be loaded separately.

In prior versions of THREE, the library was not a module. This was a problem in earlier editions of this course.

THREE also provides type information so we can use the TypeScript type checker (see Typed JavaScript and CS559).

Box 2: THREE and HTML

THREE actually draws into a Canvas element. It doesn’t use the Canvas 2D API - it uses WebGL, a different API that we will learn about later.

Normally, THREE creates the Canvas element for us. The example above includes the following code:

16
17
18
let renderer = new T.WebGLRenderer();
renderer.setSize(200, 200); // was (window.innerWidth, window.innerHeight );
document.getElementById("div1").appendChild(renderer.domElement);

This creates a WebGLRenderer object, which has a property that is an HTMLCanvasElement (where the drawing will happen). The call to setSize sets the size of the Canvas (in HTML pixels). The last line finds a container element called three1 (it’s a <div>) that we put into the HTML where we want to put the newly created canvas, and inserts the Canvas into it.

If we had a Canvas already, we could tell THREE to use it instead. So here is a Canvas in HTML:

06-01-02

And the code looks like:

let canvas = /** @type {HTMLCanvasElement} */ (
  document.getElementById("canvas1")
);

let renderer = new T.WebGLRenderer({ canvas: canvas });

Basically, we have to find the Canvas and pass it to the constructor of the renderer.

You can view the full code in 06-01-02.js ( 06-01-02.html).

Parameter Passing

There is one subtle thing here that is a common paradigm in THREE programming (in fact, in JavaScript programming in general). Note how we pass the parameters to the WebGLRenderer constructor as an object {"canvas":canvas}. Since JavaScript doesn’t support keyword arguments (like Python), we need some mechanism for specifying the parameters we want, without having to include the parameters that should take default values. So instead of passing a list of parameters, we pass an object that contains all of the parameters we want to control.

For example, suppose we have a function like:

function foo(a = 1, b = 2, c = 3, d = 4) {
  // do something with a, b, c and d
}

and we want to call it with the default parameters for everything except d. In this case, we’re stuck. If we wanted d=7, we would need to write foo(1,2,3,7). If this were Python, we could write foo(d=7), but it’s not. So instead we define the function to take one object that holds the parameters:

function foo(object) {
  let a = "a" in object ? object.a : 1;
  let b = "b" in object ? object.b : 2;
  let c = "c" in object ? object.c : 3;
  let d = "d" in object ? object.d : 4;
  // do something with a, b, c and d
}

so we can write foo({d:7}) (remember JavaScript quoting rules, we don’t need quotes around d). This is a little bit of a hassle when we create the function, but very convenient when we use it (especially for functions with lots of arguments). Fortunately, the author of THREE wrote a lot of his code this way.

Summary: Using THREE

So now, you can hopefully create a THREE program with the THREE library. Now let’s try to figure out how to use THREE on Page  2  (Elements of 3D Graphics Programming).

Next: Elements of 3D Graphics Programming

There are no points associated with this page.