# Материалы

Эта статья является частью серии статей о three.js. Первая была об основах. Если вы её еще не читали, советую вам сделать это.

Three.js предоставляет несколько типов материалов. Они определяют, как объекты будут появляться на сцене. Какие материалы вы используете, зависит от того, чего вы пытаетесь достичь.

Есть 2 способа установить большинство свойств материала. Один во время создания, который мы видели раньше.

    const material = new THREE.MeshPhongMaterial({
      color: 0xFF0000,    // red (можно также использовать css цвета)
      flatShading: true,
    });

Другой после создания

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

обратите внимание, что свойства типа `THREE.Color` могут быть установлены несколькими способами.

    material.color.set(0x00FFFF);    // так же, как в CSS #RRGGBB
    material.color.set(cssString);   // любой CSS цвет, например 'purple', '#F32',
                                     // 'rgb(255, 127, 64)',
                                     // 'hsl(180, 50%, 25%)'
    material.color.set(someColor)    // или другой THREE.Color
    material.color.setHSL(h, s, l)   // где h, s, и l от 0 до 1
    material.color.setRGB(r, g, b)   // где r, g, и b от 0 до 1

И во время создания вы можете передать либо шестнадцатеричное число либо строку CSS

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

прим. переводчика: Блик - световое пятно на ярко освещённой выпуклой или плоской глянцевой поверхности. Зеркальное отражение я часто буду называть бликом, хотя это скорее частный случай.

Итак, давайте рассмотрим набор материалов Three.js.

`MeshBasicMaterial` не зависит от света. `MeshLambertMaterial` вычисляет освещение только в вершинах vs, `MeshPhongMaterial` который вычисляет освещение в каждом пикселе и `MeshPhongMaterial` также поддерживающий блики.

Basic
Lambert
Phong
низкополигональные модели с теми же материалами

`shininess` устанавливает `MeshPhongMaterial` определяя блеск от бликов. Значение по умолчанию - 30.

shininess: 0
shininess: 30
shininess: 150

Обратите внимание, что установка светимости (`emissive` свойства) для цвета `MeshLambertMaterial` или `MeshPhongMaterial` и установка `color` в черный (и `shininess` в 0 для Фонга) в конечном итоге будет выглядеть как `MeshBasicMaterial`.

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

Зачем нам все 3, когда `MeshPhongMaterial` может делать то же самое, что `MeshBasicMaterial` и `MeshLambertMaterial`? Причина в том, что более сложный материал требует больше ресурсов графического процессора. На более медленном GPU, например, на мобильном телефоне, возможно, вы захотите уменьшить мощность графического процессора, необходимую для рисования вашей сцены, используя один из менее сложных материалов. Из этого также следует, что если вам не нужны дополнительные функции, используйте самый простой материал. Если вам не нужно освещение и блики, используйте `MeshBasicMaterial`.

`MeshToonMaterial` похож на `MeshPhongMaterial` с одной большой разницей. Вместо плавного затенения он использует карту градиента (текстуру размером X на 1) для выбора оттенка. По умолчанию используется карта градиента, яркость которой составляет 70% для первых 70% и 100% после, но вы можете предоставить свою собственную карту градиента. Это в конечном итоге дает 2 тона, которые выглядят как мультфильм.

Далее идут 2 физически обоснованных материала. Physically Based Rendering часто сокращается как PBR.

Приведенные выше материалы используют простую математику для создания материалов, которые выглядят трехмерными, но это не то, что происходит в реальности. 2 PBR материала используют гораздо более сложную математику, чтобы приблизиться к тому, что на самом деле происходит в реальном мире.

Первый - `MeshStandardMaterial`. Самая большая разница с `MeshPhongMaterial` и `MeshStandardMaterial` - использование различных параметров. У `MeshPhongMaterial` была `shininess` настройка. `MeshStandardMaterial` имеет 2 настройки `roughness` и `metalness`.

По простому шероховатость `roughness` это противоположность `shininess`. Что-то с высокой шероховатостью, например, баскетбольный мяч не имеет жестких отражений, а что-то не грубое, как бильярдный шар, очень блестящий. Шероховатость задается в интервале от 0 до 1.

Другая настройка - `metalness`. Она говорит о том, насколько металлический материал. Металлы ведут себя иначе, чем неметаллы, и поэтому этот параметр изменяется от 0 для не металла вообще, до единицы - 100% металла.

Вот краткий пример `MeshStandardMaterial` с `roughness` от 0 до 1 поперёк и `metalness` от 0 до 1 вниз.

