EN
Andrey Sokolov
Andrey Sokolov
730 subscribers
goals
21 of 500 paid subscribers
Когда я наберу 500 платных подписчиков, смогу больше времени уделять записи видео и разработке аддонов для Blender.
359.48 of $ 1 131 money raised
Донаты || Donates
37.45 of $ 566 money raised
Cделать аддон True Time Remapping бесплатным для всех желающих навсегда. Make True Time Remapping add-on free for everyone forever.
113.08 of $ 114 money raised
На дисковый накопитель 4Tb для хранения бэкапов курса «Blender Избушка».

Волосы на геонодах ► 04. Изгиб волос

В прошлых уроках мы подготовили проект, собрали нод-группы для регулировки длины и наклона волос. Следующая задача - регулировка изгиба волос.
Буду очень благодарен всем, кто решит поддержать проект материально. В данный момент это можно сделать только здесь, на Boosty, сделав разовый платёж или оформив спонсорскую подписку приемлемого для вас уровня (от 200 р. в месяц).     
ОБЩАЯ ИДЕЯ
Сейчас мы можем регулировать длину и наклон волос, но они продолжают расти линейно от начала к концу, по прямой ↓
Задача собрать нод-группу, с помощью которой можно было бы выгибать волос, таким образом, чтобы его начало и конец оставались на месте, а средняя часть отдалялась от поверхности объекта-эмиттера по широкой дуге, по направлению нормалей поверхности эмиттера ↓
Чтобы определить, насколько векторы нормалей будут сдвигать точки волоса, которые мы добавим в процессе, мы будем использовать Factor из нода Spline Parameter, который возвращает линейные значения от 0 до 1 на протяжении длины волоса, от его начала до конца. В начале волоса значение Factor равно 0, в конце 1. Но фактор нам будет нужен не в чистом виде, а модифицированный с помощью несложных математических операций таким образом, чтобы единица у него оказывалась не в конце, а в середине волоса, а на начале и в конце волоса был ноль. Так нормали будут максимально сдвигать точки ближе к середине, и оставлять нетронутыми конец и начало волоса ↓
Дополнительной задачей при конвертации фактора в нужные нам значения будет сделать плавающей середину, в которой значения фактора равны нулю, чтобы можно было точнее регулировать форму изгиба ↓ 
ПРАКТИЧЕСКАЯ РЕАЛИЗАЦИЯ
Чтобы сдвигать середины волос, нужно, чтобы в этих серединах у сплайнов волос были контрольные точки, потому что сейчас таких точек только две - начало и конец волоса. С помощью Resample Curve мы можем назначить любое количество точек для сплайнов волос, которые будут равномерно распределены от начала до конца каждого сплайна ↓
Обратите внимание, что по умолчанию Resample Curve переназначает количество точек не для отдельных сплайнов, а для объекта-кривых одновременно, целиком. Чтобы сдвигать точки, нам понадобится нод Set Position
Чтобы получить данные о нормалях объекта-эмиттера, нам понадобится нод Object Info, который мы сразу переключим на Relative и выберем в качестве объекта объект-эмиттер, у меня это Cube
Информацию о его нормалях мы можем получить, проведя её из объекта-эмиттера в виде атрибута с помощью Transfer Attribute. Переключим тип данных с Float на Vector, поскольку нормали - это векторы ↓
Подключим в качестве атрибута нод Normal
Мы планируем использовать фактор от 0 до 1 от начала до конца волоса в качестве множителя для вектора нормалей, которые будут в дальнейшем использованы для сдвига контрольных точек в середине волоса. Сам фактор мы можем получить в Spline Parameter, выход Factor, а умножить на него вектор мы можем при помощи Vector Math в режиме Scale (масштаб) ↓
Таким образом в начале каждого волоса вектор нормалей эмиттера умножается на 0, и постепенно к концу волоса это значение растёт до 1. То есть если сейчас подключить полученный вектор ко входу Offset в Set Position, то начала волос останутся на месте, а концы удалятся на 1 метр от поверхности эмиттера относительно своей прежней позиции. Средние точки линейно растянутся между началом и концом. Изгибать волосы на метр в наши задачи не входит, и чтобы регулировать, насколько сильно будет оказываться это воздействие на волос в целом, мы добавим ещё один Vector Math в режиме Scale ↓ 
Теперь нам нужно видоизменить фактор таким образом, чтобы его единица сместилась в центр, а ноль оказался по краям - на начале и на конце волоса. Можно было бы сделать это с помощью ColorRamp, сместив белый ползунок в центр и добавив ещё один чёрный ползунок справа, но у ColorRamp нет входящих параметров, которыми бы он управлялся, а значит, мы не сможем менять его настройки снаружи нод-группы, которую создадим, поэтому давайте подумаем, как это можно сделать при помощи математики. Тем более, что это не так сложно.
РАЗРАБОТКА
Есть несколько способов получить нужную формулу:
• Продумать всё в уме (у меня никогда не получается)
• Нарисовать на бумажке (часто самое эффективное)
• Использовать визуализацию (это как на бумажке, только сразу можно проверять на ошибки)
Мы воспользуемся третьим способом. Отложим временно модель с волосами в сторону, создадим простой плэйн из одного полигона и откроем Shader Editor вместо Геометрических Нодов. Математика - она и есть математика что там, что там. Мало того, в Блендер все ноды, связанные с математикой называются и работают одинаково во всех нодовых редакторах. И если мы соберём в Shader Editor систему, которая будет работать, как нам нужно, то перенести её в геоноды - дело пары минут. Но при этом в шейдерах её собирать проще, потому что мы можем сразу достоверно видеть, что мы делаем, а не угадывать, почему точки изгибаются не так, как мы думаем, что они должны бы ↓
Переключим вьюпорт в режим рендера и для начала сымитируем фактор, который мы получаем в Геометрических Нодах из Spline Parameter. Для этого возьмём Texture Coordinate, выход Generate, разделим его на отдельные оси и подключим ось Х к выходу материала ↓
О том, что такое текстурные координаты, как они работают и какие типы есть в Блендер, у меня есть подробный урок из другой серии, Математика в 3Д, которая в данный момент приостановлена из-за отсутствия к ней интереса у аудитории по непонятной мне причине. Вкратце, суть в том, что таким образом мы видим здесь репрезентацию числовых значений от 0 (чёрный цвет) в крайней левой части плэйна до 1 (белый цвет) в крайней правой части плэйна, и это в точности то же самое, что выдаёт на выходе Factor из Spline Parameter для каждого волоса, только визуализированное. Считайте, что это визуальная репрезентация числовых значений. Потому что это так и есть. Чтобы было ещё нагляднее, можно сжать плэйн по вертикали, чтобы он стал похож на схематическое изображение волоса ↓
Теперь нам нужно определить, в каком месте будет середина, до которой слева значения будут увеличиваться от 0 до 1, а после которой уменьшаться от 1 до 0. Чтобы наглядно увидеть, где будет находиться эта середина, мы можем использовать Math в режиме Greater Than (больше, чем). Его же мы в дальнейшем сможем использовать в качестве фактора смешивания двух вышеописанных диапазонов значений - от 0 до 1 и от 1 до 0 ↓
Для того, чтобы нам получить диапазон от 1 до 0 вместо от 0 до 1, нам нужно вычесть значения из единицы. Получается, 1-0=1, 1-1=0, таким образом, вместо 0 образуется 1, вместо 1 образуется 0, и дробные значения между ними точно так же меняются местами. Вычесть значения из 1 можно с помощью Math в режиме Subtract (вычитание) ↓ 
Ниже мы добавим временный нод Value - простое числовое значение, которое будет обозначать фактор в диапазоне от 0 до 1, определяющий середину отрезка, и установим его значение, например, на 0.4. Это значение мы будем использовать и для Greater Than, и, в инвертированном виде, в качестве делителя для инвертированного на прошлом шаге диапазона, чтобы сдвинуть у него единицу правее, ближе к центру, на отметку 0.4.
Поясню. Деля каждое значение от 0 до 1 на число меньше единицы, мы будем увеличивать их значения. На отметке 0.4 Greater Than разрезает диапазон пополам чуть левее центра. В этом месте значение инвертированного диапазона в исходном виде равно 1-0.4=0.6. Нам нужно, чтобы в том месте, где сейчас у инвертированного диапазона значение 0.6, оно стало равно 1, а на нуле осталось нулём. Чтобы это сделать, нам нужно все значения диапазона разделить на 0.6. По "счастливой случайности" это 0.6 мы как раз получаем, вычитая значение Value из 1.
«Как удобно!» (с)↓
↑ Ещё раз, что мы здесь делаем. Value временно заменяет вход в группу, обозначающий середину изгиба, это значение работает в диапазоне от 0 до 1. Оно будет использоваться, с одной стороны, как порог срабатывания для Greater Than, разделяющий отрезок на прямой и инвертированный диапазоны в середине изгиба. С другой стороны - в качестве числа, на которое мы будем делить с помощью Math > Divide (деление) прямой и инвертированный диапазоны, чтобы переместить их единицы с краёв волоса на середину изгиба. Поскольку, например, на отметке Value 0.4 значение инвертированного диапазона равно 1-0.4=0.6, и чтобы довести его в этом месте до единицы, его надо делить на 1-0.4=0.6, а не на 0.4, перед тем, как использовать для него Value, его также надо предварительно вычесть из 1 с помощью Math > Subtract (вычитание).  
С прямым, неинвертированным диапазоном всё проще: мы просто делим его на фактор с помощью Math > Divide
Обратите внимание, что поскольку в тех местах диапазона, которые оказываются выше значения Value при делении на Value значения будут выше 1, чтобы обрезать их до 1, в обоих Math > Divide активированы галочки Clamp
Компактизируем и реорганизуем ноды, разместим их в рамочках по смыслам: фактор (Fac), первый диапазон (Value 1), второй диапазон (Value 2), и используем нод Mix (бывший MixRGB) для смешивания. Greater Than используем в качестве фактора: слева от центра, где Greater Than возвращает чёрный цвет или ноль, будет использован первый диапазон значений (Value 1), а справа от центра, где Greater Than возвращает белый цвет или единицу, будет использован второй, инвертированный диапазон значений (Value 2) ↓
Меняя Value, мы будем передвигать центр изгиба, где значения диапазонов встречаются и равны единице, ближе к началу или концу волоса.
Нод Mix работает с цветами. Если ему на вход приходят простые числовые, а не цветовые значения, он сначала раскладывает эти значения по трём каналам - RGB, Red Green Blue (Красный, Зелёный, Синий), на каждом канале проводит операцию микса значений, и потом возвращает результат опять же в виде цвета, то есть тройного числового значения. Чтобы немного оптимизировать использование ресурсов компьютера, мы можем заменить этот нод на простейшие математические операции следующим образом ↓
↑ Первое значение мы умножаем с помощью Math > Multiply (умножение) на инвертированный  с помощью вычитания из единицы через Math > Subtract (деление) фактор и складываем с помощью Math > Add (сложение) со вторым значением, умноженным с помощью Math > Multiply (умножение) на фактор в чистом виде. Таким образом, когда фактор равен 0, второе значение умножается на 0 и становится нулём, а первое значение умножается на 1-0=1 и остаётся самим собой. При увеличении фактора первое значение умножается на всё меньшее, а второе - на всё большее значение, и таким образом постепенно одно значение заменяется на другое, пока фактор не станет равным единице, и они не поменяются местами.
Объединим всё, что касается микса, в отдельную группу с помощью Ctrl+G и компактизируем ноды ↓
Чтобы использовать в качестве фактора в этой группе такой же синий ползунок, что и в ноде Mix, добавим сначала в группу сам нод Mix
Подключим его значение Fac к свободному входу в группу, чтобы создался новый вход нужного типа ↓
В N-панели во вкладке Group, используя стрелочки, переместим его наверх и переподключим вместо того, что до этого использовалось в качестве фактора. Нод Mix больше не нужен, его можно удалить ↓
Поскольку нам будет необходимо, чтобы при любых условиях конец и начало волоса оставались на месте, нам нужно, чтобы в конце и в начале диапазона всегда был 0, для этого фактор никогда не должен становиться 0 или 1. Поэтому в N-панели в настройках входа назначим минимальное значение 0.001, а максимальное 0.999 ↓
Выйдем из группы с помощью Tab, активируем значок щитка, чтобы Блендер не удалил её при закрытии проекта, если она нигде не будет использована и назовём Mix Values
Будем считать, что алгоритм отрепетирован, и теперь нам нужно перенести его в Геометрические Ноды.
ПРОДОЛЖЕНИЕ ПРАКТИЧЕСКОЙ РЕЛИЗАЦИИ
К сожалению, несмотря на то, что и в Геометрических Нодах и в Редакторе Шейдеров с функциональной точки зрения используются одни и те же ноды, отвечающие за математику, типы самих редакторов всё же разные, и мы не можем просто скопировать то, что сделали в Shader Editor с помощью Ctrl+C и вставить в Geometry Node Editor с помощью Ctrl+V. Нам придётся всё переделать вручную. Но имея под рукой уже готовый собранный референс, повторить всё не составляет вообще никакой сложности. 
Разделим окно на две части в верхней нажмём иконку с "кнопкой" или "заколкой" - Pin, чтобы шейдер с нужным материалом оставался открытым даже при переключении активного объекта на другой. Переключим вьюпорт обратно в режим рендера Solid, выделим объект с волосами, снова переведём его в Sculpt Mode, чтобы не видеть оранжевой обводки, и переключим тип нижнего окна на Geometry Node Editor
Разберёмся, что здесь будет чем. Spline Parameter, выход Factor - будет тем же, чем в шейдере у нас была ось X текстурных координат - исходным диапазоном значений от 0 до 1. В качестве Value мы добавим в геоноды нод Value, и тоже выставим его значение, например, на 0.4, чтобы, опять же только для наглядности, слегка сдвинуть середину относительно центра ↓
Добавляем Math в режиме Greater Than (больше, чем), здесь он слегка отличается, но суть остаётся той же. В верхний слот подключаем диапазон, в нижний - Value
Первый диапазон у нас прямой, нам нужно просто разделить его на Value  с помощью Math > Divide (деление). Это будет первое значение для микса ↓
Для второго значения нам нужно использовать инвертированный диапазон, разделённый на инвертированный фактор. Инвертируем и фактор, и диапазон с помощью Math > Subtract (вычитание), вычтя их из 1 ↓
Делим инвертированный диапазон на инвертированный фактор с помощью Math > Divide (деление) ↓
Объединим всё в рамочки (Ctrl+J) по функциональной принадлежности, чтобы не запутаться, задать названия рамочкам можно в N-панели, вкладка Node
Теперь воссоздадим нод-группу Mix Values. Откроем её в Shader Editor и повторим схему, которую мы в ней собрали, в Geometry Node Editor
Подготовим собранную схему к добавлению в группу, компактизируем и реорганизуем ноды, объединим линки со значением фактора, используемым в нескольких нодах, с помощью точки Reroute, проведя зажатой  правой кнопкой мыши по объединяемым линкам и одновременно удерживая Shift 
Выделим ноды, относящиеся к миксу и точку Reroute, нажмём Ctrl+G
Провернём ту же операцию для использования в качестве фактора синего ползунка: добавим в группу нод Mix и подключим его вход Fac к свободному выходу в Group Input ↓ 
Передвинем новый вход вверх в N-панели, во вкладке Group, с помощью стрелочек. Переподключим к нему то, что идёт через точку Reroute, старый вход удалим, Mix удалим, новому входу назначим минимальное значение 0.001, максимальное 0.999 ↓
Выйдем с помощью Tab из группы, активируем щиток, переназовём группу GN Mix Values. Использовать сами группы из Shader Editor в Geometry Node Editor нельзя, но при этом пространство имён у всех нод-групп одно и то же, поэтому называть их одинаково мы не можем ↓ 
Подключим то, что получилось, в качестве множителя Scale
Теперь волосы изгибаются, но поскольку оба диапазона, и прямой, и инвертированный, возрастают линейно, сейчас изгиб получается в форме острого угла. Нашей следующей задачей будет этот угол сгладить, но перед этим реаранжируем ноды, чтобы они занимали минимум места и оставались читаемыми, а также с помощью нодов Value обозначим будущие входящие параметры группы ↓
Сгладить угол мы сможем с помощью Math в режиме Smooth Minimum (сглаженный минимум). Он возвращает минимальное значение своего первого и второго входа, но, в отличие от обычного Minimum, при приближении к пиковым значениям, результат сглаживается. Насколько далеко распространяется это сглаживание между значениями, определяет самый нижний параметр - Distance
Чтобы нам было удобно пользоваться сглаживанием в таком виде, мы можем в качестве второго значения использовать Value, вычтенное с помощью Math > Subtract из единицы, а само Value использовать в качестве Distance
Таким образом, получится, что пока Value (которое я в N-панели назвал Smooth), равно 0, второе значение равно 1-0=1, и поскольку значения обоих диапазонов не превышают 1, а алгоритм Minimum использует наименьшие значения, диапазоны оказываются всегда меньше 1 и используются на выходе в чистом виде; Distance при этом равно 0, то есть сглаживания значений не происходит. При добавлении Value, второе значение, приходящее в Smooth Minimum, становится меньше 1, и часть диапазонов из первого значения оказывается уже выше него и обрезается; при этом одновременно добавляется и Distance - дистанция сглаживания значений - и угол начинает сглаживаться. Таким образом получается, что чем больше разница между пиковыми значениями, тем больше добавляется сглаживания после обрезания, и тем плавнее будет получаться изгиб.
Система готова. Подготовим её к добавлению в группу: компактизируем ноды, объединим в рамочки по функциям, объединим линки общих параметров через точки Reroute, выделим всё, относящееся к изменению изгиба, включая Set Position, кроме нодов Value, Resample Curve, входов и выходов группы и ранее созданных групп↓
Объединим выделенное в группу с помощью Ctrl+G
В качестве фактора сглаживания и фактора, определяющего середину диапазона мы будем использовать факторы с синенькими полосками, для этого добавим в группу и подключим Mix для двух свободных входов (можно использовать один и тот же, но так нагляднее, мы их сейчас всё равно удалим) ↓
Один из добавленных входов переименуем в N-панели в Center, переместим на третью позицию, выставим минимальное значение 0.001, максимальное 0.999, переподключим к нему всё, что было подключено ко входу В, сам вход В и первый нод Mix удалим ↓
Переименуем второй новый вход в Smooth и используем его вместо Distance, лишнее удалим. Для регулировки сглаживания максимальное значение стоит делать от 0 до 0.75, иначе начнут затрагиваться начала и концы волос. На 0.75 это уже частично начинает происходить ↓
А вообще будет хорошим решением и для общего Scale использовать вход в виде фактора с голубым ползунком, потому что вряд ли когда-то понадобится изгибать середины волос на расстояние больше метра. Поэтому подключим в свободный вход Fac ещё одного нода Mix
Переназовём его Scale, переподключим к Vector Math > Scale, отвечающему за общий уровень добавления эффекта, Mix удалим ↓
И переместим этот вход наверх, старый удалим ↓ 
Выйдем с помощью Tab из группы, активируем щиток и назовём группу GN Hair Shape
Поздравляю! Третий элемент управления готов!
Вы видите эти уроки, благодаря тем, кто забирает их к себе на стенки, рассказывает друзьям, знакомым, в сообществах, пабликах, чатах, коммьюнити. Без такой поддержки развитие проекта было бы невозможным, и я благодарен каждому.
Выражаю большую благодарность спонсорам. Вы даёте мне возможность продолжать, а другим - бесплатно учиться.
avatar
avatar
Роман Федорков, выглядит как глюк драйверов видеокарты, скорее всего это он и есть. Блендер скачан с официального сайта? Драйвера у видеокарты обновлённые?
avatar
Это надоеда с ютуба)
avatar
Роман Федорков, да-да, я понял )))
avatar
Опечатка, 0,999 - должно быть.
avatar
Ivan Borodulin, спасибо, поправил. Боюсь, не единственная: на вычитку меня уже не хватало )

Subscription levels

1-й уровень

$ 2,27 per month
1-й уровень

2-й уровень

$ 5,7 per month
2-й уровень

3-й уровень

$ 11,4 per month
3-й уровень

4-й уровень

$ 22,7 per month
4-й уровень

5-й уровень

$ 57 per month
5-й уровень

Максимальная поддержка

$ 114 per month
Максимальная поддержка
Go up