Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Learn Three.js
Learn Three.js

Learn Three.js: Programming 3D animations and visualizations for the web with HTML5 and WebGL , Third Edition

eBook
€23.99 €34.99
Paperback
€43.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

Learn Three.js

Creating Your First 3D Scene with Three.js

Over recent years, modern browsers have acquired powerful features that can be accessed directly from JavaScript. You can easily add video and audio with the HTML5 tags and create interactive components through the use of the HTML5 canvas. Together with HTML5, modern browsers also support WebGL. With WebGL, you can directly make use of the processing resources of your graphics card and create high-performance 2D and 3D computer graphics. Programming WebGL directly from JavaScript to create and animate 3D scenes is a very complex, verbose and error-prone process. Three.js is a library that makes this a lot easier. The following list shows some of the things that are very easy to do with Three.js:

  • Creating simple and complex 3D geometries
  • Creating Virtual Reality (VR) and Augmented Reality (AR) scenes
  • Animating and moving objects through a 3D scene
  • Applying textures and materials to your objects
  • Making use of different light sources to illuminate the scene
  • Loading objects from 3D-modeling software
  • Adding advanced postprocessing effects to your 3D scene
  • Working with your own custom shaders
  • Creating point clouds

With a couple of lines of JavaScript, you can create anything, from simple 3D models to photorealistic real-time scenes, as shown in the following screenshot (see it yourself by opening http://www.vill.ee/eye/ in your browser):

In this chapter, we'll directly dive into Three.js and create a couple of examples that show you how Three.js works, and which you can use to play around with. We won't dive into all the technical details yet; that's something you'll learn in the following chapters. In this chapter, we'll cover the following points:

  • The tools required to work with Three.js
  • Downloading the source code and examples used in this book
  • Creating your first Three.js scene
  • Improving the first scene with materials, lights, and animations
  • Introducing a couple of helper libraries for statistics and controlling the scene

We'll start this book with a short introduction to Three.js and then quickly move on to the first examples and code samples. Before we get started, let's quickly look at the most important browsers out there and their support for WebGL. All modern browsers on desktop, as well as on mobile, currently support WebGL. The only browser where you have to take care of is the mobile Opera Mini browser. This browser has the option to render pages through the Opera servers, which often prevents JavaScript from working. Since version 8, however, the default mode of Opera Mini is to use the iOS Safari engine, which does support JavaScript and WebGL. You can still configure this browser, though, to use mini mode, which will render pages through the Opera servers and won't support WebGL in that case.

Basically, Three.js runs on any modern browser with the exception of older versions of IE. So, if you want to use an older version of IE, you've got to take an additional step. For IE 10 and older, there is the IEWebGL plugin, which you can get from https://github.com/iewebgl/iewebgl. This plugin is installed inside IE 10 and older versions and enables WebGL support for those browsers.

So, with WebGL, you can create interactive 3D visualizations that run very well on desktops as well as on mobile devices.

In this book, we'll focus mostly on the WebGL-based renderer provided by Three.js. There is, however, also a CSS 3D-based renderer, which provides an easy API to create CSS 3D-based 3D scenes. A big advantage of using a CSS 3D-based approach is that this standard is supported on all mobile and desktop browsers and allows you to render HTML elements in a 3D space. We'll show how to use the CSS 3D browser in Chapter 7, Points and Sprites.

In this chapter, you'll directly create your first 3D scene and will be able to run this in any of the browsers mentioned previously. We won't introduce too many complex Three.js features yet, but, at the end of this chapter, you'll have created the Three.js scene you can see in the following screenshot:

59 FPS (47-60)

For this first scene, you'll learn about the basics of Three.js and also create your first animation. Before you start your work on this example, in the next couple of sections, we'll first look at the tools you need to easily work with Three.js and how you can download the examples shown in this book.

Requirements for using Three.js

Three.js is a JavaScript library, so all you need to create Three.js WebGL applications is a text editor and one of the supported browsers to render the results. I would like to recommend the following JavaScript editors, which I've used extensively over the last couple of years on various projects:

  • Visual Studio Code: This free editor from Microsoft runs on all major platforms and provides great syntax highlighting and smart completion based on types, function definitions, and imported libraries. It provides a very clean interface and is great for working on JavaScript projects. It can be downloaded from here: https://code.visualstudio.com/.
  • WebStorm: This editor from the JetBrains guys has great support for editing JavaScript. It supports code completion, automatic deployment, and JavaScript debugging directly from the editor. Besides this, WebStorm has excellent GitHub (and other version control systems) support. You can download a trial edition from http://www.jetbrains.com/webstorm/.
  • Notepad++: Notepad++ is a general-purpose editor that supports code highlighting for a wide range of programming languages. It can easily layout and format JavaScript. Note that Notepad++ is only for Windows. You can download Notepad++ from http://notepad-plus-plus.org/.
  • Sublime Text Editor: Sublime is a great editor that offers very good support for editing JavaScript. Besides this, it provides many very helpful selections (such as multiple-line select) and edit options, which, once you get used to them, provide a really good JavaScript-editing environment. Sublime can also be tested for free and can be downloaded from http://www.sublimetext.com/.

Even if you don't use any of these editors, there are a lot of editors available, open source and commercial, that you can use to edit JavaScript and create your Three.js projects, since all you need is the ability to edit text. An interesting project you might want to look at is http://c9.io. This is a cloud-based JavaScript editor that can be connected to a GitHub account. This way, you can directly access all the source code and examples from this book and experiment with them.

Besides these text-based editors that you can use to edit and experiment with the sources from this book, Three.js currently also provides an online editor itself.

With this editor, which you can find at http://threejs.org/editor/, you can create Three.js scenes using a graphical approach.

I mentioned that most modern web browsers support WebGL and can be used to run Three.js examples. I usually run my code in Chrome. The reason is that most often, Chrome has the best support and performance for WebGL and it has a really great JavaScript debugger. With this debugger, which is shown in the following screenshot, you can quickly pinpoint problems, for instance, using breakpoints and console output. This is exemplified in the following screenshot. Throughout this book, I'll give you pointers on debugger usage and other debugging tips and tricks:

60 FPS (0-60)

That's enough by way of an introduction for now; let's get the source code and start with the first scene.

Getting the source code

All the code for this book can be accessed from GitHub (https://github.com/). GitHub is an online Git-based repository that you can use to store, access, and version source code. There are a couple of ways that you can get the sources for yourself:

  • Clone the Git repository
  • Download and extract the archive

In the following two paragraphs, we'll explore these options in a bit more detail.

Using Git to clone the repository

Git is an open source distributed version control system that I used to create and version all the examples in this book. For this, I used GitHub, a free, online Git repository. You can browse this repository from this link: https://github.com/josdirksen/learning-threejs-third.

To get all the examples, you can clone this repository using the git command-line tool. To do this, you first need to download a Git client for your operating system. For most modern operating systems, a client can be downloaded from http://git-scm.com. After installing Git, you can use this to get a clone of this book's repository. Open a command prompt and go to the directory where you want to download the sources. In that directory, run the following command:

    git clone https://github.com/josdirksen/learning-threejs-third

This will start downloading all the examples, as shown in the following screenshot:

The learning-threejs-third directory will now contain all the examples that are used throughout this book.

Downloading and extracting the archive

If you don't want to use Git to download the sources directly from GitHub, you can also download an archive. Open https://github.com/josdirksen/learning-threejs-third in a browser and click on the Clone or download button on the right-hand side. This will give you the option to download all the sources in a single ZIP file:

Extract this to a directory of your choice, and you'll have all the examples available.

Downloading the example code: You can also download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books you have purchased. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files emailed directly to you.

Testing the examples

Now that you've downloaded or cloned the source code, let's do a quick check to see whether everything is working and make you familiar with the directory structure. The code and examples are organized per chapter. There are two different ways of viewing examples. You can either open the extracted or cloned folder in a browser directly and look at and run a specific example, or you can install a local web server. This first approach will work for most of the basic examples, but when we start loading external resources, such as models or texture images, just opening the HTML file isn't enough. In this case, we need a local web server to make sure the external resources are loaded correctly. In the following section, we explain a couple of different ways you can set up a simple local web server for testing. If you can't set up a local web server but use Chrome or Firefox, we also provide an explanation on how to disable certain security features so that you can even test without a local web server.

Setting up a local web server is very easy depending on what you've already got installed. In here, we list a couple of examples on how to do this. There are many different ways of doing this, depending on what you've already got installed on your system.

Python-based web servers should work on most Unix/macOS systems

Most Unix/Linux/macOS systems already have Python installed. On those systems, you can very easily start a local web server:

     > python -m SimpleHTTPServer
     Serving HTTP on 0.0.0.0 port 8000 ...

Do this in the directory where you checked out / downloaded the source code.

Npm-based web server if you've worked with Node.js

If you've already done some work with Node.js, there is good chance you've got npm installed. With npm, you have two simple options to set up a quick local web server for testing. The first option uses the http-server module, as follows:

     > npm install -g http-server
     > http-server
    Starting up http-server, serving ./ on port: 8080
    Hit CTRL-C to stop the server

Alternatively, you can also use the simple-http-server option, as follows:

    > npm install -g simple-http-server
    > nserver
    simple-http-server Now Serving: /Users/jos/git/Physijs at http://localhost:8000/

A disadvantage of this second approach, however, is that it doesn't automatically show directory listings when browsing the sources, whereas the first approach does.

Portable version Mongoose for macOS and/or Windows

If you haven't got Python or npm installed, there is a simple, portable web server, named Mongoose, that you can use. First, download the binaries for your specific platform from https://code.google.com/p/mongoose/downloads/list. If you are using Windows, copy it to the directory containing the examples and double-click on the executable to start a web browser serving the directory it is started in.

For other operating systems, you must also copy the executable to the target directory, but instead of double-clicking on the executable, you have to launch it from the command line:

In both cases, a local web server will be started on port 8080. The following screenshot shows the output when you open a browser to a locally running Mongoose server:

All the examples are in the src folder. By just clicking on a chapter in this folder, we can show and access all the examples for that specific chapter. If we discuss an example in this book, we'll refer to the specific name and folder so that you can directly test and play around with the code.

Running from the filesystem by disabling security exceptions in Firefox and Chrome

If you use Chrome to run the examples, there is a way to disable some security settings so that you can use Chrome to view the examples without requiring a web server. Note that you shouldn't do this on a browser you use on the internet since it can leave you open to all kinds of malicious code. To do this, you have to start Chrome in the following way:

  • For Windows, you call the following:
 chrome.exe --disable-web-security  
  • On Linux, do the following:
 google-chrome --disable-web-security
  • And on macOS, you disable the settings by starting Chrome like this:
 open -a "Google Chrome" --args --disable-web-security  

When you start Chrome this way, you can access all the examples directly from the local filesystem.

For Firefox users, we need to take a couple of different steps. Open Firefox and, in the URL bar, type about:config. This is what you'll see:

Warning window

On this screen, click on the I'll be careful, I promise! button. This will show you all the available properties you can use to fine-tune Firefox. In the search box on this screen, type in security.fileuri.strict_origin_policy and change its value to false, just as we did in the following screenshot:

At this point, you can also use Firefox to directly run the examples provided in this book. Now that you've either got a web server installed, or disabled the necessary security settings, it is time to start creating our first Three.js scene.

Creating the HTML skeleton

The first thing we need to do is create an empty skeleton page that we can use as the base for all our examples, as follows:

<!DOCTYPE html>
<html>

<head>
<title>Example 01.01 - Basic skeleton</title>
<meta charset="UTF-8" />
<script type="text/javascript" charset="UTF-8" src="../../libs/three/three.js"></script>
<script type="text/javascript" charset="UTF-8" src="../../libs/three/controls/TrackballControls.js"></script>
<script type="text/javascript" src="./js/01-01.js"></script>
<link rel="stylesheet" href="../../css/default.css">
</head>

<body>
<!-- Div which will hold the Output -->
<div id="webgl-output"></div>

<!-- Javascript code that runs our Three.js examples -->
<script type="text/javascript">
(function () {
// contains the code for the example
init();
})();
</script>
</body>

</html>

As you can see from this listing, the skeleton is a very simple HTML page, with only a couple of elements. In the <head> element, we load the external JavaScript libraries that we'll use for the examples. For all the examples, we'll at least need to load the Three.js library, three.js. And we also load a controller, TrackballControls.js, which allows you to use your mouse to rotate and pan around the scenes. The last JavaScript file we load in the <head> section is the file that contains the example code. For this first example, it is called 01-01.js. Finally, in the <head> element, we load a CSS file, which contains some simple styles (for example, the styles in the default.css file remove any scrollbars when we create a full-page Three.js scene). In the <body> element of this page, you can see a single <div> element. When we write our Three.js code, we'll point to the output of the Three.js renderer to that element. At the bottom of this page, you can see a bit of JavaScript. In this function, which is called when the page is loaded, we call init(). The init() function is defined in the 01-01.js file and will set up the Three.js scene. For this example, the init() function in the 01-01.js file is very simple and just prints out the Version of Three.js we're using:

function init() {
console.log("Using Three.js version: " + THREE.REVISION);
}

If we open this file in our browser and look at the console output, you should see something like this:

In the <head> element we included the sources for Three.js. Three.js comes in two Versions:

  • three.min.js: This is the library you'd normally use when deploying Three.js sites on the internet. This is a mini version of Three.js, created using UglifyJS, which is a quarter of the size of the normal Three.js library. All the examples and code used in this book are based on Three.js r95, which was released in July 2018.
  • three.js: This is the normal Three.js library. We use this library in our examples since it makes debugging much easier when you can read and understand the Three.js source code.

In the next section, you'll learn how to add the first couple of 3D objects and render them to the <div> element we defined in our HTML skeleton.

Rendering and viewing a 3D object

In this step, you'll create your first scene and add a couple of objects and a camera. Our first example will contain the following objects:

 

Object

Description

Plane

This is a two-dimensional rectangle that serves as our ground area. In the second screenshot of this chapter, this is rendered as the gray rectangle in the middle of the scene.

Cube

This is a three-dimensional cube, which we'll render in red.

Sphere

This is a three-dimensional sphere, which we'll render in blue.

Camera

The camera determines what you'll see in the output.

Axes

These are the x, y, and z axes. This is a helpful debugging tool to see where the objects are rendered in 3D space. The x axis is colored red, the y axis is colored green, and the z axis is colored blue.

 

I'll first show you how this looks in code (the source with comments can be found in chapter-01/js/01-02.js), and then I'll explain what's happening:

function init() {
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000));
renderer.setSize(window.innerWidth, window.innerHeight);

var axes = new THREE.AxesHelper(20);
scene.add(axes);

var planeGeometry = new THREE.PlaneGeometry(60, 20);
var planeMaterial = new THREE.MeshBasicMaterial({
color: 0xAAAAAA
});

var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -0.5 * Math.PI;
plane.position.set(15, 0, 0);
scene.add(plane);

// create a cube
var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
var cubeMaterial = new THREE.MeshBasicMaterial({
color: 0xFF0000,
wireframe: true
});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.set(-4, 3, 0);
scene.add(cube);

// create a sphere
var sphereGeometry = new THREE.SphereGeometry(4, 20, 20);
var sphereMaterial = new THREE.MeshBasicMaterial({
color: 0x7777FF,
wireframe: true
});
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.set(20, 4, 2);
scene.add(sphere);

// position and point the camera to the center of the scene
camera.position.set(-30, 40, 30);
camera.lookAt(scene.position);

// add the output of the renderer to the html element
document.getElementById("webgl-output").appendChild(renderer.domElement);

// render the scene
renderer.render(scene, camera);
}

