# Matériaux

Cet article fait partie d'une série d'articles sur three.js. Le premier article est les bases de three.js. Si vous ne l'avez pas encore lu et que vous débutez avec three.js, vous pourriez vouloir commencer par là.

Three.js propose plusieurs types de matériaux. Ils définissent comment les objets apparaîtront dans la scène. Les matériaux que vous utilisez dépendent vraiment de ce que vous essayez d'accomplir.

Il existe 2 manières de définir la plupart des propriétés des matériaux. L'une au moment de la création, ce que nous avons déjà vu.

    const material = new THREE.MeshPhongMaterial({
      color: 0xFF0000,    // rouge (peut aussi utiliser une chaîne de couleur CSS ici)
      flatShading: true,
    });

L'autre est après la création

    const material = new THREE.MeshPhongMaterial();
    material.color.setHSL(0, 1, .5);  // rouge
    material.flatShading = true;

notez que les propriétés de type `THREE.Color` peuvent être définies de plusieurs manières.

    material.color.set(0x00FFFF);    // comme le style #RRGGBB de CSS
    material.color.set(cssString);   // n'importe quelle couleur CSS, par exemple 'purple', '#F32',
                                     // 'rgb(255, 127, 64)',
                                     // 'hsl(180, 50%, 25%)'
    material.color.set(someColor)    // une autre THREE.Color
    material.color.setHSL(h, s, l)   // où h, s et l sont de 0 à 1
    material.color.setRGB(r, g, b)   // où r, g et b sont de 0 à 1

Et au moment de la création, vous pouvez passer soit un nombre hexadécimal, soit une chaîne CSS

    const m1 = new THREE.MeshBasicMaterial({color: 0xFF0000});         // rouge
    const m2 = new THREE.MeshBasicMaterial({color: 'red'});            // rouge
    const m3 = new THREE.MeshBasicMaterial({color: '#F00'});           // rouge
    const m4 = new THREE.MeshBasicMaterial({color: 'rgb(255,0,0)'});   // rouge
    const m5 = new THREE.MeshBasicMaterial({color: 'hsl(0,100%,50%)'}); // rouge

Passons donc en revue l'ensemble des matériaux de three.js.

Le `MeshBasicMaterial` n'est pas affecté par les lumières.

Le `MeshLambertMaterial` calcule l'éclairage uniquement aux sommets, contrairement au `MeshPhongMaterial` qui calcule l'éclairage à chaque pixel. Le `MeshPhongMaterial` prend également en charge les reflets spéculaires.

Basique
Lambert
Phong
modèles low-poly avec les mêmes matériaux

Le paramètre `shininess` du `MeshPhongMaterial` détermine la brillance du reflet spéculaire. Par défaut, il est de 30.

shininess: 0
shininess: 30
shininess: 150

Notez que définir la propriété `emissive` sur une couleur pour un `MeshLambertMaterial` ou un `MeshPhongMaterial` et définir la `color` en noir (et `shininess` à 0 pour phong) finit par ressembler exactement au `MeshBasicMaterial`.

Basique
color: 'purple'
Lambert
color: 'black'
emissive: 'purple'
Phong
color: 'black'
emissive: 'purple'
shininess: 0

Pourquoi avoir les 3 alors que `MeshPhongMaterial` peut faire les mêmes choses que `MeshBasicMaterial` et `MeshLambertMaterial` ? La raison est que le matériau le plus sophistiqué nécessite plus de puissance GPU pour être dessiné. Sur un GPU plus lent, comme celui d'un téléphone portable, vous pourriez vouloir réduire la puissance GPU nécessaire pour dessiner votre scène en utilisant l'un des matériaux moins complexes. Il s'ensuit également que si vous n'avez pas besoin des fonctionnalités supplémentaires, utilisez le matériau le plus simple. Si vous n'avez pas besoin de l'éclairage et des reflets spéculaires, utilisez le `MeshBasicMaterial`.

Le `MeshToonMaterial` est similaire au `MeshPhongMaterial` avec une grande différence. Au lieu d'ombrer en douceur, il utilise une carte de dégradé (une texture de taille X sur 1) pour décider comment ombrer. Par défaut, il utilise une carte de dégradé dont la luminosité est de 70% pour les premiers 70% et de 100% ensuite, mais vous pouvez fournir votre propre carte de dégradé. Cela donne finalement un aspect bicolore qui ressemble à un dessin animé.

Ensuite, il y a 2 matériaux basés sur le rendu physique. Le Rendu Basé sur le Physique est souvent abrégé PBR.

Les matériaux ci-dessus utilisent des calculs simples pour créer des matériaux qui semblent en 3D, mais ils ne correspondent pas à ce qui se passe réellement dans le monde réel. Les 2 matériaux PBR utilisent des calculs beaucoup plus complexes pour se rapprocher de ce qui se passe réellement dans le monde réel.

Le premier est `MeshStandardMaterial`. La plus grande différence entre `MeshPhongMaterial` et `MeshStandardMaterial` est qu'il utilise différents paramètres. `MeshPhongMaterial` avait un paramètre `shininess`. `MeshStandardMaterial` a 2 paramètres : `roughness` et `metalness`.

À un niveau basique, `roughness` est l'opposé de `shininess`. Quelque chose qui a une rugosité élevée, comme une balle de baseball, n'a pas de reflets durs, tandis que quelque chose qui n'est pas rugueux, comme une boule de billard, est très brillant. La rugosité va de 0 à 1.

