123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436 |
- <!DOCTYPE html><html lang="fr"><head>
- <meta charset="utf-8">
- <title>principes de base</title>
- <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
- <meta name="twitter:card" content="summary_large_image">
- <meta name="twitter:site" content="@threejs">
- <meta name="twitter:title" content="Three.js – principes de base">
- <meta property="og:image" content="https://threejs.org/files/share.png">
- <link rel="shortcut icon" href="../../files/favicon_white.ico" media="(prefers-color-scheme: dark)">
- <link rel="shortcut icon" href="../../files/favicon.ico" media="(prefers-color-scheme: light)">
- <link rel="stylesheet" href="../resources/lesson.css">
- <link rel="stylesheet" href="../resources/lang.css">
- <script type="importmap">
- {
- "imports": {
- "three": "../../build/three.module.js"
- }
- }
- </script>
- </head>
- <body>
- <div class="container">
- <div class="lesson-title">
- <h1>principes de base</h1>
- </div>
- <div class="lesson">
- <div class="lesson-main">
- <p>Ceci est le premier article d'une série consacrée à Three.js.
- <a href="https://threejs.org">Three.js</a> est une bibliothèque 3D qui a pour objectif
- de rendre aussi facile que possible l'inclusion de contenu 3D dans une page web.</p>
- <p>Three.js est souvent confondu avec WebGL puisque la plupart du temps, mais
- pas toujours, elle exploite WebGL pour dessiner en 3D.
- <a href="https://webglfundamentals.org">WebGL est un système très bas niveau qui ne dessine que des points, des lignes et des triangles</a>.
- Faire quelque chose d'exploitable avec WebGL requiert une certaine quantité de code
- et c'est là que Three.js intervient. Elle prend en charge des choses
- telles que les scènes, lumières, ombres, matériaux, textures, mathématiques 3D, en bref,
- tout ce que vous avez à écrire par vous même si vous aviez à utiliser WebGL directement.</p>
- <p>Ces tutoriels supposent que JavaScript vous est connu et, pour grande partie,
- se conforment au style ES6. <a href="prerequisites.html">Consultez ici une brève liste des choses que vous êtes
- déjà censés connaître</a>.</p>
- <p>La plupart des navigateurs qui supportent three.js se mettent à jour automatiquement
- donc la plupart des utilisateurs devraient être capables d'exécuter ce code.
- Si vous souhaitez exécuter ce code sur un très vieux navigateur, nous vous recommandons
- un transpileur tel que <a href="https://babeljs.io">Babel</a>.
- Bien sûr, les utilisateurs exécutant de très vieux navigateurs ont probablement
- des machines incapables de faire tourner Three.js.</p>
- <p>Lors de l'apprentissage de la plupart des langages de programmation,
- la première tâche que les gens font est de faire afficher à l'ordinateur
- <code class="notranslate" translate="no">"Hello World!"</code>. Pour la programmation 3D, l'équivalent est de faire afficher
- un cube en 3D. Donc, nous commencerons par "Hello Cube!".</p>
- <p>Avant de débuter, nous allons tenter de vous donner un idée de la structure
- d'une application Three.js. Elle requiert de créer un ensemble d'objets
- et de les connecter. Voici un diagramme qui représente une application
- Three.js de petite taille:</p>
- <div class="threejs_center"><img src="../resources/images/threejs-structure.svg" style="width: 768px;"></div>
- <p>Voici ce qui est à remarquer dans le diagramme ci-dessus :</p>
- <ul>
- <li><p>Il y a un <a href="/docs/#api/en/constants/Renderer"><code class="notranslate" translate="no">Renderer</code></a>. C'est sans doute l'objet principal de Three.js. Vous passez
- une <a href="/docs/#api/en/scenes/Scene"><code class="notranslate" translate="no">Scene</code></a> et une <a href="/docs/#api/en/cameras/Camera"><code class="notranslate" translate="no">Camera</code></a> à un <a href="/docs/#api/en/constants/Renderer"><code class="notranslate" translate="no">Renderer</code></a> et il effectue le rendu (dessine) de la
- partie de la scène 3D qui est à l'intérieur de l'espace visible (en réalité une pyramide tronquée ou <em>frustum</em>)
- de la caméra dans une image 2D affichée dans un canevas (<em>canvas</em>).</p>
- </li>
- <li><p>Il y a un <a href="scenegraph.html">graphe de scène</a> qui est une structure arborescente,
- constituée de divers objets tel qu'un objet <a href="/docs/#api/en/scenes/Scene"><code class="notranslate" translate="no">Scene</code></a>, de multiple maillages (<a href="/docs/#api/en/objects/Mesh"><code class="notranslate" translate="no">Mesh</code></a>),
- des lumières (<a href="/docs/#api/en/lights/Light"><code class="notranslate" translate="no">Light</code></a>), des groupes (<a href="/docs/#api/en/objects/Group"><code class="notranslate" translate="no">Group</code></a>), des objets 3D <a href="/docs/#api/en/core/Object3D"><code class="notranslate" translate="no">Object3D</code></a> et des objets <a href="/docs/#api/en/cameras/Camera"><code class="notranslate" translate="no">Camera</code></a>.
- Un objet <a href="/docs/#api/en/scenes/Scene"><code class="notranslate" translate="no">Scene</code></a> définit la racine d'un graphe de scène et contient des propriétés telles que
- la couleur d'arrière plan et le brouillard. L'ensemble de ces objets définissent une structure
- hiérarchique de type parent/enfant, arborescente, et indique où les objets apparaissent et
- comment ils sont orientés. Les enfants sont positionnés et orientés par rapport à leur parent.
- Par exemple, les roues d'une voiture sont les enfants du châssis impliquant que si l'on déplace
- ou oriente la voiture, les roues suivront automatiquement son déplacement. Plus de
- détails sont donnés dans <a href="scenegraph.html">l'article sur les graphes de scène</a>.</p>
- <p>Il est à noter sur que ce diagramme <a href="/docs/#api/en/cameras/Camera"><code class="notranslate" translate="no">Camera</code></a> est patiellement placé dans le graphe de scène.
- Cela permet d'attirer l'attention qu'en Three.js, contrairement aux autres objets, une <a href="/docs/#api/en/cameras/Camera"><code class="notranslate" translate="no">Camera</code></a> ne doit
- pas forcément faire partie du graphe de scène pour être opérationnelle. Une <a href="/docs/#api/en/cameras/Camera"><code class="notranslate" translate="no">Camera</code></a>, de la même
- façon que les autres objets, enfant d'un autre objet, se déplace et s'oriente par rapport à son
- objet parent. A la fin de <a href="scenegraph.html">l'article sur les graphes de scène</a>, l'inclusion
- de multiples objets <a href="/docs/#api/en/cameras/Camera"><code class="notranslate" translate="no">Camera</code></a> dans un unique graphe de scène est donné en exemple.</p>
- </li>
- <li><p>Les objets de type <a href="/docs/#api/en/objects/Mesh"><code class="notranslate" translate="no">Mesh</code></a> représentent une géométrie (<code class="notranslate" translate="no">Geometry</code>) liée à un matériau (<a href="/docs/#api/en/materials/Material"><code class="notranslate" translate="no">Material</code></a>)
- spécifique. Les objets <a href="/docs/#api/en/materials/Material"><code class="notranslate" translate="no">Material</code></a> et <code class="notranslate" translate="no">Geometry</code> peuvent être liés à plusieurs objets <a href="/docs/#api/en/objects/Mesh"><code class="notranslate" translate="no">Mesh</code></a>
- simultanément. Par exemple, pour dessiner deux cubes bleus à des positions différentes, nous
- pouvons soit utiliser deux objets <a href="/docs/#api/en/objects/Mesh"><code class="notranslate" translate="no">Mesh</code></a> pour spécifier les positions et orientations de
- chaque cube; soit nous pouvons utiliser seulement une géométrie unique (<code class="notranslate" translate="no">Geometry</code>) pour décrire les
- données spatiales du cube et un matériau unique (<a href="/docs/#api/en/materials/Material"><code class="notranslate" translate="no">Material</code></a>) pour spécifier la couleur bleue.
- Les deux objets <a href="/docs/#api/en/objects/Mesh"><code class="notranslate" translate="no">Mesh</code></a> peuvent ainsi référencer les mêmes objets <code class="notranslate" translate="no">Geometry</code> et <a href="/docs/#api/en/materials/Material"><code class="notranslate" translate="no">Material</code></a>.</p>
- </li>
- <li><p>Les objets <code class="notranslate" translate="no">Geometry</code> représentent les données associées aux sommets d'une géométrie telle qu'une
- sphère, un cube, un avion, un chien, un chat, un humain, un arbre, un bâtiment, etc...
- Three.js fournit plusieurs types intégrés de <a href="primitives.html">primitives géométriques</a>.
- Vous pouvez aussi <a href="custom-buffergeometry.html">créer vos propres géométries</a> ou
- <a href="load-obj.html">charger des géométries à partir d'un fichier</a>.</p>
- </li>
- <li><p>Les objets <a href="/docs/#api/en/materials/Material"><code class="notranslate" translate="no">Material</code></a> représentent les
- <a href="materials.html">propriétés de surface utilisées pour dessiner la géométrie</a>
- telles que la couleur à utiliser ou le pouvoir réfléchissant (brillance). Un matériau (<a href="/docs/#api/en/materials/Material"><code class="notranslate" translate="no">Material</code></a>)
- peut aussi se référer à un ou plusieurs objets <a href="/docs/#api/en/textures/Texture"><code class="notranslate" translate="no">Texture</code></a> dont l'utilité est, par exemple, de plaquer
- une image sur la surface d'une géométrie.</p>
- </li>
- <li><p>Les objets <a href="/docs/#api/en/textures/Texture"><code class="notranslate" translate="no">Texture</code></a> représentent généralement des images soit <a href="textures.html">chargées de fichiers image</a>,
- soit <a href="canvas-textures.html">générées par le biais d'un canevas</a> ou
- <a href="rendertargets.html">résultant du rendu d'une autre scène</a>.</p>
- </li>
- <li><p>Les objets <a href="/docs/#api/en/lights/Light"><code class="notranslate" translate="no">Light</code></a> représentent <a href="lights.html">différentes sortes de lumière</a>.</p>
- </li>
- </ul>
- <p>Maintenant que tout cela a été défini, nous allons présenter un exemple de type <em>"Hello Cube"</em> utilisant un
- nombre minimum d'élements Three.js :</p>
- <div class="threejs_center"><img src="../resources/images/threejs-1cube-no-light-scene.svg" style="width: 500px;"></div>
- <p>Tout d'abord, chargeons Three.js :</p>
- <pre class="prettyprint showlinemods notranslate lang-html" translate="no"><script type="module">
- import * as THREE from 'three';
- </script>
- </pre>
- <p>Il est important d'écrire <code class="notranslate" translate="no">type="module"</code> dans la balise script.
- Cela nous autorise l'utilisation du mot-clé <code class="notranslate" translate="no">import</code> pour charger Three.js.
- Il y a d'autres manières de le réaliser, mais depuis la version 106 (r106),
- l'utilisation des modules est recommandée. Ils ont l'avantage de pouvoir
- facilement importer les autres modules dont ils ont besoin. Cela nous
- épargne d'avoir à charger à la main les scripts supplémentaires dont ils dépendent.</p>
- <p>Ensuite, nous avons besoin d'une balise <code class="notranslate" translate="no"><canvas></code> :</p>
- <pre class="prettyprint showlinemods notranslate lang-html" translate="no"><body>
- <canvas id="c"></canvas>
- </body>
- </pre>
- <p>Nous allons demander à Three.js de dessiner dans ce canevas donc nous devons le rechercher
- dans le document html :</p>
- <pre class="prettyprint showlinemods notranslate lang-html" translate="no"><script type="module">
- import * as THREE from 'three';
- +function main() {
- + const canvas = document.querySelector('#c');
- + const renderer = new THREE.WebGLRenderer({antialias: true, canvas});
- + ...
- </script>
- </pre>
- <p>Après la recherche du canevas, nous créons un <a href="/docs/#api/en/renderers/WebGLRenderer"><code class="notranslate" translate="no">WebGLRenderer</code></a>. Le <em>renderer</em>
- a pour mission de charger les données fournies et d'en effectuer le rendu
- dans le canevas.</p>
- <p>Notez qu'il y a quelques détails ésotériques ici. Si vous ne passez pas un
- canevas à Three.js, il va en créer un pour vous mais vous aurez à l'ajouter
- au document. Où l'ajouter peut dépendre du contexte d'utilisation et vous aurez
- à modifier votre code en conséquence. Passer un canevas à Three.js nous apparaît donc
- plus flexible. Nous pouvons mettre le canevas n'importe où et le code le retrouvera.
- Dans le cas contraire, nous aurons à coder où insérer le canevas, ce qui amènera
- probablement à changer le code si le contexte d'utilisation change.</p>
- <p>Ensuite, nous avons besoin d'une caméra. Nous créons une <a href="/docs/#api/en/cameras/PerspectiveCamera"><code class="notranslate" translate="no">PerspectiveCamera</code></a>.</p>
- <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const fov = 75;
- const aspect = 2; // valeur par défaut du canevas
- const near = 0.1;
- const far = 5;
- const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
- </pre>
- <p><code class="notranslate" translate="no">fov</code> est le raccourci pour <code class="notranslate" translate="no">field of view</code> ou champ de vision.
- Dans ce cas, 75 degrés d'ouverture verticale. Il est à noter que
- la plupart des angles dans Three.js sont exprimés en radians à l'exception
- de la caméra perspective.</p>
- <p><code class="notranslate" translate="no">aspect</code> est le ratio d'affichage dans le canevas. Cela sera détaillé
- <a href="responsive.html">dans un autre article</a>. Toutefois, par défaut,
- un canevas est de taille 300x150 pixels ce qui lui confère un ratio de 300/150 ou 2.</p>
- <p><code class="notranslate" translate="no">near</code> et <code class="notranslate" translate="no">far</code> délimitent la portion de l'espace devant la caméra dont
- le rendu est effectué. Tout ce qui est avant ou après est découpé (<em>clipped</em>),
- donc non dessiné.</p>
- <p>Ces 4 paramètres définissent une pyramide tronquée ou <em>"frustum"</em>.
- En d'autres termes, il s'agit d'une autre forme 3D à l'instar des sphères,
- cubes et prismes.</p>
- <p><img src="../resources/frustum-3d.svg" width="500" class="threejs_center"></p>
- <p>La hauteur des plans <em>near</em> et <em>far</em> est déterminée
- par le champ de vision. La largeur de ces plans est déterminée par le champ de vision et le ratio.</p>
- <p>Tout ce qui est dans le <em>frustum</em> est dessiné. Ce qui est à l'extérieur ne l'est pas.</p>
- <p>La caméra regarde par défaut suivant l'axe -Z, +Y pointant le haut.
- Nous mettons notre cube à l'origine donc nous devons déplacer la caméra de l'origine légèrement vers son arrière
- pour voir quelque chose.</p>
- <pre class="prettyprint showlinemods notranslate lang-js" translate="no">camera.position.z = 2;
- </pre>
- <p>Voici ce que nous voudrions voir :</p>
- <p><img src="../resources/scene-down.svg" width="500" class="threejs_center"></p>
- <p>Dans le schéma ci-dessus, nous pouvons voir que notre caméra est placée
- en <code class="notranslate" translate="no">z = 2</code>. Elle regarde le long de la direction -Z.
- Notre <em>frustum</em> démarre à 0.1 unités de la caméra et s'étend jusqu'à 5 unités devant elle.
- Comme le schéma est vu du haut, le champ de vision est affecté par le ratio du canvas.
- Celui-ci est deux fois plus large que haut donc le champ de vision horizontal
- est plus grand que les 75 degrés spécifiés pour le champ de vision vertical.</p>
- <p>Ensuite, nous créons une <a href="/docs/#api/en/scenes/Scene"><code class="notranslate" translate="no">Scene</code></a>. Dans Three.js, une <a href="/docs/#api/en/scenes/Scene"><code class="notranslate" translate="no">Scene</code></a> est la racine
- du graphe de scène. Tout ce que nous voulons que Three.js dessine doit être ajouté
- à la scène. Cela sera davantage détaillé dans <a href="scenegraph.html">un futur article sur le fonctionnement des scènes</a>.</p>
- <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const scene = new THREE.Scene();
- </pre>
- <p>Ensuite nous créons une géométrie de type <a href="/docs/#api/en/geometries/BoxGeometry"><code class="notranslate" translate="no">BoxGeometry</code></a> qui contient les données pour un parallélépipède.
- Quasiment tout ce que nous souhaitons afficher avec Three.js nécessite une
- géométrie qui définit les sommets qui composent nos objets 3D.</p>
- <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const boxWidth = 1;
- const boxHeight = 1;
- const boxDepth = 1;
- const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);
- </pre>
- <p>Puis nous créons un matériau basique et fixons sa couleur, qui peut être spécifiée au format hexadécimal (6 chiffres) du standard CSS.</p>
- <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const material = new THREE.MeshBasicMaterial({color: 0x44aa88});
- </pre>
- <p>Nous créons ensuite un maillage (<a href="/docs/#api/en/objects/Mesh"><code class="notranslate" translate="no">Mesh</code></a>). Dans Three.js, il représente la combinaison
- d'une <code class="notranslate" translate="no">Geometry</code> (forme de l'objet) et d'un matériau (<a href="/docs/#api/en/materials/Material"><code class="notranslate" translate="no">Material</code></a> - aspect
- d'un objet, brillant ou plat, quelle couleur, quelle texture appliquer, etc.)
- ainsi que la position, l'orientation et l'échelle de l'objet dans la scène.</p>
- <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const cube = new THREE.Mesh(geometry, material);
- </pre>
- <p>Finalement, nous ajoutons le maillage à la scène.</p>
- <pre class="prettyprint showlinemods notranslate lang-js" translate="no">scene.add(cube);
- </pre>
- <p>Nous pouvons, maintenant, effectuer le rendu de la scène en appelant la fonction <em>render</em> du <em>renderer</em>
- et en lui passant la scène et la caméra.</p>
- <pre class="prettyprint showlinemods notranslate lang-js" translate="no">renderer.render(scene, camera);
- </pre>
- <p>Voici un exemple fonctionnel :</p>
- <p></p><div translate="no" class="threejs_example_container notranslate">
- <div><iframe class="threejs_example notranslate" translate="no" style=" " src="/manual/examples/resources/editor.html?url=/manual/examples/fundamentals.html"></iframe></div>
- <a class="threejs_center" href="/manual/examples/fundamentals.html" target="_blank">Cliquer ici pour ouvrir dans une fenêtre séparée</a>
- </div>
- <p></p>
- <p>Il est difficile de déterminer s'il s'agit d'un cube 3D puisque nous
- l'observons suivant l'axe -Z sur lequel le cube est lui même aligné.
- Nous n'en voyons donc qu'une face.</p>
- <p>Animons notre cube en le faisant tourner et cela fera clairement
- apparaître qu'il est dessiné en 3D. Pour l'animation, nous effectuerons son rendu
- dans une boucle de rendu en utilisant
- <a href="https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame"><code class="notranslate" translate="no">requestAnimationFrame</code></a>.</p>
- <p>Voici notre boucle :</p>
- <pre class="prettyprint showlinemods notranslate lang-js" translate="no">function render(time) {
- time *= 0.001; // convertis le temps en secondes
- cube.rotation.x = time;
- cube.rotation.y = time;
- renderer.render(scene, camera);
- requestAnimationFrame(render);
- }
- requestAnimationFrame(render);
- </pre>
- <p><code class="notranslate" translate="no">requestAnimationFrame</code> est une requête auprès du navigateur dans le cas où vous
- voulez animer quelque chose. Nous lui passons une fonction à appeler.
- Dans notre cas, c'est la fonction <code class="notranslate" translate="no">render</code>. Le navigateur appellera cette fonction
- et, si nous mettons à jour l'affichage de la page, le navigateur refera le rendu
- de la page. Dans notre cas, nous appelons la fonction <code class="notranslate" translate="no">renderer.render</code> de Three.js
- qui dessinera notre scène.</p>
- <p><code class="notranslate" translate="no">requestAnimationFrame</code> passe à notre fonction le temps depuis lequel la page est chargée.
- Il est mesuré en millisecondes. Il est parfois plus facile de travailler
- avec des secondes. C'est pourquoi, nous l'avons converti.</p>
- <p>A présent, nous appliquons sur le cube des rotations le long des axes X et Y en fonction du temps écoulé.
- Les angles de rotation sont exprimés en <a href="https://en.wikipedia.org/wiki/Radian">radians</a>.
- Sachant que 2 PI radians fait faire un tour complet, notre cube effectuera une rotation complète
- sur chaque axe en, à peu près, 6,28 secondes.</p>
- <p>Nous effectuons alors le rendu de la scène et
- demandons une autre image pour l'animation afin de poursuivre notre boucle.</p>
- <p>A l'extérieur de la boucle, nous appelons <code class="notranslate" translate="no">requestAnimationFrame</code> une première fois pour activer la boucle.</p>
- <p></p><div translate="no" class="threejs_example_container notranslate">
- <div><iframe class="threejs_example notranslate" translate="no" style=" " src="/manual/examples/resources/editor.html?url=/manual/examples/fundamentals-with-animation.html"></iframe></div>
- <a class="threejs_center" href="/manual/examples/fundamentals-with-animation.html" target="_blank">Cliquer ici pour ouvrir dans une fenêtre séparée</a>
- </div>
- <p></p>
- <p>C'est un peu mieux mais il est toujours difficile de percevoir la 3D.
- Ce qui aiderait serait d'ajouter de la lumière.
- Three.js propose plusieurs type de lumière que nous détaillerons dans
- <a href="lights.html">un futur article</a>. Pour le moment, créons une lumière directionnelle.</p>
- <pre class="prettyprint showlinemods notranslate lang-js" translate="no">{
- const color = 0xFFFFFF;
- const intensity = 3;
- const light = new THREE.DirectionalLight(color, intensity);
- light.position.set(-1, 2, 4);
- scene.add(light);
- }
- </pre>
- <p>Les lumières directionnelles ont une position et une cible. Les deux sont par défaut en 0, 0, 0.
- Dans notre cas, nous positionnons la lumière en -1, 2, 4, de manière à ce qu'elle soit légèrement
- sur la gauche, au dessus et derrière notre caméra. La cible est toujours 0, 0, 0 donc elle va
- éclairer vers l'origine.</p>
- <p>Nous avons également besoin de changer le matériau car <a href="/docs/#api/en/materials/MeshBasicMaterial"><code class="notranslate" translate="no">MeshBasicMaterial</code></a> ne s'applique pas aux
- lumières. Nous le remplaçons par un <a href="/docs/#api/en/materials/MeshPhongMaterial"><code class="notranslate" translate="no">MeshPhongMaterial</code></a> qui est affecté par les sources lumineuses.</p>
- <pre class="prettyprint showlinemods notranslate lang-js" translate="no">-const material = new THREE.MeshBasicMaterial({color: 0x44aa88}); // cyan
- +const material = new THREE.MeshPhongMaterial({color: 0x44aa88}); // cyan
- </pre>
- <p>Voici à présent la nouvelle structure de notre programme :</p>
- <div class="threejs_center"><img src="../resources/images/threejs-1cube-with-directionallight.svg" style="width: 500px;"></div>
- <p>Et voici son fonctionnement :</p>
- <p></p><div translate="no" class="threejs_example_container notranslate">
- <div><iframe class="threejs_example notranslate" translate="no" style=" " src="/manual/examples/resources/editor.html?url=/manual/examples/fundamentals-with-light.html"></iframe></div>
- <a class="threejs_center" href="/manual/examples/fundamentals-with-light.html" target="_blank">Cliquer ici pour ouvrir dans une fenêtre séparée</a>
- </div>
- <p></p>
- <p>Cela devrait à présent apparaître très clairement en 3D.</p>
- <p>Pour le sport, ajoutons 2 cubes supplémentaires.</p>
- <p>Nous partageons la même géométrie pour chaque cube mais un matériau différent par cube
- afin qu'ils aient une couleur différente.</p>
- <p>Tout d'abord, nous définissons une fonction qui crée un nouveau matériau
- avec la couleur spécifiée. Ensuite, elle créé un maillage à partir de la
- géométrie spécifiée, l'ajoute à la scène et change sa position en X.</p>
- <pre class="prettyprint showlinemods notranslate lang-js" translate="no">function makeInstance(geometry, color, x) {
- const material = new THREE.MeshPhongMaterial({color});
- const cube = new THREE.Mesh(geometry, material);
- scene.add(cube);
- cube.position.x = x;
- return cube;
- }
- </pre>
- <p>Ensuite, nous l'appellons à 3 reprises avec 3 différentes couleurs
- et positions en X, puis nous conservons ces instances de <a href="/docs/#api/en/objects/Mesh"><code class="notranslate" translate="no">Mesh</code></a> dans un tableau.</p>
- <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const cubes = [
- makeInstance(geometry, 0x44aa88, 0),
- makeInstance(geometry, 0x8844aa, -2),
- makeInstance(geometry, 0xaa8844, 2),
- ];
- </pre>
- <p>Enfin, nous faisons tourner ces 3 cubes dans notre fonction de rendu.
- Nous calculons une rotation légèrement différente pour chacun d'eux.</p>
- <pre class="prettyprint showlinemods notranslate lang-js" translate="no">function render(time) {
- time *= 0.001; // conversion du temps en secondes
- cubes.forEach((cube, ndx) => {
- const speed = 1 + ndx * .1;
- const rot = time * speed;
- cube.rotation.x = rot;
- cube.rotation.y = rot;
- });
- ...
- </pre>
- <p>et voilà le résultat.</p>
- <p></p><div translate="no" class="threejs_example_container notranslate">
- <div><iframe class="threejs_example notranslate" translate="no" style=" " src="/manual/examples/resources/editor.html?url=/manual/examples/fundamentals-3-cubes.html"></iframe></div>
- <a class="threejs_center" href="/manual/examples/fundamentals-3-cubes.html" target="_blank">Cliquer ici pour ouvrir dans une fenêtre séparée</a>
- </div>
- <p></p>
- <p>Si nous le comparons au schéma précédent, nous constatons qu'il
- est conforme à nos attentes. Les cubes en X = -2 et X = +2
- sont partiellement en dehors du <em>frustum</em>. Ils sont, de plus,
- exagérément déformés puisque le champ de vision dépeint au travers du
- canevas est extrême.</p>
- <p>A présent, notre programme est schématisé par la figure suivante :</p>
- <div class="threejs_center"><img src="../resources/images/threejs-3cubes-scene.svg" style="width: 610px;"></div>
- <p>Comme nous pouvons le constater, nous avons 3 objets de type <a href="/docs/#api/en/objects/Mesh"><code class="notranslate" translate="no">Mesh</code></a>, chacun référençant
- la même <a href="/docs/#api/en/geometries/BoxGeometry"><code class="notranslate" translate="no">BoxGeometry</code></a>. Chaque <a href="/docs/#api/en/objects/Mesh"><code class="notranslate" translate="no">Mesh</code></a> référence également un <a href="/docs/#api/en/materials/MeshPhongMaterial"><code class="notranslate" translate="no">MeshPhongMaterial</code></a> unique
- de sorte que chaque cube possède une couleur différente.</p>
- <p>Nous espérons que cette courte introduction vous aide à débuter.
- <a href="responsive.html">La prochaine étape consiste à rendre notre code réactif et donc adaptable à de multiples situations</a>.</p>
- <div class="threejs_bottombar">
- <h3>es6 modules, Three.js et structure de dossiers</h3>
- <p>Depuis la version 106 (r106), l'utilisation de Three.js privilégie les <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import">modules es6</a>.</p>
- <p>
- Ils sont chargés via le mot-clé <code class="notranslate" translate="no">import</code> dans un script ou en ligne
- par le biais d'une balise <code class="notranslate" translate="no"><script type="module"></code>. Voici un exemple d'utilisation avec les deux :
- </p>
- <pre class="prettyprint"><script type="module">
- import * as THREE from 'three';
- ...
- </script>
- </pre>
- <p>
- Les chemins doivent être absolus ou relatifs. Un chemin relatif commencent toujours par
- <code class="notranslate" translate="no">./</code> ou par <code class="notranslate" translate="no">../</code>,
- ce qui est différent des autres balises telles que <code class="notranslate" translate="no"><img></code> et <code class="notranslate" translate="no"><a></code>.
- </p>
- <p>
- Les références à un même script ne seront chargées qu'une seule fois à partir du
- moment où leur chemin absolu est exactement identique. Pour Three.js, cela veut
- dire qu'il est nécessaire de mettre toutes les bibliothèques d'exemples dans une
- structure correcte pour les dossiers :
- </p>
- <pre class="dos">unDossier
- |
- ├-build
- | |
- | +-three.module.js
- |
- +-examples
- |
- +-jsm
- |
- +-controls
- | |
- | +-OrbitControls.js
- | +-TrackballControls.js
- | +-...
- |
- +-loaders
- | |
- | +-GLTFLoader.js
- | +-...
- |
- ...
- </pre>
- <p>
- La raison nécessitant cette structuration des dossiers est parce que les scripts
- des exemples tels que <a href="https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/OrbitControls.js"><code class="notranslate" translate="no">OrbitControls.js</code></a>
- ont des chemins relatifs tels que :
- </p>
- <pre class="prettyprint">import * as THREE from '../../../build/three.module.js';
- </pre>
- <p>
- Utiliser la même structure permet de s'assurer, lors de l'importation de
- Three.js et d'une autre bibliothèque d'exemple, qu'ils référenceront le même fichier
- three.module.js.
- </p>
- <pre class="prettyprint">import * as THREE from './someFolder/build/three.module.js';
- import {OrbitControls} from './someFolder/addons/controls/OrbitControls.js';
- </pre>
- <p>Cela est valable aussi lors de l'utilisation d'un CDN. Assurez vous que vos chemins versThis includes when using a CDN. Be <code class="notranslate" translate="no">three.modules.js</code> terminent par
- <code class="notranslate" translate="no">/build/three.modules.js</code>. Par exemple :</p>
- <pre class="prettyprint">import * as THREE from 'https://cdn.jsdelivr.net/npm/three@<version>/<b>build/three.module.js</b>';
- import {OrbitControls} from 'https://cdn.jsdelivr.net/npm/three@<version>/addons/controls/OrbitControls.js';
- </pre>
- </div>
- </div>
- </div>
- </div>
- <script src="../resources/prettify.js"></script>
- <script src="../resources/lesson.js"></script>
- </body></html>
|