If we open this example in the browser, we see something that resembles what we're aiming at (see the screenshot at the beginning of this chapter), but it is still a long way off, as follows:

Before we start making this more beautiful, I'll first walk you through the code one step at a time so that you understand what the code does:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000));
renderer.setSize(window.innerWidth, window.innerHeight);

At the top of the example, we create a scene, a camera, and a renderer. The scene object is a container that is used to store and keep track of all the objects we want to render and all the lights we want to use. Without a THREE.Scene object, Three.js isn't able to render anything. More information on the THREE.Scene object can be found in Chapter 2, The Basic Components that Make Up a Three.js Application. The sphere and the cube we want to render will be added to the scene later on in the example.

In this first fragment, we also create a camera object. The camera object defines what we'll see when we render a scene. In Chapter 2, The Basic Components That Make Up a Three.js Application, you learn more about the arguments you can pass into the camera object. Next, we define renderer. The renderer object is responsible for calculating what the scene object will look like in the browser based on what the camera is looking at. We create a WebGLRenderer that uses your graphics card to render the scene in this example.

If you look through the source code and the documentation of Three.js (which you can find at http://threejs.org/), you'll notice that there are different renderers available besides the WebGL-based one. There is a canvas-based renderer, a CSS-based renderer, and even an SVG-based one. Even though they work and can render simple scenes, I wouldn't recommend using them. They're not actively developed anymore, very CPU-intensive, and lack features such as good material support and shadows. 

We set the background color of renderer to black (new THREE.Color(0X000000)) with the setClearColor function and tell renderer how large the scene needs to be rendered using the setSize function. By passing in the window.innerWidth and window.innerHeight, we use all the screen space available.

So far, we've got a basic empty scene, a renderer, and a camera. There is, however, nothing yet to render. The following code adds the lines showing the axis and the plane:

var axes = new THREE.AxesHelper(20);
scene.add(axes);

var planeGeometry = new THREE.PlaneGeometry(60, 20);
var planeMaterial = new THREE.MeshBasicMaterial({
color: 0xAAAAAA
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -0.5 * Math.PI;
plane.position.set(15, 0, 0);
scene.add(plane);

As you can see, we create an axes object (the passed-in value determines the size of the lines representing the x, y, and axes) and use the scene.add function to add these axes to our scene. Next, we create the plane. This is done in two steps. First, we define what the plane looks like using the new THREE.PlaneGeometry(60,20) code. In this case, it has a width of 60 and a height of 20. We also need to tell Three.js what this plane looks like (for example, its color and its transparency). In Three.js, we do this by creating a material object. For this first example, we'll create a basic material (THREE.MeshBasicMaterial) with the color 0xAAAAAA. Next, we combine these two into a Mesh object and assign that to the plane variable. Before we add plane to the scene, we need to put it in the correct position; we do this by first rotating it 90 degrees around the x axis, and next, set its position in the scene using the position property. If you're already interested in the details of this, look at the 06-mesh-properties.html example from the code folder of Chapter 2, The Basic Components That Make Up a Three.js Application, which shows and explains rotation and positioning. All we then need to do is add plane to scene, just like we did with axes.

The cube and sphere objects are added in the same manner, but with the wireframe property set to true, which tells Three.js to show us a wireframe and not a solid object. Now, let's move on to the final part of this example:

camera.position.set(-30, 40, 30);
camera.lookAt(scene.position);

document.getElementById("webgl-output").appendChild(renderer.domElement);
renderer.render(scene, camera);

At this point, all the elements we want to render are added to the scene at the correct positions. We've already mentioned that the camera defines what will be rendered. In this piece of code, we position the camera using the set function to hover above our scene (we can also use position.x, position.y, and position.z to set the individual parts of the camera's position). To make sure the camera is looking at our objects, we use the lookAt function to point it at the center of our scene, which is located at position (0, 0, 0) by default. All that is left to do is append the output from the renderer to the <div> element of our HTML skeleton. We use standard JavaScript to select the correct output element and append it to our div element with the appendChild function. Finally, we tell renderer to render scene using the camera object provided.

In the next couple of sections, we'll make this scene more interesting by adding lights, shadows, more materials, and even animations.

Adding materials, lights, and shadows

Adding new materials and lights in Three.js is very simple and is implemented in pretty much the same way as we explained in the previous section. We start by adding a light source to the scene (for the complete source, look at js/03-03.js), as follows:

  var spotLight = new THREE.SpotLight(0xFFFFFF);
spotLight.position.set(-40, 40, -15);
spotLight.castShadow = true;
spotLight.shadow.mapSize = new THREE.Vector2(1024, 1024);
spotLight.shadow.camera.far = 130;
spotLight.shadow.camera.near = 40;

THREE.SpotLight illuminates our scene from its position (spotLight.position.set( -40, 60, -10 )). We tell it that we want it to cast a shadow by setting the castShadow property to true. In the code, you can see that we also set some additional properties on the light: shadow.mapSize, shadow.camera.far, and shadow.camera.near. Without going into too much detail, these properties define how sharp and detailed our rendered shadow will appear. We'll explain these properties in more detail in Chapter 3Working with the Different Light Sources Available in Three.js. If we render the scene this time, however, you won't see any difference from the previous one. The reason is that different materials respond differently to light. The basic material we used in the previous example (THREE.MeshBasicMaterial) doesn't do anything with the light sources in the scene. They just render the object in the specified color. So, we have to change the materials for plane, sphere, and cube to the following:

var planeGeometry = new THREE.PlaneGeometry(60,20); 
var planeMaterial = new THREE.MeshLambertMaterial({color: 
0xffffff}); var plane = new THREE.Mesh(planeGeometry, planeMaterial); ... var cubeGeometry = new THREE.BoxGeometry(4,4,4); var cubeMaterial = new THREE.MeshLambertMaterial({color:
0xff0000}); var cube = new THREE.Mesh(cubeGeometry, cubeMaterial); ... var sphereGeometry = new THREE.SphereGeometry(4,20,20); var sphereMaterial = new THREE.MeshLambertMaterial({color:
0x7777ff}); var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);

In this piece of code, we changed the materials for our objects to MeshLambertMaterial. This material, MeshPhysicalMaterial and MeshStandardMaterial (and the deprecated  MeshPhongMaterial) are the materials Three.js provides that take light sources into account when rendered.

The result, shown in the following screenshot, however, still isn't what we're looking for:

We're getting there, and the cube and sphere are looking a lot better. What is still missing, though, are the shadows. Rendering shadows takes a lot of computing power and, for that reason, shadows are disabled by default in Three.js. Enabling them, though, is very easy. For shadows, we have to change the source in a couple of places, as follows:

renderer.setClearColor(new THREE.Color(0x000000)); 
renderer.setSize(window.innerWidth, window.innerHeight); 
renderer.shadowMap.Enabled = true; 

The first change we need to make is to tell renderer that we want shadows. You do this by setting the shadowMap.Enabled property to true. If you look at the result from this change, you won't notice anything different yet. That is because we need to explicitly define which objects cast shadows and which objects receive shadows. In our example, we want the sphere and the cube to cast shadows on the ground plane. You do this by setting the corresponding properties on those objects:

plane.receiveShadow = true; 
... 
cube.castShadow = true; 
... 
sphere.castShadow = true; 

Now, there is just one more thing to do to get the shadows. We need to define which light sources in our scene will cast shadows. Not all the lights can cast shadows, and you'll learn more about that in Chapter 3Working with the Different Light Sources Available in Three.js, but THREE.SpotLight, which we used in this example. We only need to set the correct property, as shown in the following line of code, and the shadows will finally be rendered:

spotLight.castShadow = true; 

And, with this, we get a scene complete with shadows from our light source, as follows:

If you look at the code in 01-03.js, you can see that we also create a scene with different objects. You can use this for yourself by removing the comments for the createXXX functions. Once you do that, and remove the objects we added previously, you can see how shadows work with a slightly more complex scene. How the result from that scene appears can be seen in the following screenshot.

The last feature that we'll add to this first scene is some simple animation. In Chapter 9, Animations and Moving the Camera, you'll learn more advanced animation options.

Expanding your first scene with animations

If we want to animate the scene, the first thing that we need to do is find some way to re-render the scene at a specific interval. Before HTML5 and the related JavaScript APIs came along, the way to do this was using the setInterval(function,interval) function. With setInterval, we could specify a function that, for instance, would be called every 100 milliseconds. The problem with this function is that it doesn't take into account what is happening in the browser. If you were browsing another tab, this function would still be fired every couple of milliseconds. Besides that, setInterval isn't synchronized with the redrawing of the screen. This can lead to higher CPU usage, flickering, and generally poor performance.

Introducing requestAnimationFrame

Modern browsers luckily have a solution for that with the requestAnimationFrame function. With requestAnimationFrame, you can specify a function that is called at an interval. You, however, don't define this interval. This interval is defined by the browser. You do any drawing you need to do in the supplied function, and the browser will make sure it is painted as smoothly and efficiently as possible. Using this is really simple (the complete source can be found in the 04-04.js file); you just create a function that handles the rendering:

function renderScene() { 
  requestAnimationFrame(renderScene); 
  renderer.render(scene, camera); 
} 

In this renderScene function, we call requestAnimationFrame again, to keep the animation going. The only thing we need to change in the code is that instead of calling renderer.render after we've created the complete scene, we call the renderScene function once to initiate the animation:

... 
document.getElementById("webgl-output") 
  .appendChild(renderer.domElement); 
renderScene(); 

If you run this, you won't see any changes yet compared to the previous example because we haven't animated anything yet. Before we add the animation, though, we introduce a small helper library that gives us information about the frame rate the animation is running at. This library, from the same author as Three.js, renders a small graph that shows us information about the rate at which the scene is rendered.

To add these statistics, we first need to include the library in the <head> element of the HTML, as follows:

<script type="text/javascript" src="../../libs/util/Stats.js"></script>

The only thing left to do is initialize the statistics and add them to the page:

function initStats(type) {

var panelType = (typeof type !== 'undefined' && type) && (!isNaN(type)) ? parseInt(type) : 0;
var stats = new Stats();

stats.showPanel(panelType); // 0: fps, 1: ms, 2: mb, 3+: custom
document.body.appendChild(stats.dom);

return stats;
}

This function initializes the statistics and, based on the passed in type variable renders the frames per second, the time it took to render the frame, or the amount of allocated memory. At the beginning of our init() function, we'll call this function, and we've got stats enabled, as follows:

function init(){ 
 
  var stats = initStats(); 
  ... 
} 
Since this is something we want to add to each example, we don't add the initStats function to the sources of our examples, but this function, together with other useful helper functions, are added to the util.js file.

This file is included in the header of the HTML pages as follows:

<script type="text/javascript" src="../js/util.js"></script>

The only thing left to do now is to tell the stats object when we're in a new rendering cycle. We do this by adding a call to the stats.update function in our renderScene function, as follows:

function renderScene() { 
  stats.update(); 
  ... 
  requestAnimationFrame(renderScene); 
  renderer.render(scene, camera); 
} 

If you run the code with these additions, you'll see the statistics in the upper left-hand corner, as shown in the following screenshot:

60 FPS (49-60)

Animating the cube

With requestAnimationFrame and the statistics configured, we've got a place to put our animation code. In this section, we'll expand the renderScene function with code that will rotate our red cube around all of its axes. Let's start by showing you the code:

function renderScene() { 
  ... 
  cube.rotation.x += 0.02; 
  cube.rotation.y += 0.02; 
  cube.rotation.z += 0.02; 
  ... 
  requestAnimationFrame(renderScene); 
  renderer.render(scene, camera); 
} 

That looks simple, right? What we do is that we increase the rotation property of each of the axes by 0.02 every time the renderScene function is called, which shows up as a cube smoothly rotating around all of its axes. Bouncing the blue ball isn't much harder.

Bouncing the ball

To bounce the ball, we once again add a couple of lines of code to our renderScene function, as follows:

  var step=0; 
  function renderScene() { 
    ... 
    step+=0.04; 
    sphere.position.x = 20 + 10*(Math.cos(step)); 
    sphere.position.y = 2 + 10*Math.abs(Math.sin(step)); 
    ... 
    requestAnimationFrame(renderScene); 
    renderer.render(scene, camera); 
  } 

With the cube, we changed the rotation property; for the sphere, we're going to change its position property in the scene. We want the sphere to bounce from one point in the scene to another with a nice, smooth curve. This is shown in the following diagram:

For this, we need to change its position on the x axis and its position on the y axis. The Math.cos and Math.sin functions help us create a smooth trajectory using the step variable. I won't go into the details of how this works here. For now, all you need to know is that step+=0.04 defines the speed of the bouncing sphere. In Chapter 8, Creating and Loading Advanced Meshes and Geometries, we'll look in much more detail at how these functions can be used for animation, and we'll explain everything. Here's how the ball looks in the middle of a bounce:

60 FPS (1-60)

Before wrapping up this chapter, we must add one more element to our basic scene. When working with 3D scenes, animations, colors, and properties like that, it often requires a bit of experimenting to get the correct color or speed. It would be very easy if you could just have a simple GUI that allows you to change these kinds of properties on the fly. Luckily, there is!

Using dat.GUI to make experimenting easier

A couple of employees from Google created a library called dat.GUI (you can find the documentation online at http://code.google.com/p/dat-gui/), which allows you to very easily create a simple user interface component that can change variables in your code. In the last part of this chapter, we'll use dat.GUI to add a user interface to our example that allows us to do the following:

  • Control the speed of the bouncing ball
  • Control the rotation of the cube

Just like we had to do for the statistics, we first add this library to the <head> element of our HTML page, as follows:

<script type="text/javascript" src="../../libs/util/dat.gui.js"></script>

The next thing we need to configure is a JavaScript object that will hold the properties we want to change using dat.GUI. In the main part of our JavaScript code, we add the following JavaScript object, as follows:

var controls = new function() { 
  this.rotationSpeed = 0.02; 
  this.bouncingSpeed = 0.03; 
} 

In this JavaScript object, we define two properties: this.rotationSpeed and this.bouncingSpeed, and their default values. Next, we pass this object into a new dat.GUI object and define the range for these two properties, as follows:

var gui = new dat.GUI(); 
gui.add(controls, 'rotationSpeed', 0, 0.5); 
gui.add(controls, 'bouncingSpeed', 0, 0.5); 

The rotationSpeed and bouncingSpeed properties are both set to a range of 0 to 0.5. All we need to do now is make sure that in our renderScene loop, we reference these two properties directly so that when we make changes through the dat.GUI user interface, it immediately affects the rotation and speed of bounce of our objects, as follows:

function renderScene() { 
  ... 
  cube.rotation.x += controls.rotationSpeed; 
  cube.rotation.y += controls.rotationSpeed; 
  cube.rotation.z += controls.rotationSpeed; 
  step += controls.bouncingSpeed; 
  sphere.position.x = 20 +(10 * (Math.cos(step))); 
  sphere.position.y = 2 +(10 * Math.abs(Math.sin(step))); 
  ... 
} 

Now, when you run this example (05-control-gui.html), you'll see a simple user interface that you can use to control the bouncing and rotation speeds. A screenshot of the bouncing ball and the rotating cube is shown here:

60 FPS (51-60)

Remember that in the HTML skeleton we showed at the beginning of this chapter, we include the TrackballControls.js JavaScript file. With this file, we can control the camera used in the scene, as we'll explain in more detail in Chapter 9Animations and Moving the Camera. For now, we'll just enable this control by adding a couple lines of JavaScript. The first thing we need to do is initialize the trackball controls. Since these controls respond to Document Object Model (DOM) element events, we need to make sure we add the following lines after this call: 

document.getElementById("webgl-output").appendChild(renderer.domElement);
// add the two lines below
var trackballControls = initTrackballControls(camera, renderer);
var clock = new THREE.Clock();

The initTrackballControls function is defined in utils.js, which we mentioned earlier. In later chapters, we'll go into more detail regarding how this works. Now, we also need to update the render function as follows:

function render() {
trackballControls.update(clock.getDelta());
...
}

At this point, we're done. If you open the 05-control-gui.html example again, you can move your mouse and left-click to rotate the camera. If you press S when moving your mouse, you can zoom in and out, and, if you press D, you can pan around the scene. This, for instance, allows you to view the scene from a different side:

57 FPS (0-60)

All the examples from now on will use these controls by default, so you can easily look at different parts of the rendered scene.

If you've looked at the examples in your browser, you might have noticed that when you change the size of your browser, the scene doesn't automatically scale. In the next section, we'll add this as a final feature for this chapter.

Automatically resize the output when the browser size changes

Changing the camera when the browser is resized can be done pretty simply. The first thing we need to do is register an event listener as follows:

window.addEventListener('resize', onResize, false); 

Now, whenever the browser window is resized, the onResize function, which we'll specify next, is called. In this onResize function, we need to update the camera and renderer, as follows:

function onResize() { 
  camera.aspect = window.innerWidth / window.innerHeight; 
  camera.updateProjectionMatrix(); 
  renderer.setSize(window.innerWidth, window.innerHeight); 
} 

For the camera, we need to update the aspect property, which holds the aspect ratio of the screen, and for the renderer, we need to change its size. The final step is to move the variable definitions for camera, renderer, and scene outside of the init() function so that we can access them from different functions (such as the onResize function), as follows:

var camera; 
var scene; 
var renderer; 
 
function init() { 
  ... 
  scene = new THREE.Scene(); 
  camera = new THREE.PerspectiveCamera(45, window.innerWidth / 
window.innerHeight, 0.1, 1000); renderer = new THREE.WebGLRenderer(); ... }

Summary

That's it for the first chapter. In this chapter, we showed you how to set up your development environment, how to get the code, and how to get started with the examples provided with this book. You further learned that to render a scene with Three.js, you first have to create a THREE.Scene object, add a camera, a light, and the objects that you want to render. We also showed you how you can expand this basic scene by adding shadows and animations. Lastly, we added a couple of helper libraries. We used dat.GUI, which allows you to quickly create control user interfaces, and we added stats.js, which provided feedback on the frame rate and other metrics at which your scene is rendered.

In the next chapter, we'll expand on the example we created here. You'll learn more about the most important building blocks that you can use in Three.js.

Left arrow icon Right arrow icon

Key benefits

  • Enhance your 3D graphics with light sources, shadows, advanced materials, and textures
  • Load models from external sources, and visualize and animate them directly from JavaScript
  • Create your own custom WebGL shader and explore the postprocessing feature of Three.js

Description

WebGL makes it possible to create 3D graphics in the browser without having to use plugins such as Flash and Java. Programming WebGL, however, is difficult and complex. With Three.js, it is possible to create stunning 3D graphics in an intuitive manner using JavaScript, without having to learn WebGL. With this book, you’ll learn how to create and animate beautiful looking 3D scenes directly in your browser-utilizing the full potential of WebGL and modern browsers. It starts with the basic concepts and building blocks used in Three.js. From there on, it will expand on these subjects using extensive examples and code samples. You will learn to create, or load, from externally created models, realistic looking 3D objects using materials and textures. You’ll find out how to easily control the camera using the Three.js built-in in camera controls, which will enable you to fly or walk around the 3D scene you created. You will then use the HTML5 video and canvas elements as a material for your 3D objects and to animate your models. Finally, you will learn to use morph and skeleton-based animation, and even how to add physics, such as gravity and collision detection, to your scene. After reading this book, you’ll know everything that is required to create 3D animated graphics using Three.js.

Who is this book for?

The ideal target audience for this book would be JavaScript developers who who want to learn how to use the Three.js library

What you will learn

  • Work with the different types of materials in Three.js and see how they interact with your 3D objects and the rest of the environment
  • Implement the different camera controls provided by Three.js to effortlessly navigate around your 3D scene
  • Work with vertices directly to create snow, rain, and galaxy-like effects
  • Import and animate models from external formats, such as OBJ, STL, and COLLADA
  • Create and run animations using morph targets and bones animations
  • Explore advanced textures on materials to create realistic looking 3D objects by using bump maps, normal maps, specular maps, and light maps
  • Interact directly with WebGL by creating custom vertex and fragment shaders
Estimated delivery fee Deliver to Netherlands

Premium delivery 7 - 10 business days

€17.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Aug 31, 2018
Length: 528 pages
Edition : 3rd
Language : English
ISBN-13 : 9781788833288
Category :
Languages :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to Netherlands

Premium delivery 7 - 10 business days

€17.95
(Includes tracking information)

Product Details

Publication date : Aug 31, 2018
Length: 528 pages
Edition : 3rd
Language : English
ISBN-13 : 9781788833288
Category :
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
€189.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts
€264.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 185.97
Learn Three.js
€43.99
Real-Time 3D Graphics with WebGL 2
€37.99
Hands-on Three.js 3D Web Visualisations
€103.99
Total 185.97 Stars icon
Banner background image

Table of Contents

13 Chapters
Creating Your First 3D Scene with Three.js Chevron down icon Chevron up icon
The Basic Components that Make Up a Three.js Application Chevron down icon Chevron up icon
Working with Light Sources in Three.js Chevron down icon Chevron up icon
Working with Three.js Materials Chevron down icon Chevron up icon
Learning to Work with Geometries Chevron down icon Chevron up icon
Advanced Geometries and Binary Operations Chevron down icon Chevron up icon
Points and Sprites Chevron down icon Chevron up icon
Creating and Loading Advanced Meshes and Geometries Chevron down icon Chevron up icon
Animations and Moving the Camera Chevron down icon Chevron up icon
Loading and Working with Textures Chevron down icon Chevron up icon
Render Postprocessing Chevron down icon Chevron up icon
Adding Physics and Sounds to Your Scene Chevron down icon Chevron up icon
Other Books You May Enjoy Chevron down icon Chevron up icon

Customer reviews

Rating distribution
Full star icon Full star icon Full star icon Empty star icon Empty star icon 3
(4 Ratings)
5 star 25%
4 star 0%
3 star 50%
2 star 0%
1 star 25%
Michael Stather Jun 05, 2021
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Super ;)
Amazon Verified review Amazon
Benjamin Kieper Aug 29, 2023
Full star icon Full star icon Full star icon Empty star icon Empty star icon 3
Es wird gerade soviel gezeigt, dass man ein 3D Modell laden kann. Es wäre aber genug Platz für LOD oder Layers gewesen...
Amazon Verified review Amazon
Rax Jan 30, 2020
Full star icon Full star icon Full star icon Empty star icon Empty star icon 3
El libro tiene muy buena información, pero requerí investigar por mi cuenta para completar un proyecto que tenia.
Amazon Verified review Amazon
Janco Verduin Feb 13, 2024
Full star icon Empty star icon Empty star icon Empty star icon Empty star icon 1
First i was sent the wrong version and then they claimed it was my fault. After several emails I finally got the pdf I thought I had bought, buy their service is repulsive.
Feefo Verified review Feefo
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact [email protected] with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at [email protected] using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on [email protected] with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on [email protected] within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on [email protected] who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on [email protected] within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela