You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

490 lines
30 KiB
HTML

<!DOCTYPE html><html lang="fr"><head>
<meta charset="utf-8">
<title>Lumières</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 Lumières">
<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>Lumières</h1>
</div>
<div class="lesson">
<div class="lesson-main">
<p>Cet article fait partie d'une série d'articles sur three.js. Le
premier article est <a href="fundamentals.html">les bases de three.js</a>. Si
vous ne l'avez pas encore lu et que vous débutez avec three.js, vous pourriez envisager de
commencer par là, ainsi que l'article sur <a href="setup.html">la configuration de votre environnement</a>. Le
<a href="textures.html">l'article précédent portait sur les textures</a>.</p>
<p>Voyons comment utiliser les différents types de lumières dans three.js.</p>
<p>En partant d'un de nos exemples précédents, mettons à jour la caméra.
Nous définirons le champ de vision à 45 degrés, le plan lointain à 100 unités,
et nous déplacerons la caméra de 10 unités vers le haut et de 20 unités vers l'arrière par rapport à l'origine</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">*const fov = 45;
const aspect = 2; // the canvas default
const near = 0.1;
*const far = 100;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
+camera.position.set(0, 10, 20);
</pre>
<p>Ajoutons ensuite <a href="/docs/#examples/controls/OrbitControls"><code class="notranslate" translate="no">OrbitControls</code></a>. Les <a href="/docs/#examples/controls/OrbitControls"><code class="notranslate" translate="no">OrbitControls</code></a>
permettent à l'utilisateur de faire tourner ou d'<em>orbiter</em> la caméra autour d'un point. Les <a href="/docs/#examples/controls/OrbitControls"><code class="notranslate" translate="no">OrbitControls</code></a>
sont une fonctionnalité optionnelle de three.js, nous devons donc d'abord les inclure
dans notre page</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">import * as THREE from 'three';
+import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
</pre>
<p>Ensuite, nous pouvons les utiliser. Nous passons aux <a href="/docs/#examples/controls/OrbitControls"><code class="notranslate" translate="no">OrbitControls</code></a> une caméra à
contrôler et l'élément DOM à utiliser pour obtenir les événements d'entrée</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">const controls = new OrbitControls(camera, canvas);
controls.target.set(0, 5, 0);
controls.update();
</pre>
<p>Nous définissons également la cible d'orbite à 5 unités au-dessus de l'origine
et appelons ensuite <code class="notranslate" translate="no">controls.update</code> pour que les contrôles utilisent la nouvelle
cible.</p>
<p>Voyons ensuite comment créer des éléments à éclairer. D'abord, nous allons créer un
plan au sol. Nous appliquerons une petite texture en damier de 2x2 pixels qui
ressemble à ceci :</p>
<div class="threejs_center">
<img src="../examples/resources/images/checker.png" class="border" style="
image-rendering: pixelated;
width: 128px;
" alt="">
</div>
<p>Nous chargeons d'abord la texture, la définissons en mode répétition, définissons le filtrage au
plus proche, et définissons le nombre de fois que nous voulons qu'elle se répète. Étant donné que la
texture est un damier de 2x2 pixels, en la répétant et en définissant la
répétition à la moitié de la taille du plan, chaque case du damier
aura exactement 1 unité de taille ;</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">const planeSize = 40;
const loader = new THREE.TextureLoader();
const texture = loader.load('resources/images/checker.png');
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.magFilter = THREE.NearestFilter;
texture.colorSpace = THREE.SRGBColorSpace;
const repeats = planeSize / 2;
texture.repeat.set(repeats, repeats);
</pre>
<p>Nous créons ensuite une géométrie de plan, un matériau pour le plan et un maillage
pour l'insérer dans la scène. Les plans sont par défaut dans le plan XY,
mais le sol est dans le plan XZ, nous le faisons donc pivoter.</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">const planeGeo = new THREE.PlaneGeometry(planeSize, planeSize);
const planeMat = new THREE.MeshPhongMaterial({
map: texture,
side: THREE.DoubleSide,
});
const mesh = new THREE.Mesh(planeGeo, planeMat);
mesh.rotation.x = Math.PI * -.5;
scene.add(mesh);
</pre>
<p>Ajoutons un cube et une sphère pour avoir 3 éléments à éclairer, y compris le plan.</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">{
const cubeSize = 4;
const cubeGeo = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize);
const cubeMat = new THREE.MeshPhongMaterial({color: '#8AC'});
const mesh = new THREE.Mesh(cubeGeo, cubeMat);
mesh.position.set(cubeSize + 1, cubeSize / 2, 0);
scene.add(mesh);
}
{
const sphereRadius = 3;
const sphereWidthDivisions = 32;
const sphereHeightDivisions = 16;
const sphereGeo = new THREE.SphereGeometry(sphereRadius, sphereWidthDivisions, sphereHeightDivisions);
const sphereMat = new THREE.MeshPhongMaterial({color: '#CA8'});
const mesh = new THREE.Mesh(sphereGeo, sphereMat);
mesh.position.set(-sphereRadius - 1, sphereRadius + 2, 0);
scene.add(mesh);
}
</pre>
<p>Maintenant que nous avons une scène à éclairer, ajoutons des lumières !</p>
<h2 id="-ambientlight-"><a href="/docs/#api/en/lights/AmbientLight"><code class="notranslate" translate="no">AmbientLight</code></a></h2>
<p>Commençons par créer une <a href="/docs/#api/en/lights/AmbientLight"><code class="notranslate" translate="no">Lumière Ambiante</code></a></p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">const color = 0xFFFFFF;
const intensity = 1;
const light = new THREE.AmbientLight(color, intensity);
scene.add(light);
</pre>
<p>Faisons en sorte de pouvoir également ajuster les paramètres de la lumière.
Nous utiliserons de nouveau <a href="https://github.com/georgealways/lil-gui">lil-gui</a>.
Pour pouvoir ajuster la couleur via lil-gui, nous avons besoin d'un petit assistant
qui présente une propriété à lil-gui qui ressemble à une chaîne de couleur hexadécimale CSS
(par ex. : <code class="notranslate" translate="no">#FF8844</code>). Notre assistant obtiendra la couleur d'une propriété nommée,
la convertira en chaîne hexadécimale pour l'offrir à lil-gui.
Lorsque lil-gui essaiera de définir la propriété de l'assistant, nous assignerons le résultat à la
couleur de la lumière.</p>
<p>Voici l'assistant :</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">class ColorGUIHelper {
constructor(object, prop) {
this.object = object;
this.prop = prop;
}
get value() {
return `#${this.object[this.prop].getHexString()}`;
}
set value(hexString) {
this.object[this.prop].set(hexString);
}
}
</pre>
<p>Et voici notre code de configuration de lil-gui</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">const gui = new GUI();
gui.addColor(new ColorGUIHelper(light, 'color'), 'value').name('couleur');
gui.add(light, 'intensity', 0, 5, 0.01);
</pre>
<p>Et voici 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/lights-ambient.html"></iframe></div>
<a class="threejs_center" href="/manual/examples/lights-ambient.html" target="_blank">cliquez ici pour ouvrir dans une fenêtre séparée</a>
</div>
<p></p>
<p>Cliquez et faites glisser dans la scène pour faire <em>orbiter</em> la caméra.</p>
<p>Remarquez qu'il n'y a pas de définition. Les formes sont plates. La <a href="/docs/#api/en/lights/AmbientLight"><code class="notranslate" translate="no">Lumière Ambiante</code></a>
multiplie simplement la couleur du matériau par la couleur de la lumière multipliée par l'
intensité.</p>
<pre class="prettyprint showlinemods notranslate notranslate" translate="no">color = materialColor * light.color * light.intensity;
</pre><p>C'est tout. Elle n'a pas de direction.
Ce style d'éclairage ambiant n'est pas très utile en tant qu'éclairage car il est
uniformément réparti, donc à part changer la couleur
de tout dans la scène, il ne ressemble pas beaucoup à un <em>éclairage</em>.
Ce qui aide, c'est qu'il rend les zones sombres moins sombres.</p>
<h2 id="-hemispherelight-"><a href="/docs/#api/en/lights/HemisphereLight"><code class="notranslate" translate="no">HemisphereLight</code></a></h2>
<p>Passons au code pour une <a href="/docs/#api/en/lights/HemisphereLight"><code class="notranslate" translate="no">Lumière Hémisphérique</code></a>. Une <a href="/docs/#api/en/lights/HemisphereLight"><code class="notranslate" translate="no">Lumière Hémisphérique</code></a>
prend une couleur de ciel et une couleur de sol et multiplie simplement la
couleur du matériau entre ces 2 couleurs — la couleur du ciel si la
surface de l'objet pointe vers le haut et la couleur du sol si
la surface de l'objet pointe vers le bas.</p>
<p>Voici le nouveau code</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">-const color = 0xFFFFFF;
+const skyColor = 0xB1E1FF; // light blue
+const groundColor = 0xB97A20; // brownish orange
const intensity = 1;
-const light = new THREE.AmbientLight(color, intensity);
+const light = new THREE.HemisphereLight(skyColor, groundColor, intensity);
scene.add(light);
</pre>
<p>Mettons également à jour le code lil-gui pour éditer les deux couleurs</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">const gui = new GUI();
-gui.addColor(new ColorGUIHelper(light, 'color'), 'value').name('color');
+gui.addColor(new ColorGUIHelper(light, 'color'), 'value').name('couleur du ciel');
+gui.addColor(new ColorGUIHelper(light, 'groundColor'), 'value').name('couleur du sol');
gui.add(light, 'intensity', 0, 5, 0.01);
</pre>
<p>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/lights-hemisphere.html"></iframe></div>
<a class="threejs_center" href="/manual/examples/lights-hemisphere.html" target="_blank">cliquez ici pour ouvrir dans une fenêtre séparée</a>
</div>
<p></p>
<p>Remarquez de nouveau qu'il n'y a presque pas de définition, tout semble un peu
plat. La <a href="/docs/#api/en/lights/HemisphereLight"><code class="notranslate" translate="no">Lumière Hémisphérique</code></a> utilisée en combinaison avec une autre lumière
peut aider à donner une belle influence de la couleur du
ciel et du sol. De cette façon, elle est mieux utilisée en combinaison avec une
autre lumière ou en substitut d'une <a href="/docs/#api/en/lights/AmbientLight"><code class="notranslate" translate="no">Lumière Ambiante</code></a>.</p>
<h2 id="-directionallight-"><a href="/docs/#api/en/lights/DirectionalLight"><code class="notranslate" translate="no">DirectionalLight</code></a></h2>
<p>Passons au code pour une <a href="/docs/#api/en/lights/DirectionalLight"><code class="notranslate" translate="no">Lumière Directionnelle</code></a>.
Une <a href="/docs/#api/en/lights/DirectionalLight"><code class="notranslate" translate="no">Lumière Directionnelle</code></a> est souvent utilisée pour représenter le soleil.</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">const color = 0xFFFFFF;
const intensity = 1;
const light = new THREE.DirectionalLight(color, intensity);
light.position.set(0, 10, 0);
light.target.position.set(-5, 0, 0);
scene.add(light);
scene.add(light.target);
</pre>
<p>Remarquez que nous avons dû ajouter la <code class="notranslate" translate="no">light</code> et la <code class="notranslate" translate="no">light.target</code>
à la scène. Une <a href="/docs/#api/en/lights/DirectionalLight"><code class="notranslate" translate="no">Lumière Directionnelle</code></a> three.js
brillera dans la direction de sa cible.</p>
<p>Faisons en sorte de pouvoir déplacer la cible en l'ajoutant à
notre interface GUI.</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">const gui = new GUI();
gui.addColor(new ColorGUIHelper(light, 'color'), 'value').name('couleur');
gui.add(light, 'intensity', 0, 5, 0.01);
gui.add(light.target.position, 'x', -10, 10);
gui.add(light.target.position, 'z', -10, 10);
gui.add(light.target.position, 'y', 0, 10);
</pre>
<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/lights-directional.html"></iframe></div>
<a class="threejs_center" href="/manual/examples/lights-directional.html" target="_blank">cliquez ici pour ouvrir dans une fenêtre séparée</a>
</div>
<p></p>
<p>Il est un peu difficile de voir ce qui se passe. Three.js dispose d'un ensemble
d'objets d'aide que nous pouvons ajouter à notre scène pour aider à visualiser
les parties invisibles d'une scène. Dans ce cas, nous utiliserons le
<a href="/docs/#api/en/helpers/DirectionalLightHelper"><code class="notranslate" translate="no">Helper de Lumière Directionnelle</code></a> qui dessinera un plan, pour représenter
la lumière, et une ligne de la lumière à la cible. Nous lui
passons simplement la lumière et l'ajoutons à la scène.</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">const helper = new THREE.DirectionalLightHelper(light);
scene.add(helper);
</pre>
<p>Pendant que nous y sommes, faisons en sorte de pouvoir définir à la fois la position
de la lumière et la cible. Pour ce faire, nous allons créer une fonction
qui, étant donné un <a href="/docs/#api/en/math/Vector3"><code class="notranslate" translate="no">Vector3</code></a>, ajustera ses propriétés <code class="notranslate" translate="no">x</code>, <code class="notranslate" translate="no">y</code>, et <code class="notranslate" translate="no">z</code>
en utilisant <code class="notranslate" translate="no">lil-gui</code>.</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">function makeXYZGUI(gui, vector3, name, onChangeFn) {
const folder = gui.addFolder(name);
folder.add(vector3, 'x', -10, 10).onChange(onChangeFn);
folder.add(vector3, 'y', 0, 10).onChange(onChangeFn);
folder.add(vector3, 'z', -10, 10).onChange(onChangeFn);
folder.open();
}
</pre>
<p>Notez que nous devons appeler la fonction <code class="notranslate" translate="no">update</code> de l'assistant
chaque fois que nous changeons quelque chose afin que l'assistant sache qu'il doit se mettre à
jour. Ainsi, nous passons une fonction <code class="notranslate" translate="no">onChangeFn</code> qui sera
appelée chaque fois que lil-gui met à jour une valeur.</p>
<p>Ensuite, nous pouvons l'utiliser à la fois pour la position de la lumière
et pour la position de la cible, comme ceci</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">+function updateLight() {
+ light.target.updateMatrixWorld();
+ helper.update();
+}
+updateLight();
const gui = new GUI();
gui.addColor(new ColorGUIHelper(light, 'color'), 'value').name('couleur');
gui.add(light, 'intensity', 0, 5, 0.01);
+makeXYZGUI(gui, light.position, 'position', updateLight);
+makeXYZGUI(gui, light.target.position, 'cible', updateLight);
</pre>
<p>Nous pouvons maintenant déplacer la lumière, et sa cible</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/lights-directional-w-helper.html"></iframe></div>
<a class="threejs_center" href="/manual/examples/lights-directional-w-helper.html" target="_blank">cliquez ici pour ouvrir dans une fenêtre séparée</a>
</div>
<p></p>
<p>Faites orbiter la caméra et il devient plus facile de voir. Le plan
représente une <a href="/docs/#api/en/lights/DirectionalLight"><code class="notranslate" translate="no">Lumière Directionnelle</code></a> car une lumière directionnelle
calcule la lumière venant dans une seule direction. Il n'y a pas de
<em>point</em> d'où la lumière provient, c'est un plan infini de lumière
émettant des rayons parallèles.</p>
<h2 id="-pointlight-"><a href="/docs/#api/en/lights/PointLight"><code class="notranslate" translate="no">PointLight</code></a></h2>
<p>Une <a href="/docs/#api/en/lights/PointLight"><code class="notranslate" translate="no">Lumière Ponctuelle</code></a> est une lumière qui se situe à un point et projette de la lumière
dans toutes les directions à partir de ce point. Modifions le code.</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">const color = 0xFFFFFF;
-const intensity = 1;
+const intensity = 150;
-const light = new THREE.DirectionalLight(color, intensity);
+const light = new THREE.PointLight(color, intensity);
light.position.set(0, 10, 0);
-light.target.position.set(-5, 0, 0);
scene.add(light);
-scene.add(light.target);
</pre>
<p>Passons également à un <a href="/docs/#api/en/helpers/PointLightHelper"><code class="notranslate" translate="no">Helper de Lumière Ponctuelle</code></a></p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">-const helper = new THREE.DirectionalLightHelper(light);
+const helper = new THREE.PointLightHelper(light);
scene.add(helper);
</pre>
<p>et comme il n'y a pas de cible, la fonction <code class="notranslate" translate="no">onChange</code> peut être plus simple.</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">function updateLight() {
- light.target.updateMatrixWorld();
helper.update();
}
-updateLight();
</pre>
<p>Notez qu'à un certain niveau, un <a href="/docs/#api/en/helpers/PointLightHelper"><code class="notranslate" translate="no">Helper de Lumière Ponctuelle</code></a> n'a pas de... point.
Il dessine simplement un petit losange en fil de fer. Cela pourrait tout aussi facilement
être n'importe quelle forme que vous souhaitez, il suffit d'ajouter un maillage à la lumière elle-même.</p>
<p>Une <a href="/docs/#api/en/lights/PointLight"><code class="notranslate" translate="no">Lumière Ponctuelle</code></a> a la propriété supplémentaire de <a href="/docs/#api/en/lights/PointLight#distance"><code class="notranslate" translate="no">distance</code></a>.
Si la <code class="notranslate" translate="no">distance</code> est 0, alors la <a href="/docs/#api/en/lights/PointLight"><code class="notranslate" translate="no">Lumière Ponctuelle</code></a> brille à
l'infini. Si la <code class="notranslate" translate="no">distance</code> est supérieure à 0, alors la lumière brille
à pleine intensité au niveau de la lumière et s'estompe jusqu'à ne plus avoir d'influence à
<code class="notranslate" translate="no">distance</code> unités de distance de la lumière.</p>
<p>Configurons l'interface GUI pour que nous puissions ajuster la distance.</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">const gui = new GUI();
gui.addColor(new ColorGUIHelper(light, 'color'), 'value').name('couleur');
gui.add(light, 'intensity', 0, 250, 1);
+gui.add(light, 'distance', 0, 40).onChange(updateLight);
makeXYZGUI(gui, light.position, 'position', updateLight);
-makeXYZGUI(gui, light.target.position, 'target', updateLight);
</pre>
<p>Et maintenant, essayez.</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/lights-point.html"></iframe></div>
<a class="threejs_center" href="/manual/examples/lights-point.html" target="_blank">cliquez ici pour ouvrir dans une fenêtre séparée</a>
</div>
<p></p>
<p>Remarquez quand <code class="notranslate" translate="no">distance</code> est > 0 comment la lumière s'estompe.</p>
<h2 id="-spotlight-"><a href="/docs/#api/en/lights/SpotLight"><code class="notranslate" translate="no">SpotLight</code></a></h2>
<p>Les projecteurs sont effectivement une lumière ponctuelle avec un cône
attaché où la lumière ne brille qu'à l'intérieur du cône.
Il y a en fait 2 cônes. Un cône extérieur et un cône intérieur.
Entre le cône intérieur et le cône extérieur, la
lumière s'estompe de la pleine intensité à zéro.</p>
<p>Pour utiliser une <a href="/docs/#api/en/lights/SpotLight"><code class="notranslate" translate="no">Projecteur</code></a>, nous avons besoin d'une cible, tout comme
pour la lumière directionnelle. Le cône de la lumière s'ouvrira
vers la cible.</p>
<p>En modifiant notre <a href="/docs/#api/en/lights/DirectionalLight"><code class="notranslate" translate="no">Lumière Directionnelle</code></a> avec l'assistant d'en haut</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">const color = 0xFFFFFF;
-const intensity = 1;
+const intensity = 150;
-const light = new THREE.DirectionalLight(color, intensity);
+const light = new THREE.SpotLight(color, intensity);
scene.add(light);
scene.add(light.target);
-const helper = new THREE.DirectionalLightHelper(light);
+const helper = new THREE.SpotLightHelper(light);
scene.add(helper);
</pre>
<p>L'angle du cône du projecteur est défini avec la propriété <a href="/docs/#api/en/lights/SpotLight#angle"><code class="notranslate" translate="no">angle</code></a>
en radians. Nous utiliserons notre <code class="notranslate" translate="no">DegRadHelper</code> de l'<a href="textures.html">article sur les textures</a>
pour présenter une interface utilisateur en
degrés.</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">gui.add(new DegRadHelper(light, 'angle'), 'value', 0, 90).name('angle').onChange(updateLight);
</pre>
<p>Le cône intérieur est défini en réglant la propriété <a href="/docs/#api/en/lights/SpotLight#penumbra"><code class="notranslate" translate="no">pénombre</code></a>
comme un pourcentage à partir du cône extérieur. En d'autres termes, quand <code class="notranslate" translate="no">penumbra</code> est 0, alors le
cône intérieur a la même taille (0 = aucune différence) que le cône extérieur. Quand la
<code class="notranslate" translate="no">penumbra</code> est 1, alors la lumière s'estompe en partant du centre du cône jusqu'au
cône extérieur. Quand <code class="notranslate" translate="no">penumbra</code> est 0,5, alors la lumière s'estompe en partant de 50 % entre
le centre du cône extérieur.</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">gui.add(light, 'penumbra', 0, 1, 0.01);
</pre>
<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/lights-spot-w-helper.html"></iframe></div>
<a class="threejs_center" href="/manual/examples/lights-spot-w-helper.html" target="_blank">cliquez ici pour ouvrir dans une fenêtre séparée</a>
</div>
<p></p>
<p>Remarquez qu'avec la <code class="notranslate" translate="no">penumbra</code> par défaut de 0, le projecteur a un bord très net,
tandis que lorsque vous ajustez la <code class="notranslate" translate="no">penumbra</code> vers 1, le bord devient flou.</p>
<p>Il peut être difficile de voir le <em>cône</em> du projecteur. La raison est qu'il est
en dessous du sol. Raccourcissez la distance à environ 5 et vous verrez l'extrémité ouverte
du cône.</p>
<h2 id="-rectarealight-"><a href="/docs/#api/en/lights/RectAreaLight"><code class="notranslate" translate="no">RectAreaLight</code></a></h2>
<p>Il existe un autre type de lumière, la <a href="/docs/#api/en/lights/RectAreaLight"><code class="notranslate" translate="no">Lumière Rectangulaire</code></a>, qui représente
exactement ce à quoi cela ressemble : une zone rectangulaire de lumière, comme un long
néon fluorescent ou peut-être une lucarne dépolie dans un plafond.</p>
<p>La <a href="/docs/#api/en/lights/RectAreaLight"><code class="notranslate" translate="no">Lumière Rectangulaire</code></a> ne fonctionne qu'avec les matériaux <a href="/docs/#api/en/materials/MeshStandardMaterial"><code class="notranslate" translate="no">MeshStandardMaterial</code></a> et
<a href="/docs/#api/en/materials/MeshPhysicalMaterial"><code class="notranslate" translate="no">MeshPhysicalMaterial</code></a>, nous allons donc changer tous nos matériaux en <a href="/docs/#api/en/materials/MeshStandardMaterial"><code class="notranslate" translate="no">MeshStandardMaterial</code></a></p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no"> ...
const planeGeo = new THREE.PlaneGeometry(planeSize, planeSize);
- const planeMat = new THREE.MeshPhongMaterial({
+ const planeMat = new THREE.MeshStandardMaterial({
map: texture,
side: THREE.DoubleSide,
});
const mesh = new THREE.Mesh(planeGeo, planeMat);
mesh.rotation.x = Math.PI * -.5;
scene.add(mesh);
}
{
const cubeSize = 4;
const cubeGeo = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize);
- const cubeMat = new THREE.MeshPhongMaterial({color: '#8AC'});
+ const cubeMat = new THREE.MeshStandardMaterial({color: '#8AC'});
const mesh = new THREE.Mesh(cubeGeo, cubeMat);
mesh.position.set(cubeSize + 1, cubeSize / 2, 0);
scene.add(mesh);
}
{
const sphereRadius = 3;
const sphereWidthDivisions = 32;
const sphereHeightDivisions = 16;
const sphereGeo = new THREE.SphereGeometry(sphereRadius, sphereWidthDivisions, sphereHeightDivisions);
- const sphereMat = new THREE.MeshPhongMaterial({color: '#CA8'});
+ const sphereMat = new THREE.MeshStandardMaterial({color: '#CA8'});
const mesh = new THREE.Mesh(sphereGeo, sphereMat);
mesh.position.set(-sphereRadius - 1, sphereRadius + 2, 0);
scene.add(mesh);
}
</pre>
<p>Pour utiliser la <a href="/docs/#api/en/lights/RectAreaLight"><code class="notranslate" translate="no">Lumière Rectangulaire</code></a>, nous devons inclure des données optionnelles supplémentaires de three.js et nous inclurons le
<a href="/docs/#api/en/helpers/RectAreaLightHelper"><code class="notranslate" translate="no">Helper de Lumière Rectangulaire</code></a> pour nous aider à visualiser la lumière</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">import * as THREE from 'three';
+import {RectAreaLightUniformsLib} from 'three/addons/lights/RectAreaLightUniformsLib.js';
+import {RectAreaLightHelper} from 'three/addons/helpers/RectAreaLightHelper.js';
</pre>
<p>et nous devons appeler <code class="notranslate" translate="no">RectAreaLightUniformsLib.init</code></p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">function main() {
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({antialias: true, canvas});
+ RectAreaLightUniformsLib.init();
</pre>
<p>Si vous oubliez les données, la lumière fonctionnera toujours mais elle aura un aspect étrange, alors
n'oubliez pas d'inclure les données supplémentaires.</p>
<p>Nous pouvons maintenant créer la lumière</p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">const color = 0xFFFFFF;
*const intensity = 5;
+const width = 12;
+const height = 4;
*const light = new THREE.RectAreaLight(color, intensity, width, height);
light.position.set(0, 10, 0);
+light.rotation.x = THREE.MathUtils.degToRad(-90);
scene.add(light);
*const helper = new RectAreaLightHelper(light);
*light.add(helper);
</pre>
<p>Une chose à noter est que, contrairement à la <a href="/docs/#api/en/lights/DirectionalLight"><code class="notranslate" translate="no">Lumière Directionnelle</code></a> et au <a href="/docs/#api/en/lights/SpotLight"><code class="notranslate" translate="no">Projecteur</code></a>, la
<a href="/docs/#api/en/lights/RectAreaLight"><code class="notranslate" translate="no">Lumière Rectangulaire</code></a> n'utilise pas de cible. Elle utilise simplement sa rotation. Une autre chose
à noter est que l'assistant doit être un enfant de la lumière. Il n'est pas un enfant de la
scène comme les autres assistants.</p>
<p>Ajustons également l'interface GUI. Nous allons faire en sorte de pouvoir faire pivoter la lumière et ajuster
sa <code class="notranslate" translate="no">width</code> et sa <code class="notranslate" translate="no">height</code></p>
<pre class="prettyprint showlinemods notranslate lang-js" translate="no">const gui = new GUI();
gui.addColor(new ColorGUIHelper(light, 'color'), 'value').name('couleur');
gui.add(light, 'intensity', 0, 10, 0.01);
gui.add(light, 'width', 0, 20);
gui.add(light, 'height', 0, 20);
gui.add(new DegRadHelper(light.rotation, 'x'), 'value', -180, 180).name('rotation x');
gui.add(new DegRadHelper(light.rotation, 'y'), 'value', -180, 180).name('rotation y');
gui.add(new DegRadHelper(light.rotation, 'z'), 'value', -180, 180).name('rotation z');
makeXYZGUI(gui, light.position, 'position');
</pre>
<p>Et voici cela.</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/lights-rectarea.html"></iframe></div>
<a class="threejs_center" href="/manual/examples/lights-rectarea.html" target="_blank">cliquez ici pour ouvrir dans une fenêtre séparée</a>
</div>
<p></p>
<p>Il est important de noter que chaque lumière que vous ajoutez à la scène ralentit la vitesse
de rendu de la scène par three.js, vous devriez donc toujours essayer d'en
utiliser le moins possible pour atteindre vos objectifs.</p>
<p>Ensuite, passons à <a href="cameras.html">la gestion des caméras</a>.</p>
<p><canvas id="c"></canvas></p>
<script type="module" src="../resources/threejs-lights.js"></script>
</div>
</div>
</div>
<script src="../resources/prettify.js"></script>
<script src="../resources/lesson.js"></script>
</body></html>