Three.js Essentials

4.8 (4 reviews total)
By Jos Dirksen
    Advance your knowledge in tech with a Packt subscription

  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Get Up and Running with Three.js

About this book

Create beautiful visualizations and 3D scenes using Three.js with this practical, example-rich book. Learn all the core concepts of Three.js, and whether you are targeting mobile devices or desktop browsers, you will gain the necessary skills to build a 3D application and improve web performance.

From setting up a development environment and creating your first Three.js scene, you will quickly dive into more complex scene-making. Discover a variety of possible scenes from how to make a rotating planet with data overlay to mini games. Through these examples, you will be shown an array of skills from using materials, controls, and lighting to creating particle systems and geometries from scratch.

By the end of this book, you'll be able to effectively and confidently create 3D scenes using different lights and materials, create visualizations using particle systems, animate web pages, and incorporate Blender in your 3D workflow.

Publication date:
July 2014
Publisher
Packt
Pages
198
ISBN
9781783980864

 

Chapter 1. Get Up and Running with Three.js

Three.js is an open source JavaScript library that allows you to create and render 3D scenes directly in your browser. Three.js provides an extensive API for this with a large set of functions. The online documentation for Three.js, however, is very sparse and doesn't provide information on how to create complex visualizations. In this book, you'll learn the essential parts of Three.js by creating a number of extensive examples so that after reading this book, you'll be able to create these kind of complex graphics yourself.

Before we dive into the examples that will help you learn the essentials of Three.js, we first have to set up an environment that you can use to experiment and play around with. Besides setting up this environment, we'll also introduce a couple of concepts around which Three.js is built and show some techniques that you can use if you run into problems. The following topics will be discussed in this chapter:

  • What is Three.js, and what are its requirements?

  • Getting access to the source of the examples discussed in this book

  • Setting up a local environment to experiment with the examples

  • Creating a minimal Three.js scene

  • Extending the scene with additional helper libraries for stats, control, and progress

Let's get started with a quick introduction to Three.js.

 

Introducing Three.js


Three.js is an open source JavaScript library that's been around since 2010 and allows you to easily create good-looking 3D scenes directly inside your browser. For rendering, Three.js uses WebGL (http://www.khronos.org/webgl/) if a browser supports it, and it can fall back to an HTML5 canvas or an SVG approach if WebGL isn't supported.