L'autre paramètre, `metalness`, indique à quel point le matériau est métallique. Les métaux se comportent différemment des non-métaux. 0 pour non-métal et 1 pour métal.

Voici un échantillon rapide de `MeshStandardMaterial` avec une `roughness` de 0 à 1 horizontalement et une `metalness` de 0 à 1 verticalement.

Le `MeshPhysicalMaterial` est le même que le `MeshStandardMaterial` mais il ajoute un paramètre `clearcoat` qui va de 0 à 1 pour déterminer la quantité de couche de vernis brillant à appliquer, et un paramètre `clearCoatRoughness` qui spécifie la rugosité de la couche brillante.

Voici la même grille de `roughness` par `metalness` que ci-dessus, mais avec les paramètres `clearcoat` et `clearCoatRoughness`.

Les différents matériaux standard progressent du plus rapide au plus lent : `MeshBasicMaterial` ➡ `MeshLambertMaterial` ➡ `MeshPhongMaterial` ➡ `MeshStandardMaterial` ➡ `MeshPhysicalMaterial`. Les matériaux plus lents peuvent créer des scènes plus réalistes, mais vous pourriez avoir besoin de concevoir votre code pour utiliser les matériaux plus rapides sur les machines à faible puissance ou les appareils mobiles.

Il existe 3 matériaux qui ont des utilisations spéciales. `ShadowMaterial` est utilisé pour obtenir les données créées par les ombres. Nous n'avons pas encore abordé les ombres. Lorsque ce sera le cas, nous utiliserons ce matériau pour jeter un coup d'œil à ce qui se passe en coulisse.

Le `MeshDepthMaterial` affiche la profondeur de chaque pixel où les pixels au `near` négatif de la caméra sont 0 et au `far` négatif sont 1. Certains effets spéciaux peuvent utiliser ces données, que nous aborderons ultérieurement.

Le `MeshNormalMaterial` vous montrera les normales de la géométrie. Les normales sont la direction vers laquelle pointe un triangle ou un pixel particulier. `MeshNormalMaterial` dessine les normales de l'espace de vue (les normales relatives à la caméra). x est rouge, y est vert, et z est bleu donc les choses orientées vers la droite seront roses, vers la gauche seront aqua, vers le haut seront vert clair, vers le bas seront violettes, et vers l'écran seront lavande.

`ShaderMaterial` sert à créer des matériaux personnalisés à l'aide du système de shaders de three.js. `RawShaderMaterial` sert à créer des shaders entièrement personnalisés sans aide de three.js. Ces deux sujets sont vastes et seront abordés plus tard.

La plupart des matériaux partagent un ensemble de paramètres tous définis par `Material`. Consultez la documentation pour les voir tous, mais passons en revue deux des propriétés les plus couramment utilisées.

`flatShading` : si l'objet semble facetté ou lisse. défaut = `false`.

flatShading: false
flatShading: true

`side` : quels côtés des triangles afficher. La valeur par défaut est `THREE.FrontSide`. Les autres options sont `THREE.BackSide` et `THREE.DoubleSide` (les deux côtés). La plupart des objets 3D dessinés dans three.js sont probablement des solides opaques, donc les faces arrière (les faces tournées vers l'intérieur du solide) n'ont pas besoin d'être dessinées. La raison la plus courante de définir `side` est pour les plans ou d'autres objets non solides où il est courant de voir les faces arrière des triangles.

Voici 6 plans dessinés avec `THREE.FrontSide` et `THREE.DoubleSide`.

side: THREE.FrontSide
side: THREE.DoubleSide

Il y a vraiment beaucoup de choses à considérer avec les matériaux et nous en avons encore beaucoup à voir. En particulier, nous avons largement ignoré les textures qui ouvrent tout un éventail d'options. Cependant, avant d'aborder les textures, nous devons faire une pause et configurer votre environnement de développement.

### material.needsUpdate

Ce sujet affecte rarement la plupart des applications three.js, mais juste pour information... Three.js applique les paramètres des matériaux lorsqu'un matériau est utilisé, où "utilisé" signifie "quelque chose qui est rendu utilise le matériau". Certains paramètres de matériau ne sont appliqués qu'une seule fois, car leur modification nécessite beaucoup de travail de la part de three.js. Dans ces cas, vous devez définir `material.needsUpdate = true` pour indiquer à three.js d'appliquer vos modifications de matériau. Les paramètres les plus courants qui nécessitent de définir `needsUpdate` si vous modifiez les paramètres après avoir utilisé le matériau sont :

- `flatShading`
- ajout ou suppression d'une texture

  Changer une texture est acceptable, mais si vous souhaitez passer de l'absence de texture à l'utilisation d'une texture, ou de l'utilisation d'une texture à l'absence de texture, alors vous devez définir `needsUpdate = true`.

  Dans le cas où l'on passe d'une texture à l'absence de texture, il est souvent simplement préférable d'utiliser une texture blanche de 1x1 pixel.

Comme mentionné ci-dessus, la plupart des applications ne rencontrent jamais ces problèmes. La plupart des applications ne basculent pas entre un ombrage plat et non plat. La plupart des applications utilisent également des textures ou une couleur unie pour un matériau donné ; elles basculent rarement de l'utilisation de l'un à l'utilisation de l'autre.