Advertisement
 
Tutorial
  1 <!DOCTYPE html> 
  2 <!-- The previous line tells the browser, that the page uses the HTML5 standard. --> 
  3  
  4 <html>
  5     <head>
  6         <title>Three.js tutorial - Lesson 05</title> 
  7         <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> 
  8  
  9         <!-- The following meta line optimizes the site for mobile devices. It sets the viewport size 
 10         to the screen size, so it will be displayed maximized, but unscaled. --> 
 11         <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1"> 
 12         <style type="text/css"> 
 13             body { 
 14                 /* Set the background color of the HTML page to black */ 
 15                 background-color: #000000; 
 16  
 17                 /* Hide oversized content. This prevents the scroll bars. */ 
 18                 overflow: hidden; 
 19             } 
 20         </style> 
 21         <!-- Include Three.js libraries --> 
 22         <script src="../js/r69/three.js"></script> 
 23         <script src="../js/r69/Detector.js"></script> 
 24         <script src="../js/r69/CanvasRenderer.js"></script> 
 25         <script src="../js/r69/Projector.js"></script> 
 26     </head> 
 27     <body>
 28         <!-- This is the DIV element which will contain the WebGL canvas. To be identifiable lateron, 
 29         the id 'WebGLCanvas' is applied to it. --> 
 30         <div id="WebGLCanvas"> 
 31  
 32         <!-- This JavaScript block encloses the Three.js commands --> 
 33         <script> 
 34             // Global scene object 
 35             var scene; 
 36  
 37             // Global camera object 
 38             var camera; 
 39  
 40             // Global mesh object of the pyramid 
 41             var pyramidMesh; 
 42  
 43             // Global mesh object of the cube 
 44             var cubeMesh; 
 45  
 46             // Initialize the scene 
 47             initializeScene(); 
 48  
 49             // Animate the scene 
 50             animateScene(); 
 51  
 52             /** 
 53              * Initialze the scene. 
 54              */ 
 55             function initializeScene(){ 
 56                 // Check whether the browser supports WebGL. If so, instantiate the hardware accelerated 
 57                 // WebGL renderer. For antialiasing, we have to enable it. The canvas renderer uses 
 58                 // antialiasing by default. 
 59                 // The approach of multiplse renderers is quite nice, because your scene can also be 
 60                 // viewed in browsers, which don't support WebGL. The limitations of the canvas renderer 
 61                 // in contrast to the WebGL renderer will be explained in the tutorials, when there is a 
 62                 // difference. 
 63                 if(Detector.webgl){ 
 64                     renderer = new THREE.WebGLRenderer({antialias:true}); 
 65  
 66                 // If its not supported, instantiate the canvas renderer to support all non WebGL browsers 
 67                 } else { 
 68                     renderer = new THREE.CanvasRenderer(); 
 69                 } 
 70  
 71                 // Set the background color of the renderer to black, with full opacity 
 72                 renderer.setClearColor(0x000000, 1); 
 73  
 74                 // Get the size of the inner window (content area) to create a full size renderer 
 75                 canvasWidth = window.innerWidth; 
 76                 canvasHeight = window.innerHeight; 
 77  
 78                 // Set the renderers size to the content areas size 
 79                 renderer.setSize(canvasWidth, canvasHeight); 
 80  
 81                 // Get the DIV element from the HTML document by its ID and append the renderers DOM 
 82                 // object to it 
 83                 document.getElementById("WebGLCanvas").appendChild(renderer.domElement); 
 84  
 85                 // Create the scene, in which all objects are stored (e. g. camera, lights, 
 86                 // geometries, ...) 
 87                 scene = new THREE.Scene(); 
 88  
 89                 // Now that we have a scene, we want to look into it. Therefore we need a camera. 
 90                 // Three.js offers three camera types: 
 91                 //  - PerspectiveCamera (perspective projection) 
 92                 //  - OrthographicCamera (parallel projection) 
 93                 //  - CombinedCamera (allows to switch between perspective / parallel projection 
 94                 //    during runtime) 
 95                 // In this example we create a perspective camera. Parameters for the perspective 
 96                 // camera are ... 
 97                 // ... field of view (FOV), 
 98                 // ... aspect ratio (usually set to the quotient of canvas width to canvas height) 
 99                 // ... near and 
100                 // ... far. 
101                 // Near and far define the cliping planes of the view frustum. Three.js provides an 
102                 // example (http://mrdoob.github.com/three.js/examples/ 
103                 // -> canvas_camera_orthographic2.html), which allows to play around with these 
104                 // parameters. 
105                 // The camera is moved 10 units towards the z axis to allow looking to the center of 
106                 // the scene. 
107                 // After definition, the camera has to be added to the scene. 
108                 camera = new THREE.PerspectiveCamera(45, canvasWidth / canvasHeight, 1, 100); 
109                 camera.position.set(0, 0, 10); 
110                 camera.lookAt(scene.position); 
111                 scene.add(camera); 
112  
113                 // To create a pyramid, we use THREE.CylinderGeometry. By its five parameters, we are 
114                 // able to create the geometry of the pyramid (subtype of a cylinder). 
115                 // Parameter 1 'radiusTop': Controls the radius of the upper end of the cylinder. If we 
116                 //                          set to to '0', we have a cone. 
117                 // Parameter 2 'radiusBottom': Controls the radius of the lower end. 
118                 // Parameter 3 'height': Sets the height of the cylinder. 
119                 // Parameter 4 'segments': Number of segments, forming the cylindrical shell. To create 
120                 //                         a pyramid, we choose '4'. 
121                 // Parameter 5 'openEnded': Allows to have open ends ('true') or closed ends ('false') 
122                 //                          of the cylindern. Since the pyramid shall have a bottom 
123                 //                          face, we set it to 'false'. 
124                 var pyramidGeometry = new THREE.CylinderGeometry(0, 1.5, 1.5, 4, false); 
125  
126                 // Coloring the faces with vertex colors is a bit tricky, but allows us to see how to 
127                 // loop through the faces and check whether they have three or four vertices. 
128                 // With a simple 'for'-loop we run through all faces, which are accessed by their index.
129                 // The 'instanceof' operator gives the possibility to check, whether the current face is 
130                 // a THREE.Face4 or THREE.Face3. Depending on its object type, we set three or four 
131                 // vertex colors. For THREE.Face4 we switch the colors of vertex 1 and 2 for every 
132                 // second face because we want the lower vertices having the same colors as the 
133                 // neighbour face. Vertex 0 and 3 are the upper vertices, which are always red. 
134                 // If WebGL isn't supported and the canvas renderer is used, it ignores the vertex 
135                 // colors. They are only supported by the WebGL renderer (current release of 
136                 // Three.js: 49). 
137                 for(i = 0; i < pyramidGeometry.faces.length; i++){ 
138                     if(pyramidGeometry.faces[i] instanceof THREE.Face4){ 
139                         pyramidGeometry.faces[i].vertexColors[0] = new THREE.Color(0xFF0000); 
140                         if((i % 2) == 0){ 
141                             pyramidGeometry.faces[i].vertexColors[1] = new THREE.Color(0x00FF00); 
142                             pyramidGeometry.faces[i].vertexColors[2] = new THREE.Color(0x0000FF); 
143                         } else { 
144                             pyramidGeometry.faces[i].vertexColors[1] = new THREE.Color(0x0000FF); 
145                             pyramidGeometry.faces[i].vertexColors[2] = new THREE.Color(0x00FF00); 
146                         } 
147                         pyramidGeometry.faces[i].vertexColors[3] = new THREE.Color(0xFF0000); 
148                     } else { 
149                         pyramidGeometry.faces[i].vertexColors[0] = new THREE.Color(0xFF0000); 
150                         pyramidGeometry.faces[i].vertexColors[1] = new THREE.Color(0x00FF00); 
151                         pyramidGeometry.faces[i].vertexColors[2] = new THREE.Color(0x0000FF); 
152                     } 
153                 } 
154  
155                 // To activate the vertex color, we have to set 'vertexColors' attribute to 
156                 // 'THREE.VertexColors'. Otherwise they won't be displayed. 
157  
158                 // Create a basic material, supporting vertex colors. Activate the 'doubleSided' 
159                 // attribute to force the rendering of both sides of each face (front and back). 
160                 // This prevents the so called 'backface culling'. Usually, only the side is 
161                 // rendered, whose normal vector points towards the camera. The other side is not 
162                 // rendered (backface culling). But this performance optimization sometimes leads 
163                 // to wholes in the surface. When this happens in your surface, simply set 
164                 // 'doubleSided' to 'true'. 
165                 var pyramidMaterial = new THREE.MeshBasicMaterial({ 
166                     vertexColors:THREE.VertexColors, 
167                     side:THREE.DoubleSide 
168                 }); 
169  
170                 // Create a mesh and insert the geometry and the material. Translate the whole mesh 
171                 // by -1.5 on the x axis and by 4 on the z axis. Finally add the mesh to the scene. 
172                 pyramidMesh = new THREE.Mesh(pyramidGeometry, pyramidMaterial); 
173                 pyramidMesh.position.set(-1.5, 0.0, 4.0); 
174                 scene.add(pyramidMesh); 
175  
176                 // Create the cube 
177                 // Parameter 1: Width 
178                 // Parameter 2: Height 
179                 // Parameter 3: Depth 
180                 var boxGeometry = new THREE.BoxGeometry(1.5, 1.5, 1.5); 
181  
182                 // Applying different materials to the faces is a more difficult than applying one 
183                 // material to the whole geometry. We start with creating an array of 
184                 // THREE.MeshBasicMaterial. 
185  
186                 // Define six colored materials 
187                 var boxMaterials = [ 
188                     new THREE.MeshBasicMaterial({color:0xFF0000}), 
189                     new THREE.MeshBasicMaterial({color:0x00FF00}), 
190                     new THREE.MeshBasicMaterial({color:0x0000FF}), 
191                     new THREE.MeshBasicMaterial({color:0xFFFF00}), 
192                     new THREE.MeshBasicMaterial({color:0x00FFFF}), 
193                     new THREE.MeshBasicMaterial({color:0xFFFFFF}) 
194                 ]; 
195  
196                 // Create a MeshFaceMaterial, which allows the cube to have different materials on 
197                 // each face 
198                 var boxMaterial = new THREE.MeshFaceMaterial(boxMaterials); 
199  
200                 // Create a mesh and insert the geometry and the material. Translate the whole mesh 
201                 // by 1.5 on the x axis and by 4 on the z axis and add the mesh to the scene. 
202                 boxMesh = new THREE.Mesh(boxGeometry, boxMaterial); 
203                 boxMesh.position.set(1.5, 0.0, 4.0); 
204                 scene.add(boxMesh); 
205             } 
206  
207             /** 
208              * Animate the scene and call rendering. 
209              */ 
210             function animateScene(){ 
211                 // Increase the y rotation of the triangle 
212                 pyramidMesh.rotation.y += 0.1; 
213  
214                 // Decrease the rotation of the cube 
215                 boxMesh.rotateOnAxis(new THREE.Vector3(1, 1, 1).normalize(), 0.075); 
216  
217                 // Define the function, which is called by the browser supported timer loop. If the 
218                 // browser tab is not visible, the animation is paused. So 'animateScene()' is called 
219                 // in a browser controlled loop. 
220                 requestAnimationFrame(animateScene); 
221  
222                 // Map the 3D scene down to the 2D screen (render the frame) 
223                 renderScene(); 
224             } 
225  
226             /** 
227              * Render the scene. Map the 3D world to the 2D screen.
228              */ 
229             function renderScene(){ 
230                 renderer.render(scene, camera); 
231             } 
232         </script> 
233     </body> 
234 </html>
Live example