8 янв. 2014 г.

Полосатый шейдер. Статья 1

Я запланировал написать цикл статей, посвещенных принципам создания процедурных полосатых шейдеров. Это первая статья цикла.

Довольно часто при текстурировании возникает необходимость использовать полосы и их комбинации. Удобнее всего манипулировать настройками подобных графических конструкций процедурно, с помощью редактора узлов материала.


Для начала предлагаю разобрать пример получения простейшей одинарной полосы с жесткими границами. В качестве тестового объекта будем использовать элементарную плоскость.


Материал статьи рассчитан на подготовленного пользователя Blender. Подразумевается, что читатель знаком с интерфейсом и владеет базовыми техниками.

1) Подготовка:
Назначаем плоскости UV-развертку. Метод Unwrap позволит получить развертку, повторяющую форму тестового объекта и покрывающую значения от 0 до 1 по вертикальной и горизонтальной оси.


Назначаем плоскости материал. Активируем узлы.

2) Рассмотрим схему шейдера:


В данном примере характеристики затенения нас интересовать не будут. По-этому выбираем тип шейдера Emision.

а) Для того чтобы получить полосу нам потребуются входные данные. Для этого будем использовать двухмерное UV-пространство, из которого вычленим одно из направлений U или V и визуализируем его. Для удобства, я всегда скрываю неиспользуемые гнезда узлов. В пункте (а) я использую узел Attribute. Чтобы, корректно визуализировать UV-пространство нужно использовать гамма-коррекцию со значением 2,2.

gamma 2,2

без гамма-коррекции

Такие несоответствия происходят из-за того, что хранение данных и операции вычисления производятся в линейном пространстве, а при выводе на экран необходимо производить преобразования из линейного пространства в sRGB. В рамках этой статьи я не буду останавливаться на принципах построения линейного рабочего процесса. Это материал для отдельного обсуждения.

б) Выбираем направление U. На выходе получается горизонтальный градиент. Для корректной визуализации опять используем узел Gamma.

gamma 2,2

без гамма-коррекции

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

в) Узел Value задает шаг смешения полосы вдоль горизонтального направления.

г) Само смещение вычисляется узлом Subtract.

д) Далее производим разветвление и обрабатываем значения меньше 0 узлом Less Than. Если изменять значения от 0 до -1 то можно регулировать левую границу полосы.

е) Узел Greater Than возвращает значения больше 0,1. Если изменять значения от 0,1 до 1 то можно регулировать правую границу полосы.

ж) В итоге суммируем результаты разветвления. Получаем полосу.

Хотя Blender поддерживает неявное преобразование типов данных, я придерживаюсь простого правила, позволяющего поддерживать порядок и достигать предсказуемых результатов. В Blender существует три типа данных: целые числа и числа с плавающей запятой (кодируются серым цветом), цвет RGB или RGBA (кодируются желтым цветом), векторы XY или XYZ (кодируются фиолетовым цветом). Соединяйте связями только совместимые гнезда узлов.

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

Ниже приведен пример версии шейдера из нескольких полос для различных видов поверхностей.


Как видно на изображении ниже, я скомпоновал настройки полос в группу. Теперь их можно многократно дублировать.


Так выглядят развертки тестовых объектов. Слева направо: UV-развертка полисферы и тора, пример расмещения UV-швов на торе.



striped_shader-1.blend

Желаю успехов.

4 комментария:

Unknown комментирует...

Полезная статья, спасибо!

Артур комментирует...

шейдер приложи, чувак

Unknown комментирует...

Артур, обязательно выложу, чуть позже. Готовлю.
Gleb Alexandrov, благодарю. Рад, что мой труд полезен другим людям.

Unknown комментирует...

Шейдер, выложил. Пользуйтесь.