Материалы

Эта статья является частью серии статей о 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.

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

Есть 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. Большинство приложений либо используют текстуры либо сплошной цвет для одного и того же материала, они редко переключаются с использования одного на использование другого.