5/13
3. First Three.js program
Executing the code
Consider the code provided in the directory first_program
-
Decompress the code
-
Hint: in Unix command line
$ tar xvfJ 01_first_program.tar.xz
-
-
Open the file index.html using a web browser
-
You should observe the following result
-
Analyzing the code
The code contains 4 files.
-
index.html: the HTML file describing the general structure of the document.
The HTML code consists of a header part defining general information such as text-encoding format, viewport ratio, webpage title.
The header also includes one external CSS file, and two JavaScript files corresponding respectively to loading Three.js library, and our 3D scene. Note that the order of file inclusion in important, and three.js should be included before any file using it.[1]
The HTML body corresponds to an empty page, an invisible tag with id "Tag3DScene" is placed, and will be used to include the rendered image corresponding to the 3D scene.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- =========================================== -->
<!-- General HTML Headers -->
<!-- =========================================== -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title> My first 3D scene </title>
<link rel="stylesheet" href="style.css">
<!-- =========================================== -->
<!-- Load JavaScript files -->
<!-- =========================================== -->
<!-- Load Three.js library -->
<script src="lib/three.js" defer></script>
<!-- Load 3D scene description -->
<script src="scene.js" defer></script>
</head>
<!-- =========================================== -->
<!-- Webpage body -->
<!-- =========================================== -->
<body>
<!-- In our case, the body of the webpage is almost empty.
Only one markup is used to be replaced by the 3D scene
-->
<div id="Tag3DScene"> </div>
</body>
</html>
-
style.css: the CSS file describing the appearance related to the HTML page.
This file is only used to set the page margin to 0, therefore the resulting image of the scene will take the entire size of the window.
/* Empty CSS stylesheet, only set margin of the page to 0 to fill the window with the 3D scene */
body {
margin: 0px;
}
-
lib/three.js: the code corresponding to the Three.js library. Loading JavaScript library typically corresponds to include source code file before your own script.
-
Note that you don’t have to read the code of this file.
-
Note also that JavaScript libraries are often provided in minimal version of their code (min.js) corresponding to a condensed text file without any comments, line breaks, and shorter variable name, see for instance three.min.js. This allows to get smaller file size that can be downloaded faster when executing the code from a distant website.
-
-
lib/scene.js: the actual code handling the 3D scene.
"use strict"; // Always add this line in your JavaScript code
// ==================================================== //
// Initialization of the scene variables
// ==================================================== //
// Init the scene graph
const sceneGraph = new THREE.Scene(); // JavaScript classes are instanciated using "new ClassName" syntax
// Get size (widht and height) of the window
// Note that window is a global variable automatically filled by your web browser
const width = window.innerWidth;
const height = window.innerHeight;
// Init perspective camera (field of view of 45 degrees, depth view between 0.1 to 500)
const camera = new THREE.PerspectiveCamera(45, width/height, 0.1, 500); // Note that parameters can be passed in the constructor of the class
camera.position.set(-5, 5, 5); // Place camera position in space
camera.lookAt(0, 0, 0); // View position from the camera
// Init render engine
const renderer = new THREE.WebGLRenderer( );
renderer.setPixelRatio( window.devicePixelRatio ); // Set size of the pixel
renderer.setClearColor('rgb(255, 255, 150)', 1.0); // Background color (in RGB description)
renderer.setSize( width, height ); // Size of the rendered image
// Add the render image in the HTML document (at the position of element with id Tag3DScene)
const htmlElement = document.querySelector("#Tag3DScene");
htmlElement.appendChild(renderer.domElement);
// ==================================================== //
// Setup visual elements of the 3D scene (shapes, light)
// ==================================================== //
// Init light element
const spotLight = new THREE.SpotLight('rgb(255,255,255)'); // White spotlight (emit light in all directions)
spotLight.position.set(-5, 8, 0); // Set spotlight position in space
sceneGraph.add(spotLight); // Add spotlight in the scenegraph
// Init 3D shape
// *************************************************** //
// Cubic primitive of size 1x1x1, centered in (0,0,0)
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
// Set red color for the cube (MeshPhongMaterial allows the cube to be correctly illuminated by the spotlight)
const cubeMaterial = new THREE.MeshPhongMaterial( {color:'rgb(255,0,0)'} );
// In Three.js, a 3D drawable shape (called Mesh) is a pair of Geometry and Material
const cubeObject = new THREE.Mesh( cubeGeometry,cubeMaterial );
// Translate the cube in space to be centered in (0, 0.5, 0)
cubeObject.translateY(0.5);
// Add the cube in the scenegraph
sceneGraph.add(cubeObject);
// ==================================================== //
// Rendering of the 3D scene
// ==================================================== //
// The render engine takes as parameters the scenegraph and a camera
renderer.render(sceneGraph, camera);
-
Without going into the details of JavaScript language, make sure you understand globally the different part of this program.
-
Note that the sentence
sceneGraph.add(cubeObject)is necessary for the cube to appear on screen. Comment this line, and observe that, this time the cube will not be displayed if he his not part of the scene.
A version of the same code can be made in only one single file.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title> My first 3D scene </title>
<style> body {margin: 0;}
</style>
</head>
<body>
<div id="Tag3DScene"> </div>
</body>
<script src="https://threejs.org/build/three.min.js"></script>
<script>
"use strict";
const sceneGraph = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 500);
camera.position.set(-5, 5, 5);
camera.lookAt(0, 0, 0);
const renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setClearColor('rgb(255, 255, 150)', 1.0);
renderer.setSize(window.innerWidth, window.innerHeight);
const htmlElement = document.querySelector("#Tag3DScene");
htmlElement.appendChild(renderer.domElement);
const spotLight = new THREE.SpotLight('rgb(255,255,255)');
spotLight.translateY(0.5);
sceneGraph.add(spotLight);
const cubeObject = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), new THREE.MeshPhongMaterial({ color: 'rgb(255,0,0)' }));
cubeObject.position.set(0, 0.5, 0);
sceneGraph.add(cubeObject);
renderer.render(sceneGraph, camera);
</script>
</html>
This time, HTML, CSS, and JavaScript code are all embedded in the same file (and the Three.js library is loaded online (you need an internet connection)).
This allows to visualize the entire code in a concise way. However, when developing, we suggest using a different file for each language. This allows to separate the semantic purpose for good practice (document description in HTML, logic and 3D scene in JavaScript), and ease the code edition as well as your code editor in handling only one language per file.
Exercise
Try to modify the following parameters one by one in editing the JavaScript file directly, and observe the result in refreshing your webpage (when reloading the HTML webpage, the JavaScript code is reloaded).
-
Change the background color of the scene.[2]
-
Change the position (and size) of the cube - understand the x, y, and z direction
-
Change the color of the cube
-
Change the position of the spotlight
-
Change the position of the camera
-
Add a second cube with different color, size, and position in the scene (see the following example).