# Brouillard

Cet article fait partie d'une série d'articles sur three.js. Le premier article est les fondamentaux de three.js. Si vous ne l'avez pas encore lu et que vous débutez avec three.js, vous devriez peut-être envisager de commencer par là. Si vous n'avez pas lu sur les caméras, vous voudrez peut-être commencer par cet article.

Le brouillard dans un moteur 3D est généralement une façon de s'estomper vers une couleur spécifique en fonction de la distance par rapport à la caméra. Dans three.js, vous ajoutez du brouillard en créant un objet `Fog` ou `FogExp2` et en le définissant sur la propriété `fog` de la scène.

`Fog` vous permet de choisir les paramètres `near` et `far` qui sont des distances par rapport à la caméra. Tout ce qui est plus proche que `near` n'est pas affecté par le brouillard. Tout ce qui est plus loin que `far` prend complètement la couleur du brouillard. Les parties entre `near` et `far` s'estompent de leur couleur de matériau à la couleur du brouillard.

Il y a aussi `FogExp2` qui augmente de manière exponentielle avec la distance par rapport à la caméra.

Pour utiliser l'un ou l'autre type de brouillard, vous en créez un et l'attribuez à la scène comme dans

    const scene = new THREE.Scene();
    {
      const color = 0xFFFFFF;  // white
      const near = 10;
      const far = 100;
      scene.fog = new THREE.Fog(color, near, far);
    }

ou pour `FogExp2` ce serait

    const scene = new THREE.Scene();
    {
      const color = 0xFFFFFF;
      const density = 0.1;
      scene.fog = new THREE.FogExp2(color, density);
    }

`FogExp2` est plus proche de la réalité mais `Fog` est utilisé plus couramment car il vous permet de choisir un endroit où appliquer le brouillard afin que vous puissiez décider d'afficher une scène claire jusqu'à une certaine distance, puis de s'estomper vers une couleur au-delà de cette distance.

THREE.Fog
THREE.FogExp2

Il est important de noter que le brouillard est appliqué aux choses qui sont rendues. Il fait partie du calcul de chaque pixel de la couleur de l'objet. Cela signifie que si vous voulez que votre scène s'estompe vers une certaine couleur, vous devez définir le brouillard et la couleur de fond sur la même couleur. La couleur de fond est définie à l'aide de la propriété `scene.background`. Pour choisir une couleur de fond, vous y attachez un `THREE.Color`. Par exemple

    scene.background = new THREE.Color('#F00');  // rouge

brouillard bleu, fond rouge
brouillard bleu, fond bleu

Voici l'un de nos exemples précédents avec l'ajout de brouillard. La seule addition est juste après la mise en place de la scène, nous ajoutons le brouillard et définissons la couleur de fond de la scène

    const scene = new THREE.Scene();

    +{
    +  const near = 1;
    +  const far = 2;
    +  const color = 'lightblue';
    +  scene.fog = new THREE.Fog(color, near, far);
    +  scene.background = new THREE.Color(color);
    +}

Dans l'exemple ci-dessous, `near` de la caméra est de 0.1 et `far` est de 5. La caméra est à `z = 2`. Les cubes mesurent 1 unité de large et sont à Z = 0. Cela signifie qu'avec un réglage de brouillard de `near = 1` et `far = 2`, les cubes s'estomperont juste autour de leur centre.

cliquez ici pour ouvrir dans une fenêtre séparée

Ajoutons une interface pour pouvoir ajuster le brouillard. Encore une fois, nous allons utiliser lil-gui. lil-gui prend un objet et une propriété et crée automatiquement une interface pour ce type de propriété. Nous pourrions simplement le laisser manipuler les propriétés `near` et `far` du brouillard, mais il est invalide d'avoir `near` supérieur à `far`, alors créons un assistant pour que lil-gui puisse manipuler une propriété `near` et `far`, mais nous nous assurerons que `near` est inférieur ou égal à `far` et que `far` est supérieur ou égal à `near`.

    // Nous utilisons cette classe pour la passer à lil-gui
    // ainsi quand elle manipule near ou far
    // near n'est jamais > far et far n'est jamais < near
    class FogGUIHelper {
      constructor(fog) {
        this.fog = fog;
      }
      get near() {
        return this.fog.near;
      }
      set near(v) {
        this.fog.near = v;
        this.fog.far = Math.max(this.fog.far, v);
      }
      get far() {
        return this.fog.far;
      }
      set far(v) {
        this.fog.far = v;
        this.fog.near = Math.min(this.fog.near, v);
      }
    }

Nous pouvons ensuite l'ajouter comme ceci

    {
      const near = 1;
      const far = 2;
      const color = 'lightblue';
      scene.fog = new THREE.Fog(color, near, far);
      scene.background = new THREE.Color(color);
    +
    +  const fogGUIHelper = new FogGUIHelper(scene.fog);
    +  gui.add(fogGUIHelper, 'near', near, far).listen();
    +  gui.add(fogGUIHelper, 'far', near, far).listen();
    }