Creating 3D scenes using WebGL directly (or using a canvas) is very hard. Three.js provides an easy-to-use API to create and manipulate 3D objects and scenes without having to know too much about WebGL or complex math formulas. The following screenshot shows a Three.js-based game that even runs on mobile browsers (http://helloracer.com/racer-s/):

A lot of information about Three.js can be found online at the main Three.js site, http://threejs.org. For an extensive reference guide, you can also look at Learning Three.js: The JavaScript 3D Library for WebGL, Jos Dirksen, Packt Publishing.

In the next section, we'll look at the requirements for Three.js to work.

 

Looking at the requirements for Three.js


Three.js is a 100 percent JavaScript library and hasn't got any dependencies to other libraries, so it can run completely in a standalone manner. To get the most out of Three.js, however, you need a browser that supports the WebGL standard. Luckily though, most modern browsers on desktop and mobile currently support this standard. The following table provides an overview of the supported desktop browsers:

Browser

Description

Internet Explorer

Supports WebGL from version 11. For older versions, you can use the IEWebGL plugin that adds support for WebGL to IE 9 and IE 10.

Mozilla Firefox

WebGL is supported from version 4.

Google Chrome

Supports WebGL from version 10.

Safari

Supports WebGL from version 5.1 and above installed on Mac OS X Mountain Lion, Lion, Snow Leopard, and Maverick.

You might need to explicitly enable WebGL in Safari by navigating to Preferences | Advanced, and checking the Show Develop Menu In Menu Bar option. From the Develop menu, you can now enable WebGL through Develop | Enable WebGL.

Opera

Supports WebGL from version 12.0. You still might need to enable this though. Type opera:config in the address bar. Once there, set the value for WebGL and Enable Hardware Acceleration to 1. After this, restart the browser and WebGL will be enabled.

As you can see, almost all modern browsers support WebGL. Support and especially performance on mobile devices, however, is very diverse. The following list shows the browsers that support WebGL and thus Three.js on mobile devices:

  • Mozilla Firefox for Android

  • Google Chrome for Android (you might need to turn it on explicitly)

  • Opera Mobile

  • Blackberry Browser

Note

Note that performance is dependent on how old your device is and the OS you're running. It might even be the case that your graphics card might be blacklisted (http://www.khronos.org/webgl/wiki/BlacklistsAndWhitelists).

Generally speaking, support on mobile Android devices, especially the modern ones, is pretty good. The following screenshot, for instance, shows how one of the examples from this chapter runs on Firefox for Android on a Samsung Galaxy S3.

Note

Note that as iOS doesn't support WebGL (yet), most of the examples from this book won't run on iOS devices because we will use the WebGL renderer provided by Three.js. Three.js also provides an HTML5 canvas and an SVG renderer that do work on iOS but with rather bad performance. A subset of Three.js's functionalities is provided by the CSS3D renderer, which is explained in Chapter 6, Combining HTML and Three.js with CSS3DRenderer, and which runs really well on mobile devices.

 

Setting up a local development environment


The easiest and fastest way to learn Three.js is by playing around with the examples in this book. In this section, we'll have a quick look at how you can get the source code for this book and set up a local web server to easily test and extend the examples.

Getting the source code

There are two different ways in which you can get the source code for this chapter. You can download them directly from the Packt website at http://www.packtpub.com/support, or you can get the code directly from the GitHub repository. For the first approach, point your browser to the specified URL, download the source code, and extract the .zip file into a directory of your choice.

When you want to get the source code directly from GitHub, first make sure you've got Git installed. A good manual on how to install Git for various operating systems can be found online at http://git-scm.com/book/en/Getting-Started-Installing-Git. After you've installed Git, all you have to do is run the following command from the command line:

git clone https://github.com/josdirksen/essential-threejs

This will download all the source code to the directory you're currently in and show an output that looks something like the following code:

Cloning into 'essential-threejs'...
remote: Reusing existing pack: 8, done.
remote: Counting objects: 36, done.
remote: Compressing objects: 100% (21/21), done.
remote: Total 44 (delta 6), reused 0 (delta 0)
Unpacking objects: 100% (44/44), done.
Checking connectivity... done

Now, you'll have a directory where all the source code can be found as shown in the following screenshot:

You could open the files directly in your browser, but for the complex examples in the following chapters, where resources are loaded asynchronously, this approach won't work. To make sure all the examples work, the best thing to do is set up a local web server.

Setting up a local web server

Setting up a local web server is fairly straightforward. In this section, we'll explore the following three different approaches:

  1. A Python-based approach for those who have Python installed.

  2. If you're a Node.js developer or have played around with it, you can use the npm command.

  3. If the previous two approaches don't work for you, you can always install Mongoose, which has a portable version for Mac and Windows.

Let's start by looking at the Python-based approach.

Using Python to run a web server

The easiest way to check whether you've got Python installed is by just typing python on the command line. If you see something like the following output, you've got Python installed, and you can use it to run a simple web server:

> python
Python 2.7.3 (default, Apr 10 2013, 05:09:49)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

All you need to do to run a simple Python-based web server is type the following code on the command line:

> python -m SimpleHTTPServer

The output will be as shown in the following snippet:

Serving HTTP on 0.0.0.0 port 8000...

This will start a web server on port 8000, which allows you to access all the files from the directory where you've run this command.

Using the npm command from Node.js to run a web server

Alternatively, if you haven't got Python installed, you can check whether the npm package manager from the Node.js distribution is available by just typing the following command on the command line:

> npm

If the output is as shown in the following snippet, then you can use the npm-based approach:

Usage: npm <command>
...

In this approach, you can run a web server that serves the files from the directory you're in, using the following command:

> npm install -g http-server

After installing the web server, you can start it using the following command:

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

If both the scenarios discussed so far fail, you can also opt to download a portable web server directly.

Running a portable version of Mongoose

You can download Mongoose, a portable web server, from https://code.google.com/p/mongoose/downloads/list. In Windows, you can just copy the downloaded executable to the folder where you've put the source code files and double-click on the executable to launch the web server. For other platforms as well, copy the file to the directory that contains the source code files. However, you can't run the executable directly; you must start it from the command line. Once started, your web server will be up and running on port 8080.

Note

There is a final alternative if you're not able to install a local web server. You can open the files directly from the browser (or drag-and-drop them in the browser window). For a lot of examples, this will work directly; however, once textures or other features that require the loading of external resources are required, this approach will stop working because of browser security settings. It is possible to change this security policy so that the examples that use those features also work. A good explanation on how to do this is shown in the Three.js website at https://github.com/mrdoob/three.js/wiki/How-to-run-things-locally.

 

Creating a minimal Three.js web application


At this point, you'll have the source code and a locally running web server. Now, let's look at the basics of Three.js to prepare you for the examples in the following chapters. In this section, we'll introduce you to a basic Three.js scene and the basic building blocks.

Creating a scene to contain all the objects

Let's start with a minimal Three.js scene where we'll show you the following:

  • How to include the correct libraries

  • How to create a THREE.Scene object

  • How to add a THREE.Camera object

  • How to set up a render loop

The source code that the following example refers to is the 01.01-basic-scene.html file. The first thing that we need to do is include the Three.js JavaScript library. This is described in the following code:

<head>
    <script src="../libs/three.js"></script>
</head>

Here, we include the three.js library from the libs folder. This library also comes in a minified version (the three.min.js library), which you can also use and which downloads faster. In our examples, we use the normal one as it makes debugging inside the included Three.js file much easier.

Now, we can add the script tag to the HTML page where we will add our Three.js code. This is described in the following code:

<script>
    // code
</script>

Tip

Downloading the example code

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

Now, let's look at what we need for JavaScript to set up a minimal Three.js web application. The first thing we do inside the script tag is set up a couple of global variables, which we'll explain later. This setup is described in the following code:

// global variables
var renderer;
var scene;
var camera;

Next, we'll look at the init() function that we'll use to initialize the Three.js library once the complete document is loaded. This is described in the following code:

function init() {
    // Three.js initialization code
}

window.onload = init;

With the window.onload function, we tell the browser to call the init() function when the document is loaded. The init() function itself looks like as described in the following code:

function init() {
    scene = new THREE.Scene();

    renderer = new THREE.WebGLRenderer();
    renderer.setClearColor(0x000000, 1.0);
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMapEnabled = true;

    camera = new THREE.PerspectiveCamera(
        45, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.x = 15;
    camera.position.y = 16;
    camera.position.z = 13;
    camera.lookAt(scene.position);

    document.body.appendChild(renderer.domElement);
    render();
}

In the previous fragment of code, we created three basic Three.js objects. First, we created a THREE.Scene object. This object is the container that will hold all the objects we want to render. Next, we created a THREE.WebGLRenderer object. This is the Three.js object that we'll use to render the created THREE.Scene object. Finally, the THREE.PerspectiveCamera object determines what we see. The last call of the init() function is a call to the render() function, which is shown in the following code:

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

In this function, you can see that we use the renderer.render() function to visualize the scene using the camera. In this function, we also use the requestAnimationFrame function to set up a render loop. With the requestAnimationFrame function, we tell the browser to determine when it thinks it is best to call the supplied function (the render function in this case). This way, we can offload the graphical rendering of the scene from the normal JavaScript thread; this provides a much smoother experience and better performance.

As you can probably guess, when we open this example (the 01.01-basic-scene.html file) in the browser, the result is still just a black screen. This is because we don't have any objects and any light in the scene yet. This is seen in the following screenshot:

Even though this is just a black scene, this is the minimal Three.js skeleton you can create.

In the next section, we'll make the scene a bit more interesting by adding a ground plane, a cube, and a light.

Adding a mesh created from geometry

Now that we've got our basic scene set up, we'll add the elements to be rendered. In this section, we'll create the scene shown in the following screenshot (the 01.02-simple-mesh.html file):

In the previous screenshot, you can see a simple cube that is rendered on top of a square floor. In the following couple of code fragments, we'll show you how to do this. The first thing we do is add the cube. This is described in the following code:

var cubeGeometry = new THREE.CubeGeometry(6, 4, 6);
var cubeMaterial = new THREE.MeshLambertMaterial({
  color: "red"
});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.castShadow = true;
scene.add(cube);

Now, the first thing we need to do is create the shape and the geometry of the cube. We do this by creating a new THREE.CubeGeometry object where we specify the width, the height, and the depth of the cube. Now that we have the shape, we must also specify a material. This material is used to determine how an object will react to the light sources in the scene. For instance, you can use it to determine its color, reflectivity, whether it's transparent, and much more. In this example, we will create a THREE.MeshLambertMaterial object and set the cube's color to red.

We'll discuss materials in more detail in the next chapter. For now, it's enough to know that a material requires a light source to be present in the scene to determine the color it should show. Now, we need to combine these two components; we do this by creating a THREE.Mesh object, where we provide the geometry and the material as arguments. This THREE.Mesh object is then added to the scene as shown in the previous code fragment.

For the floor plane, we do pretty much the same. Consider the following code:

var planeGeometry = new THREE.PlaneGeometry(20, 20);
var planeMaterial = new THREE.MeshLambertMaterial({
  color: 0xcccccc
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.receiveShadow = true;

plane.rotation.x = -0.5 * Math.PI;
plane.position.y = -2;

scene.add(plane);

What is different here is that we set two additional properties of the create THREE.Mesh object. We set its position in the scene and we set its rotation. The rotation is needed because normally a THREE.PlaneGeometry object is oriented vertically, and as we want to have a horizontal plane, we need to rotate it by 90 degrees (which is 0.5*Pi in radians). As you can see in the previous code, we also set its position. If we don't do this, our ground will cut through half of the cube as the center of the cube is at the position 0, 0, 0 (because we didn't specify it explicitly). The height of the cube is 4, so if we offset the position of the ground by 2, the cube will fit in completely.

Now all that is left to do is to add the light and tell Three.js that we want to see shadows. This is described in the following code:

var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(10, 20, 20);
spotLight.castShadow = true;
scene.add(spotLight);

For this scene, we've created a THREE.SpotLight object that works like a spot on the ceiling or a flashlight. We use the position property to determine where the light should be added and then we add the light to the scene. To enable shadows, we must tell Three.js which objects cast a shadow and which objects should receive a shadow. For this example, it's only useful to show shadows on the ground plane, so we set the plane.receiveShadow object to true to enable shadow rendering on this plane. Now, we just need to set the castShadow object to true on the cube and the light, and we're almost done. Finally, we need to explicitly enable shadow rendering on the renderer. This is done by setting the renderer.shadowMapEnabled object to true. With all this code in place, you get the result you've seen in the screenshot at the beginning of this section.

Before we move on to the next section, we'd like to go one step deeper into two important concepts of Three.js (or modeling in general): vertices and faces.

What are vertices?

In the later chapters of this book, we'll sometimes mention vertices, so it's good to understand what we're talking about in that case. A vertex (plural, vertices) is a single point with an x, y, and z coordinate. When we create a geometry, we're actually creating a number of vertices that together define the shape of the object. If we show the vertices for the cube we created earlier, you will get something like the following screenshot (the 01.03-vertices.html file):

Here, each vertex is shown as a small green sphere. So, when we create a THREE.CubeGeometry object, we actually create eight vertices.

Vertices themselves don't determine the shape of an object. This shape is defined by how the vertices are connected to one another. This concept is called faces.

Combining vertices into faces

A face in Three.js consists of three vertices that together fill out an area. This area is called a face. The easiest way to understand this is by looking at the following screenshot (the 01.04-faces.html file):

Here, you can see that each side of the cube is divided into two faces, and the corners of each face are defined by a vertex.

Now that you've seen the basic components of a scene and know about faces and vertices, we'll add some helper elements to the scene to best prepare you for the more complex examples in the following chapters.

 

Enhancing the basic scene


You can easily experiment with the previous examples by changing the code and refreshing your browser. In this section, we'll introduce two additional components that will make experimenting easier and allow you to keep an eye on the performance of your 3D web application.

Adding easy controls with the dat.GUI library

The first thing that we do is add the dat.GUI library (https://code.google.com/p/dat-gui/) to our basic scene. Even though this library isn't part of Three.js, we can use it to easily add a simple UI element that can be used to control some properties of your scene. For instance, in the following screenshot (the 01.05-controls.html file), you can use the menu on the top right-hand side of the window to control a number of properties of the scene:

Adding a control element to our scene is very simple and only requires a couple of lines of code. First, of course, we need to include the JavaScript dat.GUI library. This is described in the following line of code:

<script src="../libs/dat.gui.min.js"></script>

Next, what we need to do is create a JavaScript object, which you do counter intuitively in JavaScript by calling the new function(), which contains the values we want to change using the dat.GUI library. This is described in the following code:

control = new function() {
  this.rotationSpeed = 0.005;
  this.opacity = 0.6;
  this.color = cubeMaterial.color.getHex();
};
addControlGui(control);

The addControl function creates the menu you see on the top right-hand side of the window. Consider the following code:

function addControlGui(controlObject) {
  var gui = new dat.GUI();
  gui.add(controlObject, 'rotationSpeed', -0.01, 0.01);
  gui.add(controlObject, 'opacity', 0.1, 1);
  gui.addColor(controlObject, 'color');
}

Now, whenever we use the UI to change one of the elements, the value in the supplied control object also changes. In the render loop that we created, we can update the corresponding values to reflect the changes in the objects on the screen. This is described in the following code:

function render() {
   ...
  scene.getObjectByName('cube').material.opacity = control.opacity;

  scene.getObjectByName('cube').material.color = new THREE.Color(control.color);

  renderer.render(scene, camera);
  requestAnimationFrame(render);
}

The more complex your scene becomes, the longer it will take to render and update, which might adversely affect the frame rate. To keep track of this, we'll add a simple counter that shows the current frame rate.

Add a statistics element to show the frame rate

For statistics, we use an external library called stats.js, which happens to be created by the author of Three.js. You can get this library from https://github.com/mrdoob/stats.js. Adding a statistics element with this library is fairly straightforward. First, of course, you have to include the corresponding JavaScript library, which is described in the following line of code:

<script src="../libs/stats.min.js"></script>

Next, we need to configure what kind of statistics we want to show and where to show them. This is described in the following code:

function addStatsObject() {
    stats = new Stats();
    stats.setMode(0);
    stats.domElement.style.position = 'absolute';
    stats.domElement.style.left = '0px';
    stats.domElement.style.top = '0px';
    document.body.appendChild( stats.domElement );
}

Stats.js supports two modes. Mode 0, which we will use here, shows the frames per second (FPS). If we set the mode to 1, we will see the number of milliseconds needed to render the frame. In this function, we also position the stats element at the top left-hand side of the window. Now, all we need to do is call the update() function on the stats object whenever we render a new frame. So, logically, we add this to the render() function. This is described in the following code:

function render() {
  ...
  stats.update();
  ...
}

The same scene with a statistics element looks like as shown in the following screenshot (the 01.06-statistics.html file):

For the last subject in this chapter, we'll give you two tips that will make it easier for you to experiment and play around with the examples.

 

Debugging the examples in this book


While creating JavaScript applications, it's important to understand what happens when your application runs in the browser. In the past, we used to use pop-up alerts for this, but luckily, modern browsers (especially Firefox and Chrome) come with good development tools. In this section, we'll quickly show two approaches that you can use to get a better understanding of what happens inside your code when you run the application in a browser. First, we'll look at how to log in to the browser's console log, and after that, we'll quickly show how you can use breakpoints (in Chrome, for this example) to see and explore the current state of your web application.

Using console logging for debugging

Logging from JavaScript used to be hard, but with modern browsers, there is finally a general way of logging from JavaScript. Just by adding the following line of code to your JavaScript code, you can log a statement:

console.log('Logging something to the browsers console log');

Let's add a couple of log statements to the init() function that we saw earlier. We'll log a simple text message, but we'll also log the cube mesh we added. To do this, we just add the following two lines of code at the end of the init() function:

console.log('Log statement from the init function');
console.log(cube);

In Chrome, the result looks like the following screenshot. You can open the console from the menu through View | Developer | JavaScript Console or by accessing the settings and then going to Tools | JavaScript Console. In Firefox, you can find the console in View | Firebug.

In the preceding screenshot, you can see the string we logged with the first log statement. What's more interesting though is the console.log(cube) output. With this log statement, all the properties from the object are logged. This way, we can quickly check the value of specific properties and explore referenced objects; we can even change them directly from here. An important aspect to keep in mind when using logging in this way is performance. When you do a lot of logging in your web application, its performance will go down. So keep in mind that you remove the logging when you move your code to production.

This is a very easy way to get extra information during runtime. If you, however, want to add some logging to the render loop, the output may be a bit overwhelming. This function will be called approximately 60 times a second, so you can imagine the amount of output you'll get. There is a very easy way to solve this by using a JavaScript debugger. In the following section, I will show an example using the debugger from Chrome, but each modern browser has a very capable debugger.

Looking at objects with breakpoints in Chrome

When you use a debugger, you can easily access all the values of the JavaScript objects you're working with. If you run into issues that you can't easily solve by just adding log statements, using a debugger is probably a good choice.

In the following screenshot, you can see the Chrome debugger in action:

Here, we clicked on the Sources tab and opened the file that contained the JavaScript code. In this file, all you have to do is click on the line number where you want to add a breakpoint. When the code runs to that point, even if it is called from the requestAnimationFrame object, the execution will stop and you can then browse through all the variables and objects that are available. This works great whenever you run into some changed behavior.

 

Summary


That was that for the first introductory chapter. In this chapter, we explained a number of different subjects. Now, we'll summarize the most important ones.

Three.js is an open source JavaScript library that can run in all modern browsers without requiring any plugins, and for older IE browsers, there is a plugin available that enables WebGL support. For mobile browsers, it's a bit different. The performance of WebGL on these platforms depends on the combination of device, OS, and browser. If you want to run the examples on a mobile device, your best bet is to go for a modern Android device and use Chrome or Firefox as the browser. If you use iOS, you're out of luck, as iOS doesn't support WebGL yet. You can, however, still use the CSS3D renderer (see Chapter 6, Combining HTML and Three.js with CSS3DRenderer), which runs really well on iOS but does have a more limited API.

If you create your first Three.js application, you can run it in a number of different ways. The best way, though, is to set up a local web server, which is very easy to do. If you can't run a local web server, there is always the option to disable some of the security policies in your browser.

To understand how Three.js works, you need to understand the basic concepts of Three.js. The first thing you do in Three.js is create a THREE.Scene object. This object serves as a container in which you can place the other Three.js objects, such as meshes and lights. A THREE.Mesh object represents a 3D object and consists of a geometry and a material. The geometry defines the shape of an object, and the material defines what it will look like.

In this chapter, we also introduced a couple of external libraries that make working with Three.js easier. You can use the dat.GUI library to easily add a simple UI element to control specific properties in your scene. To keep track of performance, we introduced the Stats.js library.

Once you try to get your scene up and running, you might run into some unexpected behavior. There are different ways to determine what is going on. You can, for instance, use the console.log function, or set a breakpoint in the developers section of your favorite browser.

In the next chapter, we'll show you how to create a 3D world globe and use that example to explain camera control, textures, integration with HTML5 canvas, and a number of other essential parts of Three.js.

About the Author

  • Jos Dirksen

    Jos Dirksen has worked as a software developer and architect for more than a decade. He has a lot of experience in a large range of technologies, ranging from backend technologies, such as Java and Scala, to frontend development using HTML5, CSS, and JavaScript. Besides working with these technologies, Jos also regularly speaks at conferences and likes to write about new and interesting technologies on his blog. He also likes to experiment with new technologies and see how they can best be used to create beautiful data visualizations. He is currently working as a freelance full-stack engineer on various Scala and JavaScript project. Previously, Jos has worked in many different roles in the private and public sectors, ranging from private companies such as ING, ASML, Malmberg, and Philips to organizations in the public sector, such as the Department of Defense.

    Browse publications by this author

Latest Reviews

(4 reviews total)
Very nice book on a very interesting subject.
Good
Excellent
Book Title
Access this book and the full library for FREE
Access now