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

Математика в 3Д ► 13. Lens Flares. Лучи.

Продолжаем добавлять элементы к Lens Flares - бликам линзы. Сегодня добавим красивые, легко управляемые расходящиеся радиально лучи. О том, как настроен проект, я подробно рассказывал в прошлом уроке.
Буду очень благодарен всем, кто решит стать платными подписчиками или разово задонатить на означенные цели. Это сильно мотивирует на продолжение.
↑ Если кто-то в прошлый раз не увидел окончание урока, на всякий случай напомню, как выглядит после всех сокращений изнутри нод-группа, с помощью которой мы добавляем свечение.
🛈 Подробно мы собирали группу в прошлом уроке, сейчас просто схематично повторим, как она работает.
Vector Math > Scale (размер) управляет размером сферы. Чтобы Scale работал как увеличение размера, а не как увеличение системы координат, которое оказывает прямо противоположный эффект, перед использованием значения Size для Scale с помощью Math > Divide (деление) мы делим 1 на значение Size. Теперь Size воздействует на Scale обратно пропорционально, что нам и было нужно. Скорректированную таким образом входящую систему координат мы используем для Vector Math > Length (длина), которая показывает длину векторов системы координат в каждой точке пространства. В центре значения системы координат равны 0, длина их векторов, соответственно, тоже равна 0, поэтому в середине сфера черная. Ближе к краям значения системы координат, определяющие векторы, постепенно увеличиваются, длина векторов растёт, поэтому градиент к краям светлеет. Чтобы инвертировать эти значения и поменять чёрный и белый цвета местами мы используем Math > Subtract (вычитание) со включённой галочкой Clamp, которая все значения ниже 0 делает равными 0, а все значения выше 1 - равными 1. Таким образом мы не позволяем значениям проваливаться в отрицательную область и превышать единицу. После этого мы используем Math > Power (возведение в степень), чтобы контролировать огибающую градиента или, другими словами - распределение тёмных оттенков. Тёмные оттенки смещаются ближе к краям, когда экспонента (то, в какую степень возводятся значения) находится между 0 и 1, и ближе к центру - когда экспонента становится выше 1. После этого с помощью Math > Multiply (умножение), мы контролируем финальную яркость.  
↑ Так выглядит предварительная демонстрационная сборка из несколько раз продублированной с разными настройками нод-группы. Результаты перед окраской суммируются с помощью Math > Add (сложение). 
↑ Пока нам эта сборка не понадобится. Чтобы она не мешалась, мы её сейчас сдвинем, но чтобы потом можно было понять, что это единая система, объединим её в рамочку. Для этого сначала, удерживая Shift и правую кнопку мыши, проводим по фиолетовым линкам, чтобы объединить все текстурные координаты через точку Reroute. Затем выделяем точку, выделяем все ноды, кроме текстурных координат и выхода материала, и нажимаем Ctrl+J. Добавить ноды в рамочку можно, просто перенеся их на её поле, а исключить из рамочки - нажав Alt+P (как когда мы отпэрренчиваем объекты друг от друга). Опционально можно назвать рамочку в N-панели, во вкладке Node, в графе Label 
↑ Отключим рамочку от входящих и исходящих линков и сдвинем в сторону, чтобы не мешалась.
↑ Мы будем использовать ту же систему координат, что и раньше: Texture Coordinate > Object. Те, кто здесь с первого урока, могут помнить, что мы уже создавали лучи с помощью арктангенса осей X и Y. Там лучи были равноразмерные, и сейчас мы это исправим, но принцип остаётся тот же. Сначала разделяем систему координат на отдельные оси с помощью Convertor > Separate XYZ
↑ Затем добавляем Math > Arctan2 и подключаем к нему оси X и Y, чтобы пустить градиент со значениями от -Пи до Пи по часовой стрелке.
Для создания равноразмерных лучей мы использовали синус, предварительно умножив градент на значение, определявшее количество лучей. Чтобы сделать лучи более органичными, более рандомными, мы будем использовать Noise Texture, о настройках которой есть отдельный подробный урок. В обычных системах координат она представляет из себя текстуру, похожую на облачка, но представьте, что будет, если одну из координатных осей, на которых она строится, растянуть до бесконечности, умножить на 0? Получатся просто рандомные полосы, расположенные перпендикулярно другой оси.
Но мы также можем помнить, что координатные оси не обязательно должны быть прямыми, мы можем использовать в качестве системы координат любые градиенты, и паттерн текстуры будет распределяться между их тёмными и светлыми значениями. Поэтому мы вполне можем использовать полученный результат в качестве одной из осей.
🛈 Кто забыл/не знал/не понимает, о чём речь, есть отдельный подробный урок про векторные операции с текстурными координатами.
↑ Чтобы использовать полученный с помощью арктангенса результат в качестве координатной оси Х для Noise Texture, мы можем использовать нод Combine XYZ, который собирает три единичные числовые значения в вектор. Мы подаём полученный градиент на вход Х - и получаем рандомные лучи. Обратите внимание, что поскольку мы работаем с плэйном, то есть с плоскостью, у нас нет нужда использовать в Noise Texture все 3 измерения, что довольно сильно увеличивает нагрузку на производительность. В этом случае нам достаточно режима 2D.
↑ Напомню, что Noise Texture генерирует значения примерно от 0.25 до 0.75, поэтому чтобы нормализовать их, привести к диапазону от 0 до 1, которым проще управлять, мы сначала вычтем из её диапазона 0.25 с помощью Math > Subtract (вычитание), чтобы нижняя его граница оказалась на 0 (а верхняя на 0.5), а потом умножим на 2 с помощью Math > Multiply (умножение), чтобы растянуть диапазон вверх до 1.
↑ Чтобы контролировать огибающую лучей - сдвиг диапазона между 0 и 1 ближе к тёмным или светлым значениям - мы будем использовать Math > Power (возведение в степень). Он будет работать так же, как и в предыдущем уроке, когда мы его использовали для размытия границ сферы - только для каждого луча.
↑ Кстати, сфера из предыдущего урока нам сейчас тоже понадобится. Мы будем использовать её в качестве маски для обрезки краёв лучей, чтобы они постепенно затухали от центра к краям. Давайте подумаем или вспомним, с помощью какой математической операции нам объединить лучи с этой маской, чтобы светлые части лучей остались только в том месте, где сферическая маска тоже светлая. Помним, что чёрный - это 0, белый это 1. Что нам нужно сделать со значениями лучей и сферы: сложить, вычесть, умножить или разделить? О математических операциях над масками есть отдельный урок, но даже если вы его не проходили или забыли, попробуйте подумать сами.
🛈 Это типичная задача, с которой в работе сталкиваешься постоянно. Если не можете решить для всего градиента сразу, возьмите любые две точки - внутри сферы и вне сферы, и возьмите на них светлые части лучей или тёмные, прикиньте какие приблизительно в это месте числовые значения у градиента сферы, и какие значения у градиента лучей. И прямо как в школе - если мы к 0 прибавим 1... если мы 1 разделим на 1... и так далее. Нам нужно, чтобы там где сфера заканчивается, где тёмная часть, лучей не было. Итак - сложение, вычитание, умножение или деление? 
↑ Правильный ответ: умножение. Чёрный - это 0, а умножение на 0 любого числа даёт 0. Белый это 1, а умножение любого числа на 1 всегда даёт исходное число. Поэтому там, где сфера чёрная, все значения лучей будут обнуляться, там где в центре белая - будут оставаться оригинальными, а между центром и краями сферы, будут постепенно затухать, потому что значения градиента сферы, на которые мы умножаем значения градиента лучей, будут постепенно уменьшаться. С другой стороны, и сами лучи будут "прорезать" белую часть сферы, потому что в промежутках их значения также стремятся к нулю. Такие вещи очень важно понимать, чтобы научиться быстро и эффективно находить верные математические решения. Это просто типичнейшая задача.
↑ Однако, у нас возникает одна небольшая и, вероятно, для большинства случаев несущественная проблема, которую тем не менее, можно исправить: при низких значениях Scale в Noise Texture становится видна чёткая вертикальная линия разреза от центра вниз. Если вы отмотаете чуть вверх, на тот момент, где мы только подключили арктангенс, то увидите, что в этом месте как раз происходит разрыв градиента, он достигает своего максимального значения и резко обрывается обратно на минимальное значение.
К сожалению, с использованием той же текстуры это исправить не получится: можно отзеркалить координаты с помощью Math > Absolute, переводящим отрицательные значения в положительный диапазон, чтобы координатная ось плавно доходила до 0 и плавно возвращалась обратно, но в этом случае мы получим полностью симметричные лучи, а это ещё хуже, чем небольшой разрыв. Поэтому мы замаскируем этот разрыв с помощью дубликата текстуры.
↑ Полностью дублируем всё, что у нас уже есть. Нам нужно, чтобы на том месте, где у первой текстуры разрез, у её дубликата разреза не было, поэтому с помощью Vector > Mapping мы поворачиваем по оси Z координатную систему на 90 градусов. Мы могли бы развернуть её и сразу на 180 градусов, чтобы разрез оказался наверху, а не сбоку, но в таком случае может получиться элемент зеркальности. Поэтому, чтобы этого избежать, мы довернём разрез на оставшиеся 90 градусов, а заодно и изменим паттерн дубликата текстуры, поменяв местами оси X и Y на входе в арктангенс. 
↑ Из одного из арктангенсов сделаем маску с помощью Math > Absolute 
↑ Инвертируем её, вычтя из 1 с помощью  Math > Subtract. Не то чтобы это было обязательно, можно было бы позже, шагом ниже, просто поменять при миксе текстуры местами, но вычитание в плане ресурсоёмкости операция не дорогая, а мне так удобнее воспринимать, что я делаю.
↑ Используя полученную маску в качестве фактора, смешиваем между собой выходы из обеих Noise Texture c помощью собранной в прошлом уроке нод-группы Mix Values. Если у вас вместо того, чтобы разрез исчез, возникло два разреза, либо удаляем инвертирующий Subtract перед фактором, либо меняем местами текстуры, подключенные к Mix Values.
↑ Всю коррекцию, которую мы собирали для первой Noise Texture - нормализацию до диапазона от 0 до 1, коррекцию огибающей и микс со сферической маской теперь переносим после выхода из Mix Values
↑ Время объединить всё в группу. На этот раз просто объединим с помощью Shift и правой кнопки мыши векторные линки в Reroute, а предварительные значения  с помощью Value подключать не будем. Выделяем все ноды и Reroute.
↑ Нажимаем Ctrl+G, чтобы объединить всё в группу.
↑ Протягиваем из нижнего свободного входа в Group Input новые линки к параметрам, которыми нужно будет управлять снаружи, чтобы они сразу создавались правильного типа. Обратите внимание на следующие моменты.
• Мы создавали две Noise Texture только чтобы закрыть шов. Настройки у них должны регулироваться синхронно, поэтому сначала добавляем новые входы в группу, протягивая линки к одной из Noise Texture, а потом используем эти же входы для подключения к параметрам другой Noise Texture, чтобы когда снаружи эти значения будут меняться, они менялись у обоих текстур синхронно.
• Мы использовали в качестве текстурных координат только ось X, а в качестве осей Y и Z были просто нулевые значения. Это было в ноде Combine XYZ. Поскольку мы используем Noise Texture в режиме 2D, она использует только оси X и Y, а ось Z во входящих текстурных координатах игнорируется, и чтобы мы вместо неё не подключали, ничего не поменяется. А вот ось Y - это хоть и обнулённая, но вполне рабочая ось. И если мы будем менять её значение, мы будем как бы протягивать через неё плоскость оси X, таким образом шум будет постепенно меняться. И это можно очень эффективно использовать для анимации, чтобы у нас были не статичные лучи, а постепенно эволюционирующие. Для этого мы подключаем вход Y обоих нодов Combine XYZ в свободный вход - теперь мы сможем регулировать скорость анимации лучей снаружи группы, делая её разной для разных дублей лучей.
• Огибающая градиента для лучей будет регулироваться отдельным параметром, подключенным к Power, ближе к выходу из группы, а вот для яркости совершенно не обязательно добавлять дополнительный Multiply, мы можем использовать яркость сферической маски из группы Smooth Sphere. Ведь если яркость сферы в центре будет равна, например, 2, то те значения лучей, которые равнялись 1, будут перемножены со значениями сферы и также станут равными 2, то есть увеличат яркость, а те которые равнялись 0 останутся 0. Поэтому мы подключаем Emission из группы Smooth Sphere напрямую на вход нашей новой группы, и будем использовать в качестве яркости его, таким образом экономя одну лишнюю математическую операцию.
↑ Используя Ctrl+H, чтобы скрыть неиспользуемые входы/выходы и H, чтобы свернуть ноды, а также комбинацию клавиш S > X > 0, чтобы выровнять их по оси X, компактизируем ноды. В N-панели переназываем входы во что-то осмысленное, при необходимости устанавливаем для входов минимальные и максимальные значения и значения по умолчанию. Например, для регулировки огибающих с помощью Power минимальное значение имеет смысл выставить на 0.0001, чтобы оно не могло стать 0 и неожиданно засветить весь объект сплошным белым цветом (возведение числа в степень 0 даёт 1; математика, 7 класс).
↑ Выходим из группы с помощью Tab, переназываем её во что-то осмысленное и отражающее её суть, например - Rays (лучи), ставим значок щитка, чтобы Блендер её случайно не удалил при закрытии проекта. Не забываем засейвить и сам проект.
↑ Меняем настройки, смотрим, как работает созданная группа
↑ Ещё тесты, проверяем, как ведут себя параметры при значениях от 0 до 1, выше 1, ниже 0, при экстремально больших значениях, всё ли работает правильно и предсказуемо.
↑ В демонстрационных целях подключаем отключенную в начале урока рамочку обратно, дублируем новую группу с лучами несколько раз с разными настройками, и с помощью Math > Add (сложение) складываем результаты и прибавляем к результатам в рамочке.
↑ Вот так пока что выглядит наша сборка. В новичков такие картинки обычно вселяют хтонический ужас, но мы с вами уже понимаем, что большинство того, что мы здесь видим - это просто дубли одного и того же с разными настройками, и ничего страшного в них нет. 
Если вам нравятся эти уроки, поблагодарите, пожалуйста, хотя бы мысленно, тех, кто забирает их к себе на стенки, рассказывает о них друзьям, знакомым, в сообществах, пабликах, чатах, коммьюнити. Этих людей пока очень мало, но именно благодаря их действиям вы сейчас можете видеть эти уроки.
Со своей стороны выражаю большую благодарность спонсорам. Ваша поддержка даёт мне силы продолжать. И это не просто слова!
avatar
..."отпэрренчиваем"... Звучит как новый вариант знакомого матерного выражения.
Привет. Ссылка вначале поста на предыдущий урок не правильная.
avatar
Kirill Putchenko, спасибо, поправил )
avatar
Урок пушка, вот что получилось:
Все понятно и по делу. Уже появились мысли для некоторых своих эффектных текстур.

Subscription levels

1-й уровень

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

2-й уровень

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

3-й уровень

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

4-й уровень

$ 20,8 per month
4-й уровень

5-й уровень

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

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

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