Get started with Three.js

The lat­est in the se­ries demon­strates how to add tex­tures for re­al­is­tic looks and cool visual ef­fects.

Web Designer - - Contents -

Nearly uni­ver­sal browser and de­vice sup­port for WEBGL makes it a per­fect ap­proach for real-time ren­der­ing. No plug-ins are re­quired and you can start learn­ing these tech­nolo­gies right away. WEBGL 3D en­ables browser-based ex­pe­ri­ences, based on the pow­er­ful Opengl lan­guage. It taps into the graph­ics pipe­line, for highly op­ti­mised, in­ter­ac­tive ex­pe­ri­ences.

Com­plex mod­els with high lev­els of de­tail, re­flec­tions, en­vi­ron­ment maps and shad­ows can all be gen­er­ated in real-time. You can give users ac­cess to beau­ti­ful visual ex­pe­ri­ences on their desk­tops or in the palm of their hand via a smart­phone or tablet.

You’ll be us­ing the pop­u­lar 3D li­brary Three.js to dive into cre­at­ing scenes and an­i­mat­ing ob­jects. It’s free and open source, light­weight and boasts count­less award-win­ning web­sites that have used it. Face­book 3D ob­jects are also now pow­ered by this 3D li­brary.

Con­tin­u­ing from the last tu­to­rial, you will move onto learn­ing about ma­te­ri­als and tex­tures. You’ll learn how to load ex­ter­nal files to cre­ate re­al­is­tic tex­tures, ap­ply light­ing and en­vi­ron­ment maps for great re­sults. Other than hav­ing a Javascript back­ground, you can dive into this tu­to­rial with no prior knowl­edge and get some great re­sults. The goal is to de­mys­tify 3D web pro­gram­ming and get you in­spired.

1. Cre­ate a ba­sic HTML file

To get started, you need to set up a ba­sic HTML file. You can set up ex­ter­nal CSS and Javascript files or in­clude in­line for sim­plic­ity. Three.js’s ren­derer class will cre­ate a <can­vas> el­e­ment for you. Add the fol­low­ing code to your in­dex.html file.

<!DOCTYPE html>


<head> <style> </style> </head> <body> <script> </script> </body> </html>

2. In­clude the Three.js li­brary

In­clude a link to the Three.js li­brary in the head of your file, ei­ther hosted ex­ter­nally or down­load it from the Three.js repos­i­tory. You can find the li­brary and mini­fied Javascript here:­doob/three.js. Note: The code in this tu­to­rial has been tested on the lat­est re­lease of Three.js v91.

<script src=”libs/three.min.js”></script>

3. Add ba­sic CSS

In your style.css or be­tween your style tags, set up a couple of ba­sic styles. These are sim­ple style rules to keep your can­vas full screen, re­mov­ing any mar­gins or pad­ding. We’ll han­dle siz­ing of the ren­derer later on. In pre­vi­ous tu­to­ri­als you also saw how to cre­ate a win­dow re­size han­dler. html, body { mar­gin: 0; pad­ding:0; } can­vas { width: 100%; height: 100% }

4. Cre­ate a 3D scene

You’re go­ing to add a ba­sic 3D scene, which will be the con­tainer for your ob­jects. The scene is the stage that will ren­der with the cam­era. All 3D pre­sen­ta­tions will have a scene or stage of some form. What is in that stage and in view of the cam­era is what the user will see. Add the fol­low­ing code to add a scene:

// cre­ate a scene ob­ject var scene = new THREE.SCENE();

5. Add a per­spec­tive cam­era

Next, you need to add a cam­era. You’ll use the per­spec­tive cam­era meant for 3D scenes. The first at­tribute is the field of view of the cam­era. The sec­ond is the as­pect ra­tio (width/height). Then you in­di­cate the near and far clip­ping plane dis­tances, which de­fine what is to be vis­i­ble to the cam­era. Also push the cam­era back in Z space a lit­tle to see things eas­ier. var cam­era = new Three.per­spec­tive­cam­era( 75, win­­ner­width/win­­ner­height, 0.1, 1000

); cam­era.po­si­tion.set(0,0,4.0);

6. Add a ren­derer and can­vas

The ren­derer han­dles the draw­ing of the ob­jects in your scene that are vis­i­ble to the cam­era. Set the an­tialias prop­erty to true, to get smooth edges on our ob­ject. You can also de­fine the size of the draw area to full screen. The ren­derer cre­ates a ‘domele­ment’ which is ac­tu­ally an HTML <can­vas> el­e­ment. You can then ap­pend to the body. Op­tion­ally, you could spec­ify an ex­ist­ing can­vas el­e­ment to draw to if you pre­fer, via the ‘can­vas’ at­tribute of the ren­derer.

// cre­ate a ren­derer var ren­derer = new THREE. We­bglren­derer({an­tiali as:true}); ren­derer.set­size( win­­ner­width, win­dow. in­ner­height ); doc­u­ment.body.ap­pend­child( ren­derer.domele­ment


7. Cre­ate ob­ject ge­om­e­try

