Initiation à la programmation 3D avec Three.js Dans une animation 3D, nous avons la possibilité non seulement de déplacer des objets sur la scène, mais également de déplacer des sources de lumière et une caméra pour modifier le point de vue. Nous utiliserons un maillage ou Mesh pour créer les objets et les formes. Pour cela nous utiliserons des matières Materials dont nous pouvons choisir les propriétés telles que la couleur, l’opacité, la réflectivité. Il est également possible d’ajouter une texture en plaquant une image sur la surface de l’objet. Nous allons utiliser la libraire open source JavaScript Three.js qui fonctionne dans tous les navigateurs sans addition de plugin et qui simplifie la programmation 3D. Vous en trouverez ici la version 69 : http://isnangellier.alwaysdata.net/three.min.js, de nombreux exemples de réalisation ainsi qu’une documentation complète sur le site http://threejs.org/ I. La scène et l’objet Créer la page html.
Shapes In Scene La première chose à faire est de mettre en place la scène puis de placer la caméra. L’objet scène est créé en utilisant : scene=new THREE.Scene(). Les dimensions de la fenêtre d’affichage sont choisies égales aux dimensions de l’écran. On laisse Three.js créer le DOM et on utilise WebGLRenderer pour restituer la scène et gérer le rendu. Créer le script3D.js ci-dessous qui constitue le squelette de base. function init() { function render() { requestAnimationFrame(render);//fait une boucle sur render renderer.render(scene,camera);//pour visualiser la scène avec la caméra } scene=new THREE.Scene();//cet objet scène va contenir tous les objets renderer=new THREE.WebGLRenderer();//cet objet va permettre le rendu de la scène renderer.setClearColor("black",1.0); renderer.setSize(window.innerWidth,window.innerHeight); renderer.shadowMapEnabled=true; camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);//cela d»termine ce que l'on va voir
camera.position.x=15; camera.position.y=16; camera.position.z=13; camera.lookAt(scene.position); document.body.appendChild(renderer.domElement); render(); } window.onload=init;//une fois la page chargée, initialise Nous allons maintenant placer un cube sur la scène ainsi qu’un spot lumineux pour l’éclairer. Pour cela on donne les caractéristiques de sa géométrie et on précise la matière qui le constitue. On précise la position du spot lumineux et on l’ajoute à la scène. Placer ce code juste avant render(). var cubeGeometry=new THREE.BoxGeometry(6,4,6);//largeur, hauteur et profondeur du cube var cubeMaterial=new THREE.MeshLambertMaterial({//définition de la matière pour savoir comment l'objet réagira sous l'éclairage color: "yellow" }); var cube=new THREE.Mesh(cubeGeometry,cubeMaterial);//on combine les deux informations précédentes scene.add(cube); var spotLight=new THREE.SpotLight("white"); spotLight.position.set(10,20,-20);//détermine la position du spot lumineux spotLight.castShadow=true; scene.add(spotLight); On peut vérifier qu’un cube rouge éclairé par de la lumière bleue apparaît noir, et qu’un cube jaune éclairé par de la lumière verte apparaît vert… L’absence de précision sur la position du cube le place à l’origine (0,0,0). On peut ajouter une sphère sur la scène en précisant sa position, celle-ci est repérée dans le système d’axes représenté ci-dessous :
var sphereGeometry = new THREE.SphereGeometry( 2, 32, 32 ); var sphereMaterial = new THREE.MeshLambertMaterial( {color: "blue"} ); var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); sphere.position.x=-10; sphere.position.z=-6; scene.add(sphere);
Ainsi qu’un plan positionné de façon à ce que le cube de hauteur 4, centré en O, repose sur ce plan : var geometry = new THREE.PlaneBufferGeometry( 5, 20, 32 ); var material = new THREE.MeshLambertMaterial( {color: "red"} ); var plane = new THREE.Mesh( geometry, material ); plane.position.y=-2; scene.add( plane ); Puis faire tourner le plan de -90° pour qu’il devienne horizontal : plane.rotation.x=-0.5*Math.PI; II. Exemple d’application Nous effaçons les objets précédents pour créer une nouvelle sphère : var sphereGeometry = new THREE.SphereGeometry( 5, 32, 32 ); var sphereMaterial = new THREE.MeshNormalMaterial( {color: "blue"} ); var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); sphere.position.x=0; sphere.position.z=0; scene.add(sphere); Nous ajoutons dans le fichier html un lien vers la librairie OrbitControls.js que l’on trouvera ici : http://isnangellier.alwaysdata.net/OrbitControls.js Dans script3D.js, on ajoute : cameraControl = new THREE.OrbitControls(camera); control = new function () { this.rotationSpeed = 0.005; this.opacity = 0.6; }; et on ajoute dans la fonction render() : cameraControl.update(); Grâce à ces lignes de code, on peut déplacer la sphère avec les touches directionnelles du clavier et on peut la faire tourner et redimensionner avec la souris. Nous allons maintenant mettre une texture de planisphère sur la sphère. Nous avons besoin de l’image : http://isnangellier.alwaysdata.net/earthmap.jpg Nous changeons également la matière de la sphère. var sphereGeometry = new THREE.SphereGeometry( 5, 32, 32 ); var earthTexture = new THREE.ImageUtils.loadTexture('earthmap.jpg'); var sphereMaterial = new THREE.MeshBasicMaterial(); sphereMaterial.map=earthTexture; var Earth = new THREE.Mesh(sphereGeometry, sphereMaterial); scene.add(Earth);
Nous allons également ajouter des nuages à la surface de la terre : http://isnangellier.alwaysdata.net/earthcloudmap.jpg var cloudsGeometry= new THREE.SphereGeometry(0.51, 32, 32 ); var cloudsTexture = new THREE.ImageUtils.loadTexture('earthcloudmap.jpg'); var sphereMaterial = new THREE.MeshBasicMaterial({ map : cloudsTexture, side : THREE.DoubleSide, opacity : 0.35, transparent : true, depthWrite : false, } ); var Clouds = new THREE.Mesh(sphereGeometry, sphereMaterial); On peut lier les nuages à la Terre Earth.add(Clouds); On peut faire tourner la Terre et les nuages autour de l’axe des y en ajoutant dans le render() Earth.rotation.y +=0.002; On se propose maintenant de représenter la Terre éclairée par le Soleil de façon plus réaliste. On sera amené à utiliser le même matériau qu’au début MeshLambertMaterial pour diffuser la lumière envoyée par une DirectionalLight (une source infiniment lointaine comme le Soleil, voir la documentation). On fera tourner la Terre autour d’un axe incliné de 23° par rapport à l’axe des y en utilisant : rotateOnAxis(axis,rad) après avoir défini var axis = new THREE.Vector3(0,0.92,-0.39);
On est très loin de ce résultat http://planetmaker.wthr.us/ mais il faut bien un début!