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 : MeshBasicMaterialMeshLambertMaterialMeshPhongMaterialMeshStandardMaterialMeshPhysicalMaterial. 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.