Three.js in­cludes a num­ber of ge­ome­tries. Try out a Torus Knot us­ing the ‘Torus­knot­buffer­ge­om­e­try’. You will swap out an­other ge­om­e­try af­ter to see how easy that is as well. Try this code first:

// cre­ate a 3D ob­ject var ge­om­e­try = new THREE. Torus­knot­buffer­ge­om­e­try( 1,.4,60,60 );

8. Cre­ate a nor­mal ma­te­rial

Next, you need a ma­te­rial. Yes, fi­nally ma­te­ri­als! That’s

why you’ve stuck it out this long! Three.js in­cludes a range of ma­te­ri­als, in­clud­ing phys­i­cal shaders, lam­bert, phong and others. You can set tex­tures to video or im­ages as well. Use a ‘Mesh­nor­mal­ma­te­rial’ to start. It’s a shader that takes in the ge­om­e­try of the ob­ject and re­turns colour. It cre­ates a nice colour range with­out need­ing an im­age tex­ture or lights to see it. var ma­te­rial = new Three.mesh­nor­mal­ma­te­rial();

9. Cre­ate a mesh and add it to the scene

To cre­ate an ob­ject ‘mesh’, you com­bine the ge­om­e­try and ma­te­rial you just de­fined. ‘Phys­i­cal’ ob­jects in 3D re­quire a ge­om­e­try that de­fines the faces, ver­tices and draw­ing of the shape. They also re­quire a ma­te­rial or skin to cover that ob­ject so we can see it. Cre­ate the mesh ob­ject and add it to the scene, like this: var ob­ject = new THREE.MESH( ge­om­e­try, ma­te­rial

); scene.add( ob­ject );

10. Ren­der the scene each re­ques­tani­ma­tion­frame

Next, you call the ren­derer’s ‘ren­der’ func­tion in­side a loop bound to the ‘re­ques­tani­ma­tion­frame’ func­tion. To an­i­mate scenes smoothly you need to ren­der at least 24 frames per sec­ond (ide­ally 60 fps), which this loop does op­ti­mally. You also add a lit­tle ro­ta­tion an­i­ma­tion to the ob­ject to see it move. Add this new code and run your scene af­ter:

// ren­der the scene var an­i­mate = func­tion () { re­ques­tani­ma­tion­frame( an­i­mate ); ob­­ta­tion.x += 0.01; ob­­ta­tion.y += 0.03; ren­­der(scene, cam­era);

}; an­i­mate();

11. Load a tex­ture from an ex­ter­nal file

Now that you can see your an­i­mated ob­ject us­ing a Nor­mal Ma­te­rial, you can ex­plore var­i­ous ma­te­ri­als and how they work. First, you need to load an ex­ter­nal ma­te­rial. This is done by us­ing the Tex­tureloader class. For bet­ter code and load man­age­ment, you can also lis­ten for progress and com­ple­tion as well on this class. In its sim­plest form use this code, re­plac­ing the file­name with your own tex­ture:

// load tex­ture var tex­ture = new Three.tex­tureloader(). load(“as­sets/rock­_01_d­if­fu­sion.jpg”);

12. Ap­ply­ing a loaded tex­ture to a ma­te­rial

Once loaded, a tex­ture file can be used by a ma­te­rial. These are typ­i­cally ap­plied a type of ‘map’. These in­clude nor­mal maps, bump maps, am­bi­ent oc­clu­sion and more. The main colour map of a ma­te­rial is sim­ply called ‘map’. It’s what you would think of typ­i­cally as an im­age tex­ture. Re­place your Mesh­nor­mal­ma­te­rial line of code with this one:

// load tex­ture var ma­te­rial = new THREE. Mesh­ba­sic­ma­te­rial({map:tex­ture });

13. Set­ting tex­ture prop­er­ties

Tex­tures have a num­ber of use­ful prop­er­ties. These in­clude how a tex­ture will wrap or re­peat around an ob­ject, off­set­ting the start po­si­tion, cen­tring and more. To see how it works, try this code to ad­just the wrap­ping of your tex­ture. It re­peats four times in the hor­i­zon­tal and one time in the ver­ti­cal.

// load tex­ture var tex­ture = new Three.tex­tureloader(). load(“as­sets/rock­_01_d­if­fu­sion.jpg”); tex­ture.wraps =­peatwrap­ping; tex­ture.wrapt =­peatwrap­ping; tex­­peat.set ( 4,1);

14. Add an am­bi­ent light

Ba­sic and nor­mal ma­te­ri­als did not re­quire lights, since they do not re­act to them. More re­al­is­tic ma­te­ri­als do re­act to light. Three.js lights in­clude direc­tional, spot lights, point lights, am­bi­ent lights and many others. Am­bi­ent lights will cast a gen­eral light on the en­tire scene, with no di­rec­tion. Add one to your scene, set­ting a colour and an in­ten­sity like this:

// cre­ate an am­bi­ent light var light = new­bi­ent­light( 0xf­feecc,.4

); scene.add( light );

15. Add a direc­tional light