Les paramètres `near` et `far` définissent les valeurs minimum et maximum pour l'ajustement du brouillard. Ils sont définis lorsque nous configurons la caméra.

Le `.listen()` à la fin des 2 dernières lignes indique à lil-gui d'écouter les changements. De cette façon, lorsque nous changeons `near` à cause d'une modification de `far` ou que nous changeons `far` en réponse à une modification de `near`, lil-gui mettra à jour l'interface utilisateur de l'autre propriété pour nous.

Il pourrait également être agréable de pouvoir changer la couleur du brouillard, mais comme mentionné ci-dessus, nous devons synchroniser la couleur du brouillard et la couleur de fond. Ajoutons donc une autre propriété virtuelle à notre assistant qui définira les deux couleurs lorsque lil-gui la manipulera.

lil-gui peut manipuler les couleurs de 4 manières : comme une chaîne hexadécimale CSS à 6 chiffres (par exemple : `#112233`). Comme un objet teinte, saturation, valeur (par exemple : `{h: 60, s: 1, v: }`). Comme un tableau RGB (par exemple : `[255, 128, 64]`). Ou, comme un tableau RGBA (par exemple : `[127, 200, 75, 0.3]`).

Le plus simple pour notre objectif est d'utiliser la version chaîne hexadécimale, car de cette façon, lil-gui ne manipule qu'une seule valeur. Heureusement, `THREE.Color` dispose d'une méthode `getHexString` que nous pouvons utiliser pour obtenir facilement une telle chaîne, il suffit de faire précéder d'un '#' au début.

    // Nous utilisons cette classe pour la passer à lil-gui
    // ainsi quand elle manipule near ou far
    // near n'est jamais > far et far n'est jamais < near
    // Aussi, lorsque lil-gui manipule la couleur, nous allons
    // mettre à jour les couleurs du brouillard et de l'arrière-plan.
    class FogGUIHelper {
    *  constructor(fog, backgroundColor) {
        this.fog = fog;
    +    this.backgroundColor = backgroundColor;
      }
      get near() {
        return this.fog.near;
      }
      set near(v) {
        this.fog.near = v;
        this.fog.far = Math.max(this.fog.far, v);
      }
      get far() {
        return this.fog.far;
      }
      set far(v) {
        this.fog.far = v;
        this.fog.near = Math.min(this.fog.near, v);
      }
    +  get color() {
    +    return `#${this.fog.color.getHexString()}`;
    +  }
    +  set color(hexString) {
    +    this.fog.color.set(hexString);
    +    this.backgroundColor.set(hexString);
    +  }
    }

Nous appelons ensuite `gui.addColor` pour ajouter une interface utilisateur de couleur pour la propriété virtuelle de notre assistant.

    {
      const near = 1;
      const far = 2;
      const color = 'lightblue';
      scene.fog = new THREE.Fog(color, near, far);
      scene.background = new THREE.Color(color);

    *  const fogGUIHelper = new FogGUIHelper(scene.fog, scene.background);
      gui.add(fogGUIHelper, 'near', near, far).listen();
      gui.add(fogGUIHelper, 'far', near, far).listen();
    +  gui.addColor(fogGUIHelper, 'color');
    }

cliquez ici pour ouvrir dans une fenêtre séparée

Vous pouvez voir que régler `near` à environ 1.9 et `far` à 2.0 donne une transition très nette entre non-brouillardé et complètement brouillardé. tandis que `near` = 1.1 et `far` = 2.9 devraient être à peu près les plus lisses étant donné que nos cubes tournent à 2 unités de distance de la caméra.

Une dernière chose, il existe une propriété booléenne `fog` sur un matériau indiquant si les objets rendus avec ce matériau sont affectés par le brouillard. Elle est par défaut à `true` pour la plupart des matériaux. À titre d'exemple de pourquoi vous pourriez vouloir désactiver le brouillard, imaginez que vous créez un simulateur de véhicule 3D avec une vue depuis le siège du conducteur ou le cockpit. Vous voudrez probablement désactiver le brouillard pour tout ce qui se trouve à l'intérieur du véhicule lorsque vous regardez depuis l'intérieur du véhicule.

Un meilleur exemple pourrait être une maison et un brouillard épais à l'extérieur. Disons que le brouillard est configuré pour commencer à 2 mètres de distance (`near` = 2) et complètement brouillardé à 4 mètres (`far` = 4). Les pièces sont plus longues que 2 mètres et la maison est probablement plus longue que 4 mètres, vous devez donc régler les matériaux de l'intérieur de la maison pour ne pas appliquer de brouillard, sinon, en vous tenant à l'intérieur de la maison et en regardant dehors le mur au fond de la pièce, cela aura l'air d'être dans le brouillard.

brouillard : vrai, tout

Remarquez que les murs et le plafond au fond de la pièce sont affectés par le brouillard. En désactivant le brouillard sur les matériaux de la maison, nous pouvons corriger ce problème.

brouillard : vrai, seulement les matériaux extérieurs