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 Избушка».

Волосы на геонодах ► 07. Добавление неровностей

Несмотря на то, что мы уже добавили волосам изгиб, в реальной жизни вряд ли можно встретить систему волос, в которой все волосы были бы изогнуты идеально ровно. Наша следующая задача - добавить волосам контролируемых неровностей.
Буду очень благодарен всем, кто решит поддержать проект материально. В данный момент это можно сделать только здесь, на Boosty, сделав разовый платёж или оформив спонсорскую подписку приемлемого для вас уровня (от 200 р. в месяц).
Да-да, по скриншоту вы могли заметить, что для этого мы будем использовать подключенный через 
кастомную систему координат нод Noise Texture, который мы, в частности, уже неоднократно использовали в серии Математика в 3Д. Напомню, что к настоящему моменту у нас в проекте есть нод-группы, регулирующие длину волосугол наклонаизгиб волоснастройки дочерних волос и толщину волос ↓
Для деформации волос нам понадобится нод Set Position. Обратите внимание, что мы подключаем его уже после нода Resample Curve, переопределяющего количество контрольных точек в каждом сплайне и после группы, определяющей изгиб волоса GN Hair Radius
Через поиск, либо через Shift+A > Textures > Noise Texture находим нод Noise Texture. Ссылку на урок с подробным описанием, как он работает и как настраивается, я давал выше ↓
Мы будем использовать его выход Color для параметра Offset в ноде Set Position. Конечно, не в чистом виде ↓
Если выход Fac возвращает дробные числовые значения шума для каждой точки пространства, то выход Color для каждой точки пространства генерирует индивидуальные дробные числовые значения яркости красного, зелёного и синего каналов цвета. И если мы будем использовать цветовую информацию - числовые значения яркости RGB каналов - в качестве значений XYZ, определяющих вектор сдвига точек, то для каждой оси будет использован свой паттерн шума. Это придаст неровностям больше рандомности.
Поскольку значения яркости цветов находятся в положительном диапазоне, условно, от 0 до 1, то сейчас сдвиг происходит относительно центра в одну сторону по каждой оси: вправо по Х, вперёд по Y и вверх по Z. Чтобы шум сдвигал значения в обе стороны по каждой оси, нужно вычесть из значений каждого канала цвета 0.5 с помощью Vector Math в режиме Subtract (вычитание). Тогда диапазон значений сместится с (0, 1) до (-0.5, 0.5), и сдвиг будет происходить во все стороны ↓
Регулировать размер добавляемых искажений мы можем с помощью настроек самой Noise Texture, у которой есть параметр Scale, а объём добавляемых искажений мы сможем регулировать при помощи Vector Math в режиме Scale (масштабирование), умножая получившийся вектор на число ↓
Чтобы неровности не затрагивали корни волос, и те оставались на своих местах, мы могли бы использовать нод Endpoint Selection для параметра Selection в ноде Set Position. Но Endpoint Selection определяет только количество точек с начала и с конца каждого сплайна, которые будут подвержены воздействию Set Position. Вместо этого я предлагаю использовать Factor из нода Spline Parameter, который генерирует на протяжении длины волоса значения от 0 до 1. Умножая вектор на 0 у корней волоса, мы будем нивелировать его влияние на корни, а к концам волос его влияние будет линейно возрастать, пока на конечной точке волоса не достигнет единицы ↓
Мы можем контролировать объём добавляемых на концах волос неровностей используя нод Math в режиме Multiply (умножение) для выхода Factor из нода Spline Parameter. А дополнительно используя перед ним нод Math в режиме Power (возведение в степень) мы сможем контролировать распространение неровностей по длине волоса ↓
Чем выше единицы будет значение Power, тем дальше от корней будут начинаться неровности, и чем ближе от единицы к нулю будет значение Power, тем воздействие неровностей будет смещаться ближе к корням. Это происходит потому, что мы возводим в степень значения Factor от 0 до 1. Возведение в степень больше единицы значений от 0 до 1 делает их меньше: 0.5 в квадрате равно 0.5 * 0.5 = 0.25, а 0.25 это меньше, чем 0.5. Или 0.1 * 0.1 = 0.01. При этом 1 * 1 = 1. Чем ближе исходное значение к нулю и чем выше степень, в которую оно возводится, тем меньше будет результирующее значение.
Таким образом, когда мы увеличиваем степень, те значения Factor, которые ближе к 0 или, иными словами, ближе к корням, становятся ещё меньше, а те которые ближе к 1, то есть к концу волоса, почти не затрагиваются. Возведение в степень от 1 до 0 даёт прямо противоположный результат. 0.25 в степени 0.5 (квадратный корень 0.25) равно 0.5, 0.16 в степени 0.2 = 0.4 и т.д. 
Добавим временные ноды Value для обозначения будущих входов в группу ↓
Сейчас в качестве системы координат для Noise Texture используется Position - то есть позиции контрольных точек. Потому что Position используется по умолчанию в качестве системы координат, если ко входу Vector не подключено ничего другого. Это означает, что если объект эмиттер будет деформироваться, например, с помощью скелетной арматуры, то волосы будут смещаться, позиции их контрольных точек будут смещаться, влияя на систему координат Noise Texture, и она во время движения начнёт искажать волосы непредсказуемым образом. Визуально это будет выглядеть, как если бы волосы проплывали в пространстве сквозь статичный паттерн шума. Чтобы этого избежать, нам понадобится собрать особую систему координат.
Компактизируем и реаранжируем ноды и добавим в качестве вектора нод Combine XYZ, с помощью которого будем определять по отдельности новые оси XYZ для Noise Texture ↓
Текстурные координаты, если мы вспомним, как они работают, генерируют для каждой рассматриваемой точки пространства числовые значения по осям X, Y и Z, которые потом используются в Noise Texture для расчёта результирующего значения для каждой точки (в шейдерах - для каждого пикселя на экране). Noise Texture "не знает" обо всех остальных точках пространства, вне тех точек, для которых она рассчитывается. Мало того, о них "не знают" ни система координат, ни сам Блендер, потому что для расчётов они не нужны. То есть для того, чтобы высчитать значения Noise Texture для контрольных точек сплайнов, для каждой контрольной точки должны быть заданы числовые значения по осям X, Y и Z. Это совершенно не обязательно должна быть их позиция, это могут быть любые три числовые значения. Мало того, эти значения вообще совершенно не обязательно должны меняться по всем трём осям на протяжении сплайна. Для того, чтобы Noise Texture начала генерировать трёхмерный шум, достаточно, чтобы значения текстурных координат на протяжении сплайна менялись вообще только по одной оси.
Дело в том, что несмотря на то, что мы видим сплайны волос в виде трубочек или, скорее, полосочек, постоянно разворачивающихся "лицом" к камере, у самих кривых, как таковых, объёма нет. Вся геометрия дорисовывается на волос уже поверх кривой, которая является просто направляющей. И если рассматривать сплайн волоса не как трёхмерный объект, а как одномерную последовательность контрольных точек, для каждой из которых нужно задать 3 значения, одно из которых должно меняться на протяжении сплайна, то мы можем взять тот же Factor из Spline Parameter и использовать его в качестве, назовём это так, активной координатной оси.
Однако, значение Factor рассчитывается одинаково для всех волос, и если использовать только его, а значения по остальным двум осям использовать одинаковые для всех сплайнов, то и шум будет генерироваться полностью одинаковым для всех волос. Чтобы шум отличался для каждого волоска, в качестве второй координаты мы можем взять индекс сплайна. А что, чем не число? Для каждого сплайна индекс является его идентификатором, и поэтому он уникален и не повторяется. Используя его в качестве второй координатной оси, мы для каждого волоска сдвинем шум достаточно далеко, чтобы он не повторялся.
Чтобы получить индекс сплайна, нам понадобится предварительно интерполировать домен. Добавим нод Interpolate Domain и переведём домен на Spline
Теперь, если мы подключим к нему в качестве параметра нод Index, то он будет возвращать поле, состоящее из индексов сплайнов. То есть для каждой точки каждого сплайна будет сгенерировано значение с индексом сплайна, которому эта точка принадлежит ↓ 
В качестве оси Y используем выход Factor из Spline Parameter ↓
Мало того, если использовать Noise Texture в режиме 3Д, у нас остаётся незадействованной ещё одна координатная ось - Z. Мы можем подключить  к ней временный Value и использовать его в качестве аниматора волос, плавно сдвигая с его помощью текстурные координаты шума и приводя таким образом волосы в движение ↓
Подготовим ноды к объединению в группу. Если вы хотите более точно контролировать параметры шума, можно добавить больше нодов Value, для каждого входа Noise Texture. Я считаю, что регулировки параметра Scale для этой цели вполне достаточно ↓ 
Объединяем выделенные ноды в группу с помощью Ctrl + G
Реорганизовываем для читаемости, переименовываем входы в N-панели и задаём минимальные, максимальные и дефолтные значения. Напоминаю, что для входа, регулирующего степень в Math > Power целесообразно ограничить минимальное значение 0.001, потому что возведение любого числа в нулевую степень возвращает единицу ↓
С помощью Tab выходим из группы, активируем значок щитка и переименовываем её в GN Hair Noise
Тестируем систему, проверяем, чтобы всё работало как задумано с разными сочетаниями настроек ↓ 
Поздравляю! Шестой элемент управления готов!
Вы видите эти уроки, благодаря тем, кто забирает их к себе на стенки, рассказывает друзьям, знакомым, в сообществах, пабликах, чатах, коммьюнити. Без такой поддержки развитие проекта было бы невозможным, и я благодарен каждому.
Выражаю большую благодарность спонсорам. Вы даёте мне возможность продолжать, а другим - бесплатно учиться.

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