Direc­tional lights cast an even light from a spe­cific di­rec­tion with­out any falloff. These em­u­late light from a large source like the sun. They can also have colour and in­ten­sity to light your scene. No­tice you can also set the light po­si­tion. Add a light like this:

//Cre­ate a Direc­tional Light var light = new Three.di­rec­tion­al­light( 0xffdd99,1.9 ); scene.add( light ); light.po­si­tion.set(-10,10,0);

16. Use lam­bert ma­te­rial

Lam­bert shader ma­te­ri­als give you more op­tions than ba­sic ma­te­ri­als and re­act to light. How­ever, they are best for non-shiny sur­faces, with­out spec­u­lar high­light­ing. They’re good for stone or un­treated wood, for ex­am­ple. They are ef­fi­cient due to their sim­plic­ity. Re­place your ba­sic ma­te­rial with this code: var ma­te­rial = new THREE. Mesh­lam­bert­ma­te­rial({map:tex­ture });

17. Use phong ma­te­rial

Phong ma­te­ri­als use a per-pixel shad­ing model and are more ac­cu­rate than lam­bert ma­te­ri­als. They have op­tions for shini­ness, spec­u­lar colour and re­flec­tiv­ity. They are

best for shiny sur­faces, with spec­u­lar high­light­ing. They are more com­pu­ta­tion­ally ex­pen­sive than lam­bert, but still less so than phys­i­cal shaded ma­te­ri­als. Re­place your ma­te­rial with this code: var ma­te­rial = new THREE. Mesh­phong­ma­te­rial({map:tex­ture, spec­u­lar:

0x333333, re­flec­tiv­ity:1.0 });

18. Use a phys­i­cal ma­te­rial

The most ac­cu­rate shad­ing ma­te­rial is the phys­i­cal ma­te­rial. Its ap­proach is used in the Un­real en­gine among others. It re­quires more com­pu­ta­tion per frame, but gives great re­al­is­tic re­sults. Swap out your ‘Torus­knot’ for a ‘Sphere’ and re­move the wrap­ping code we ap­plied. Try out this code to re­place your pre­vi­ous en­try: var ge­om­e­try = new Three.sphere­buffer­ge­om­e­try( 2,60,60 ); var ma­te­rial = new Three.mesh­phys­i­cal­ma­te­rial(

{ map:tex­ture }); var ob­ject = new THREE.MESH( ge­om­e­try, ma­te­rial

); scene.add( ob­ject );

19. Load an en­vi­ron­ment map

Phys­i­cal ma­te­ri­als work best with en­vi­ron­ment maps ap­plied. These maps are sky boxes that sur­round the ob­ject so it can af­fect it from all di­rec­tions ac­cu­rately, im­pact­ing the colour and in­ten­sity of the colour on the sur­face tex­ture. A great re­source for cube maps can be found here:­­dex. php?page=tex­tures. Try adding this code to load a map. var en­vmap = new­be­tex­tureloader() .set­path( ‘as­sets/’)

.load( [ ‘posx.jpg’, ‘negx.jpg’, ‘posy.jpg’, ‘negy.jpg’, ‘posz.jpg’, ‘negz.jpg’ ] );

20. Ap­ply en­vi­ron­ment map and more set­tings

En­vmaps im­pact the colour and in­ten­sity of the colour on the sur­face tex­ture, from all around it. How much can be set by their rough­ness, re­flec­tiv­ity and met­al­ness. Up­date your ma­te­rial line to this one: var ma­te­rial = new Three.mesh­phys­i­cal­ma­te­rial( { map:tex­ture, en­vmap:en­vmap, met­al­ness:1.0,rough­ness:0.2 });

21. Ap­ply en­vi­ron­ment map to scene

To make the scene re­ally come alive, you can also ap­ply the en­vi­ron­ment map as a cube map to the scene. Keep ex­per­i­ment­ing with these ma­te­ri­als, com­bi­na­tions and set­tings to see what else you can ac­com­plish. Bump maps and nor­mal maps will give great de­tail to your tex­tures as well! Fi­nally, try adding this code af­ter declar­ing your scene:

// ap­ply en­vmap to scene scene.back­ground = en­vmap;

Ini­tially you can use Nor­mal Ma­te­ri­als to see your ob­ject in 3D space with­out hav­ing to set up lights. With the ba­sics set, you can add lights and shad­ows

Step 15: Us­ing a loaded ba­sic ma­te­rial tex­ture file, you can cre­ate a de­tailed ma­te­rial that skins your 3D ob­ject

Step 16: Us­ing a lam­bert ma­te­rial you can have light­ing af­fect your ma­te­rial to give much more re­al­ism to your scene

Step 17: Us­ing a phong shader is more ac­cu­rate than lam­bert ma­te­ri­als, al­low­ing more de­tailed spec­u­lar and shini­ness de­tail to sur­face

Step 21: Adding an en­vi­ron­ment cube map to your scene, com­bined with phys­i­cal ma­te­ri­als, can cre­ate re­al­is­tic re­sults

Newspapers in English

Newspapers from UK

© PressReader. All rights reserved.