`MeshPhysicalMaterial` же самое, что и `MeshStandardMaterial` но он добавляет `clearcoat` параметр, который идет от 0 до 1 для определения степени применения слоя глянцевого покрытия, и `clearCoatRoughness` параметр, который указывает, насколько шероховатым является слой глянца.

Вот та же сетка `roughness` по `metalness` как и до этого, но с `clearcoat` и `clearCoatRoughness`.

Различные стандартные материалы от самых быстрых к самым медленным: `MeshBasicMaterial` ➡ `MeshLambertMaterial` ➡ `MeshPhongMaterial` ➡ `MeshStandardMaterial` ➡ `MeshPhysicalMaterial`. Более медленные материалы могут создавать более реалистичные сцены, но вам может потребоваться писать дополнительный код, чтобы использовать более быстрые материалы на маломощных или мобильных устройствах.

Есть 3 материала, которые имеют специальное использование. `ShadowMaterial` используется для получения данных, созданных из теней. Мы еще не изучали тени. Когда мы это сделаем, мы будем использовать этот материал, чтобы оценить, что происходит за кулисами.

`MeshDepthMaterial` отрисовывает глубину каждого пикселя, где пиксели при отрицательном `near` камеры равны 0 и при отрицательном `far` равны 1. Некоторые специальные эффекты могут использовать эти данные , которые мы получим в в другое время.

The `MeshNormalMaterial` Покажет вам нормали геометрии. Нормали - это направление конкретного треугольника или грани пикселя. `MeshNormalMaterial` рисует пространство просмотра нормалей (нормали относительно камеры). x - красный, y - зеленый и z - синий, поэтому грани, направленные вправо, будут красного цвета, «вверх» - будут зеленого цвета, а к экрану будут синие.

`ShaderMaterial` предназначен для изготовления нестандартных материалов с использованием шейдерной системы three.js. `RawShaderMaterial` предназначен для создания полностью пользовательских шейдеров без помощи three.js. Обе эти темы большие и будут рассмотрены позже.

Большинство материалов имеют множество настроек, определенных `Material`. Посмотрите документацию по ним, и давайте рассмотрим два наиболее часто используемых свойства.

`flatShading`: выглядит ли объект граненным или гладким. По умолчанию = `false`.

flatShading: false
flatShading: true

`side`: какие стороны треугольников показать. По умолчанию = `THREE.FrontSide`. Другие варианты - `THREE.BackSide` и `THREE.DoubleSide` (с обеих сторон). Большинство трехмерных объектов, нарисованных в three, вероятно, являются непрозрачными твердыми телами, поэтому не нужно рисовать задние стороны (стороны, обращенные внутрь твердого тела). Наиболее распространенная причина установки `side`

- для плоскостей или других нетвердых объектов, где обычно видны задние стороны треугольников.

Вот 6 плоскостей с `THREE.FrontSide` и `THREE.DoubleSide`.

side: THREE.FrontSide
side: THREE.DoubleSide

С материалами действительно есть над чем поразмыслить, и нам еще многое предстоит сделать. Мы в основном игнорировали текстуры, которые открывают множество свойств. Прежде чем мы рассмотрим текстуры, мы должны сделать перерыв и обсудить настройку разрабочего окружения

### material.needsUpdate

Эта тема редко затрагивает большинство приложений three.js, но для общей информированности... Three.js применяет настройки материала, когда материал используется, где "используется" значит "что-то отрисовывается с использованием материала". Некоторые настройки материала применяются только один раз, так как их изменение требует много работы с three.js. В этих случаях вам нужно указать `material.needsUpdate = true` чтобы three.js применил ваши существенные изменения. Наиболее распространенные настройки, которые необходимо установить, `needsUpdate` если вы измените настройки после использования материала:

- `flatShading`
- добавление или удаление текстуры.

  Смена текстуры - это нормально, но если вы хотите переключиться с использования без текстуры на использование текстуры или с использования текстуры на использование без текстуры, то вам нужно установить `needsUpdate = true`.

  В случае перехода от текстуры к "без текстуры" часто просто лучше использовать белую текстуру 1x1 пикселей.

Как упоминалось выше, большинство приложений никогда не сталкиваются с этими проблемами. Большинство приложений не переключаются между flat shaded и не flat shaded. Большинство приложений либо используют текстуры либо сплошной цвет для одного и того же материала, они редко переключаются с использования одного на использование другого.