Уроки: Общие принципы

Создание RenderMan (RSL) и Mantra (VEX) шэйдеров в Houdini

1. Введение

2. Surface шэйдеры - шэйдеры поверхности

3. Displace шэйдеры - шэйдеры смещения геометрии

4. Volume шэйдеры - шэйдеры объема

5. Light шэйдеры - шэйдеры света

6. Заключение/Список литературы

 

Введение

Несмотря на то, что за последние пару лет популярность Houdini среди русскоязычного населения заметно выросла, этот пакет для многих так и остаётся чем-то таинственным и загадочным, но, несомненно, очень крутым. Это происходит во многом потому, что для работы в нем часто требуются знания, неочевидно связанные непосредственно c Houdini.
Поэтому, просьба людей, впервые коснувшихся данной тематики, не удивляться тому, что в уроке о создании шэйдеров в Houdini речь по большему счёту пойдёт о RenderMan.
Две основные причины:
- архитектура Houdini ориентирована на работу с RenderMan-совместимыми рендерами;
- встроенный в Houdini рендер Mantra фактически является клоном RenderMan и бóльшая часть сведений о RenderMan так же справедлива и для Mantra.

RenderMan – стандарт описания трёхмерных данных для визуализации фотореалистичных изображений, разработан в 1987 году компанией PIXAR. RenderMan описывает компьютеру всё, что необходимо знать для рендеринга: трёхмерные объекты, источники света, камеры и т.д. Изначально RenderMan разрабатывался как интерфейс между любой программой моделирования и анимации и любой программой рендеринга.
Воплощением этого стандарта стала созданная PIXAR программа PhotoRealistic renderman – PRman, и, поскольку в дальнейшем далеко не все программы для рендеринга основывались на стандарте от PIXAR, многие стали отождествлять RenderMan и PRman, считая RenderMan рендерером. Несмотря на то, что RenderMan не стал стандартным интерфейсом для всех программ, было создано достаточно много RenderMan-совместимых программ (BMRT, 3Delight, Aqsis, PIXIE) и RenderMan-клонов (Gelato, Mantra).

Официальный сайт Pixar
Фильмография PRman

Несмотря на то, что в последнее время появилось множество современных решений использующих самые прогрессивные методы просчёта фотореалистичных изображений, построенных на технологиях raytrasing или pathtrasing, RenderMan является промышленным стандартом создания компьютерной графики и используется в большинстве продакшен студий на крупных и дорогих проектах.
Основные причины этого - скорость и гибкость.
За скорость в RenderMan отвечает техническая реализация в программах рендеринга (PRman, 3Delight, PIXIE) качественного и быстрого дисплэйсмента, эффектов Antiаliasing, Motion Blur, Depth of field. Технологии, оттачивающиеся уже более двух десятков лет, позволяют работать с огромным количеством данных эффективно используя ресурсы.
Гибкость – это в основном RSL – язык написания шэйдеров, который позволяет расширять возможности программы и добиваться получения практически любого необходимого эффекта.

Изучение данной тематики требует базовых знаний математики (курс начальной школы + немного тригонометрии и векторной алгебры), а так же знание основ программирования на C-подобных языках. И то и другое в общих чертах будет рассмотрено по мере возникновения необходимости. В заключении приведён список литературы, сайтов и форумов из которых можно получить более подробную информацию.

Важно: Данный урок требует некоторого знакомства с основными понятиями интерфейса Houdini:

Как работает RenderMan.

Принцип работы связки RenderMan рендер - программа для моделирования/анимации (пайплайн) выглядит так:

схема 1

В программе для моделирования и анимации создаётся сцена. Объекты, источники света и камера, а также параметры сцены (разрешение конечного изображения, сэмплинг и прочие настройки рендера, назначенные шэйдеры и пути к текстурам) экспортируются в RIB-архив. Фактически RIB это фомат файла-сцены RenderMan. Дальнейший процесс выполняет программа-рендер
- считывает данные из RIB,
- удаляет лишние объекты, которые не попадают в область просчёта,
- выполняет вычисления displace шэйдеров
- удаляет невидимые участки поверхности
- выполняет вычисления surface и volume шэйдеров
- выдаёт финальную картинку.

Удобство работы во многом зависит от того как реализована интеграция интерфейса RenderMan в программе моделирования. Houdini, в отличие от других программ, в которых требуются плагины или скрипты для экспорта данных в RenderMan, разработана для работы с RenderMan-совместимыми рендерами, поэтому она не только имеет возможность экспортировать свои данные в RIB, но также на этапе создания сцены оперировать RenderManовскими примитывами и имеет интегрированную визуальную среду разработки VEX-builder, которую мы будем использовать для создания шэйдеров.

Так как мы будем использовать учебную версию Houdini которую можно скачать здесь, то рендерить примеры шэйдеров будем в Mantra (учебная версия не позволяет использовать внешние рендеры).
Mantra – клон RenderManа, но не RenderMan-совместимый  рендер, и, несмотря на всю их похожесть некоторые различия всё же есть. Поэтому каждый пример будет рассматриваться как для RenderMan так и для Mantra.

Замечание: Шэйдеры для RenderMan пишутся на RSL, для Mantra на VEX. Это разные языки, но они имеют много общего. Во избежание путаницы, в дальнейшем говоря "шэйдеры для RenderMan" я подразумеваю RSL, "шэйдеры для Mantra" - соответственно VEX.

VEX-builber.

VEX

VEX-builder, при всей своей внешней похожести не является аналогом Hypershade в maya, Render tree в XSI или PIXAR Slim. VEX-builder - это инструмент программирования, который представляет переменные, функции и математические операции в виде нод. В таком подходе к созданию шэйдеров есть как достоинства так и недостатки.
Достоинства:
- наглядное представление данных
- создание шэйдера происходит отдновременно с созданием его графического интерфейса
- часто используемые функции и целые сети из узлов можно собирать в один хранящийся на жёстком диске узел (Digital asset) и использовать в дальнейшем как используются готовые шэйдеры в Hypershade или Slim
- компиляция шэйдеров производится средствами самого Houdini
- есть возможность использовать глобальные переменные Houdini и с самого начала разработки использовать возможности процедурной анимации, а так же использовать шэйдеры как контент для Digital Asset'ов.

К недостаткам можно отнести то, что для многих, знакомых с программированием, пользователей Houdini будет проще и быстрее написать код в виде текста. Но в тоже время VEX-builder позволяет использовать текстовый код  – для этого есть нода Inline Code.

Что такое шэйдер.

Шэйдер - это программа, которая получает входные данные, обрабатывает их и возвращает некоторый результат. В RenderMan программы-шэйдеры  запускаются во время редеринга и, обрабатывая данные хранящиеся в RIB, закрашивают поверхности или смещают их.
Когда рендерер просчитывает пиксель, он выпускает луч из этого пикселя, и там где луч пересекает поверхность, рендер вызывает соответствующие шейдеры для вычисления цвета пикселя. И так этот процесс повторяется для каждого пикселя, составляющего картинку.
Шейдеры работают с набором данных из сцены, называемым глобальными переменными, которые содержат определенную информацию, такую как точка пересечения луча с поверхностью или положение камеры. Такие переменные могут содержать в себе разные значения для разных точек поверхности.
Рисунок показывает процесс, происходящий после испускания луча в точку поверхности. Обратите внимание на глобальные переменные (P, N, и.т.д.) и на их направления.

scheme2

В Houdini можно создавать 4 основных типа рендераман шэйдеров:

Surface – шэйдеры поверхности – вычисляют цвет и прозрачность поверхности (в Mantra ещё альфа и нормаль).
Displace – шэйдеры, вычисляющие положение точки поверхности, изменяющие геометрию – вычисляют положение точки и направление нормали в этой точке.
Volume – шэйдеры объёма – вычисляют цвет и прозрачность точки пространства (используются для атмосферных эффектов).
Light – шйэдеры света – отвечают за направление, цвет и интенсивность источников освещения.

Так же в Mantra есть ещё отдельные типы шэйдеров для теней и фотонов.

Шэйдеры для RenderMan пишутся на RSL – языке написания шэйдеров – очень похожем на С. VEX, на котором пишутся шэйдеры Mantra вцелом аналогичен RSL но имеет некотрые отличия в названиях функций и типах данных.

Код шэйдера представляет из себя следующее:

тип_шейдера имя_шейдера (
тип_параметра имя_параметра1 = значение_по_умолчанию1;
тип_параметра имя_параметра2 = значение_по_умолчанию2,            
имя_параметра3 = значение_по_умолчанию3;
тип_параметра имя_параметра4 = значение_по_умолчанию4
)
{
тип_переменной имя_переменной1 = значение_переменной1;
тип_переменной имя_переменной2,
имя_переменной3 = значение_переменной3;

           оператор__основного_кода;
имя_переменной2 = значение_переменной2;
оператор__основного_кода;
оператор__основного_кода;

           /* комментарий
комментарий
комментарий */

           код_возврата_значения;
код_возврата_значения;

Первая секция одержит тип (surface, light, displacement или volume), имя шэйдера и, в скобках, входные данные. Фигурными скобками ограничивается «тело» программы. В конце программа должна вернуть значения соответствующие типу шэйдера - обычно для этого нужно присвоить эти значения специальным переменным.

 

2. Surface шэйдеры

scheme

Surface шэйдеры предназначены для вычисления цвета и прозрачности текущей просчитываемой точки, определяемых переменными Oi и Ci.
Глобальные переменные используемые в Surface шэйдерах:

GV

Cs, Os - переменные, содержащие цвет и прозрачность указанные пользователем при объявлении шэйдера в RIB файле

P - координата точки поверхности
dPdu, dPdv - "направления" поверхности
N, Ng - нормаль шэйдинга, и геометрическая нормаль
u,v - UV координаты
du, dv - изменение координат U и V
s,t - аналог UV координат для параметрических поверхностей
E - точка положения камеры
I - вектор, направленный от камеры к точке
Ci, Oi - переменные цвета и прозрачности которым присваивается результат работы шэйдера

С небольшими отличиями в названии те же переменные можно найти в шэйдере для Mantra:

VEX

Откройте Нoudini.
Удерживая клавишу Ctrl щелкните кнопку Sphere на полке Create в центре сцены появится примитив сфера. Оставьте её настройки по умолчанию.
Тип поверхности Primitive

обозначает, что поверхность объекта не строится из патчей или полигонов, а является параметрической , т.е. задаётся математической функцией, поэтому на рендере сфера будет идеально гладкой при любом приближении.
Затем установите камеру в положение, откуда будет светить лампочка. Нажмите с Ctrl на кнопку Point Light на полке Lights and Cameras – источник света появится в месте текущего положения камеры
Нажав на эту кнопку

Можно управлять источником света как камерой. Нажмите на эту кнопку ещё раз чтобы продолжить работать с обычной перспективной проекцией.
В принципе сцена готова – теперь для проверки работы шэйдера будем назначать его на эту сферу, смотреть на неё с разных сторон, а чтобы не забивать голову настройками рендера – рендерить кнопкой быстрого рендера в нижнем левом углу:

Рендериться будет в Mantra из текущего вида во вьюпорте (нажимая правой кнопкой мыши можно выбрать любой Output Driver, созданный в контексте out, в коммерческой версии там по умолчанию присутствует RenderMan).

В контексте SHOP создайте ноду Material.

Чтобы создать нужный оператор нужно удерживая указатель иыши над Network Pane вызвать Tool menu (клавиша TAB) и напечатать на клавиатуре первые 2-3 буквы нужного оператора.

Зайдите "внутрь" оператора (клавиша i) и создайте VOP RSL Surface SHOP. Соедините выход этой ноды с входом  next ноды Suboutput. Вернитесь на уровень выше (клавиша u) и перетащите ноду material1 на объект во вьюпорте. Теперь любые шэйдеры собранные внутри ноды material1 и подключённые к соответствующему входу ноды Suboutput будут автоматически присваиваться шарику.
Входы для каждого типа шэйдеров имеют уникальный цвет:

Начнём с самого простого шэйдера.

surface constant()
{
Ci = Cs*Os;   
Oi = Os;
}

surface - тип шэйдера
constant – имя шэйдера
() – скобки – в скобки заключаются входные параметры
{} – фигурные скобки обозначают начало и конец программы.

Ci – выходное значение цвета в точке, Oi – выходное значение прозрачности.
Ci, Oi – значения цвета и прозрачности, указывающиеся при вызове шэйдера из RIB (по умолчанию это белый цвет).

Зайдём в созданную ранее ноду rsl_vopsurface1. Пока внутри неё есть одна нода - output1, с двумя входами – Ci и Oi. Смотрим на код – чтобы получить нужный нам шэйдер constant – к входу Ci мы должны присоеденить произведение двух глобальных переменных – Cs и Os, а к входу Oi значение Os. Для получение доступа к глобальным переменным нужно создать ноду Global Variables
Os можно сразу соеденить с Oi.
Для получения Ci нужно перемножить Cs и Os – сделаем это нодой Multiply. Выход Multiply будет имеет значение нужное для Ci – соеденим их.      

Для Mantra создадим VOP VEX Surface SHOP и повторим все предыдущие действия. Заметьте, что Output Surface шэйдера для Mantra выглядит иначе – Ci и Oi называются Cf и Of, а так же есть ещё три входа, Af - альфа (позволяет управлять альфой независимо от прозрачности), N - нормаль (даёт возможность создавать эффект bump в Surface шэйдере), F - данные для физически корректного движка.

Результат:

файл сцены

Поскольку мы не собираемся копаться в RIB файлах перед каждым рендером, нужно добавить шэйдеру возможность вручную вводить исходные значения.
Создайте две ноды Parametr.
Установите Parametr Type в Color.
Parametr Name и Parametr Label впишите Color для одной ноды и Opasity для второй.
Поднимитесь на уровень вверх и в параметрах шэйдера обратите внимание на появившиеся параметры Color  и Opacity. Это и есть графический интерфес который мы создали для шэйдера. Имя под которым параметр будет фигурировать в интерфейсе задаётся в Parametr Label.
Вернитесь обратно в шэйдер и присоедините параметры вместо глобальных переменных Os и Cs.

Теперь мы можем задавать шэйдеру произвольные цвет и прозрачность.
Повторим то же самое для Mantra:

Результат (цвет задан в параметрах шэйдера):

файл сцены

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

Integer – целые числа.
Float – числа с плавающей точкой.
Vector – направленный отрезок. Указывается координата конца этого отрезка, начало которого находится в начале координат. Представление этого типа данных имеет вид (x, y, z), где x, y и z это числа типа Float.
Normal - вектор, перпендикулярный касательной плоскости в точке. Это так же 3 числа Float через запятую.
Color – цвет – представлен группой из 3-х Float’ов – (r, g, b).
Point – точка – координата текущей точки – 3 числа типа float (x, y, z).

Замечание: Для Mantra все типы данных с тремя float (vector, color, normal, point) объединены под одним типом  - vector и имеют один и тотже зелёный цвет.

Так же в этом шэйдере мы столкнулись с необходимостью выполнить математическую операцию "умножение". VEX-builder позволяет выполнять любые математические операции в нодовом представлении.
Большинство нод математических операций находятся в группе Combine:

Наиболее часто используемые операции:

* - умножение – перемножает любое количество подключенных к ней источников одного типа, или умножает произведение какого-то одного составного типа данных на какой-либо простой, например перемножить несколько color’ов, а затем умножить их на float. В Rsl шэйдерах мы не можем перемножать разные составные типы, например нельзя умножить цвет на точку:

От того какая нода подключена первой зависит тип данных на выходе ноды multiply.
+ - сложение  - складывает входящие данные. Правила подключения входов такие же как и у ноды multiply.
/ - деление – работает так же как и предыдущие две, но первым всегда должно подключаться делимое, а затем делитель.
- - вычитание – работает аналогично делению.

Поскольку в шэйдерах для Mantra color, vector, point и normal – это один тип данных то их можно перемножать в одной ноде multiply, складывать в одной ноде add и т.д.

Итак, мы можем задать шэйдеру произвольный цвет и прозрачность, теперь добавим возможность использовать для цвета текстуру.

Вернитесь внутрь шэйдера. Отсоедините параметр Color но не удаляйте его  - для более широкого функционала шэйдера было бы неплохо оставить возможность пользоваться как заданным цветом, так текстурой. Для использования текстуры в своем шэйдере содайте ноду с красноречивым названием Texture.

Всё необходимое для загрузки текстур из файла в этой ноде есть. Обратите внимание на настройки:

В RSL шэйдерах в меню Signature текстуру можно переключать из режима color во Float (используется только один канал текстуры). При использовании текстуры в шэйдерах для Mantra в меню Signature можно выбрать режим RGBA – из текстуры будут использоваться не только каналы цвета но и альфа-канал.

В этом режиме на выходе ноды texture будет другой тип данных – color4 (vector4 - mantra), поэтому для дальнейших математических операций с обычным трёхцветным color придется отделять альфа канал с помощью нод из группы Convert, примерно так:

Сейчас оставим простой RGB режим. Для того чтобы можно было переключаться между цветом и текстурой создайте ноду switch. Кликните Средней кнопкой на входе switcher и из появившегося меню выберете Create Paremetr. Параметр будет имеет тип Integer и от того какое число будет выбрано в интерфейсе шэйдера будет работать тот или другой вход ноды switch. Выходы от текстуры и параметра Color подключите во входы switcher’а input1 и input2. Так как у нас всего два варианта, в параметре переключателя вместо типа Integer можно выбрать Toggle – в интерфейсе это будет выглядеть как галка – on/off.


И для того чтобы выбирать файл для текстуры, создайте параметр для атрибута map ноды texture.
Замечание: при использовании текстур необходимо запомнить, что для рендера в RenderMan текстуры должны быть в его родном формате текстур - *.tex. Сконвертировать текстуру из своего формата в формат *.tex можно утилитой texmake входящей в состав RenderMan.
Для Mantra можно использовать практически любой тип изображений (включая *.tex).

Результат:

файл сцены

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

Шэйдер Constant не использует никаких данных сцены, таких как источники света и угол камеры.
Для начала заставим диффузную составляющую реагировать на свет.
Создайте новый шэйдер назовите его diffuse_.

Вот RSL код этого шэйдера:

surface diffuse_()
{
normal Nn = normalize(N);

    Oi = Os;
Ci = Oi * Cs * diffuse(Nn);
}

Создайте ноду Global Variables.
Функция normalize выполняется нодой normalize, - создайте эту ноду и подключите к ней глобальную переменную N (эта функция приравнивает длину вектора к еденице сохраняя направление ).
При попытке найти ноду diffuse нас ожидает сюрприз: такой ноды в стандартной поставке Houdini нет, но это не значит, что мы не сможем воспользоваться этой функцией. На самом деле для далеко не всех RSL и VEX функций в VEX-builder есть соответствующие ноды (на Houdini слэнге VEX-операторы – VOP’ы). Здесь приходит на помощь нода Inline Code VOP.
Создайте эту ноду. Подсоедините к ней текущее значение переменной Nn – это нода normalize (полезно давать осмысленные имена нодам, например имена переменных, которые хранятся в этой ноде). Посмотрите на параметры ноды Inline Code:

В Output1 Type выберите color и задайте имя в поле Output1 Name (я использовал имя diff).
Теперь в поле Inline Vex Code напишите следующее:

$diff = diffuse($nvec);

$diff – только что созданный Output, знак доллара обозначает, что это переменная.

= - оператор присваивания – мы должны присвоить некоторое значение переменной $diff.

diffuse($nvec) – вызов функции diffuse с аргументом $nvec (в круглых скобках указываются аргументы - входные данные для функции). $nvec - значение являющееся результатом работы ноды Normalize, подключенной к Inline Code VOP - список все подключенных значений находится внижней части параметров этого оператора, а так же там указываются имена переменных для использования в Inline Vex Code.

; - строка с командой должна заканчиваться точкой с запятой.

Теперь создадим Multiply и перемножим Os, Cs и результат работы ноды Inline Code.
Присвоим результат Ci.

Результат:

файл сцены

Функция Diffuse это не "чёрный ящик", и при желании все вычисления внутри неё можно повторить, собрав свою функцию наделённую какими нибуть свойтвами, недоступными стандартной функции. Например работа diffuse() сводится к вычислению косинуса угла между направлением источника света и нормалью в точке:

Свет попадает в точку А перпендикулярно поверхности. В этой точке вектор -L и нормаль совпадают, т.е. угол между ними == 0. cos(0) == 1. Соответственно интенсивность источника света (пусть будеть 1) умножается на косинус получается что в точке А освещённость тоже равна 1. В точке "B" нормаль находится под углом 45 градусов к направлению освещения -L. cos(45) == 0.5. т.е. Освещённость этой точки будет 0,5 интенсивности источника света. Косинус угла вычисляется скалярным произведением еденичных векторов нормали и луча света - для получения еденичных веторов (длина которых равна 1) и нужны ноды Normalize.

Добавим возможность реагировать на Ambient освещение.

Ci = Os*Cs*(ambient()+diffuse(Nn));

Для этого добавим ноду ambient и сложим её значение с результатом с результатом вычисления Diffuse

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

файл сцены

Добавим два параметра Ka и Kd типа float для того, чтобы управлять интенсивностью диффузной и эмбиентной составляющей, а так же параметры цвета:

Установив значение, например, Kd =0 цвет diffuse, который на него умножается тоже станет равным нулю, а поскольку далее diffuse и ambient составляющие складываются, то значение 0 просто не будет оказывать какого-либо влияния на результат.

Собственно результат:

файл сцены

При желании можете добавить возможность использования текстур вместо цветовых параметров.

Следующим этапом будет добавление шэйдеру блика – specular. Specular, о котором пойдет речь не является физически корректным бликом, который в природе появляется на отражающих поверхностях и фактически является отражением самого яркого объекта (например окна или лампы). В данном случае это упрощённая математическая модель, которая рисует блики определённой формы в зависимости от положения источников света и камеры.

Кoд:

specular(Nf,V,roughness)

функция specular требует 3 аргумента:
Nf - это normalize(N) или faceforward(normalize(N), I ) (- в VEX faceforward называется frontface, так же называется соответствующая нода - frontface VOP).
Roughness – параметр float – будет регулировать жесткость блика.
V = -normalize(I);

Для получения V создайте ноду normalize.
Подключите к ней глобальную переменную I.
Создайте ноду Multiply и в первый вход подключите результат предыдущей ноды.
Нажмите средней кнопкой на втором входе ноды Multiply и выберите Create Constant.
В поле Float Default установите значение -1.

Теперь создайте ноду Inline Code и подключите к ней Nf и V, а также создайте параметр roughness:

файл сцены

Полученный specular можно добавить к diffuse и ambient составляющей присоединив его к ноде add.

файл сцены

Мы получили specular который в остальных программах обычно называют Blinn. Для получения блика типа Phong вместо функции specular в Inline Code нужно использовать функцию phong.

файл сцены

Добавим (умножением) к спекуляру параметр Ks для управления его интенсивностью:
Теперь подбирая значения Ks и Roughness можно получить, например, жесткий Glossy блик:

Замечание: обратите внимание, что функции specular и phong по-разному реагируют на параметр rougness поэтому будет удобно если для каждой из них будет выставлен соответствующий Float Range – границы в которых будет двигаться бегунок в интерфейсе.

Для specular подойдёт значение 0 1, для phong лучше использовать 0 100.

Для создания других типов бликов можно воспользоваться нодой Specular Functions (она уже содержит рассмотренные выше примеры, а так же Glossy и Anisotropic блики), либо собрать свою функцию Specular (о том как можно покопаться в функциях diffuse или specular и собрать свою с нуля можно прочитать в документации к PRman и в др. источниках которые будут указаны в заключительной части).

Чтобы придать блику цвет просто домножим его на параметр  цвета или текстуру:

файл сцены

Говоря о создании Surface шэйдеров было бы неправильно обойти стороной рэйтрэйсовые функции – если такой материал как хром можно легко сымитировать используя карту отражения, то, например, стекло сделать фейком достаточно сложно.

Отражение.

Отражение – Reflection – сорздаётся функцией reflect:

reflect(I, Nn) – где I – глобальная переменная, а Nn = faceforward(normalize(N), I)

полный вызов функции выглядит так

trace(P, reflect(I, Nn))

Cначала получим Nn:

Обратите внимание на то, что функция faceforward в VEX называется fronface, так же называется нода реализующая её.

Далее соберите конструкцию trace(P, reflect(I, Nn)), и подключите к выходу Ci:

Для проверки работы рэйтрэйса создайте плоскость на которой лежит шар:

файл сцены

Аналогичным образом создаётся рефракция, только вместо функции reflect используется функция refract (при необходимости можно вынести параметр IOR подключив ноду parametr на вход eta):

IOR = 1.333

файл сцены

Атрибут angle ноды Ray trace  регулирует «размытость» отражения или преломления, только не забывайте что Mantra и большинство RenderMan совместимых рендеров достаточно медленно просчитывают raytrace (в Mantra для этого лучше использовать Ray tracing engine).

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

файл сцены

Ещё один очень часто используемый рэйтрэйсовый эффект – Ambient Occlusion. И в RSL и в VEX это функция occlusion. Если вам достаточно её основного функционала то достаточно создать ноду Occlusion и использовать её:

Если необходимы дополнительные возможности, то лучше обратиться к документации по RSL и использовать Inline Code.

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

файл сцены

Абстрагируясь от программирования разработку Surface шэйдеров можно представить как создание компонент/составляющих (diffuse, specular и т.д.) которые в дальнейшем смешиваются (складываются, умножаются) для получения нужного окрашивания поверхности.

 

Таким образом можно создавать неограниченное количество блоков, каждый из которых будет реализовать тот или иной требуемый эффект и объединить их в самом шэйдере, или выводить их отдельно для сведения на композе. Сложение обычно используется когда нужно чтобы более тёмные цвета не оказывали влияния на картинку, умножение наоборот - как в случае с оклюженом используются более тёмные участки для создания эффекта мягких теней. Откройте Photoshop и посмотрите на список Blending режимов у слоёв - все они реализованы математическими операциями над цветами.

Паттерны.

Заканчивая разговор о Surface шэйдерах рассмотрим ещё одну очень важную возможность VEX и RSL – создание паттернов – параметрических цветных узоров, которые иногда называют «процедурными текстурами».
Паттерны – очень мощный  и гибкий инструмент с огромной сферой применения и используются не только в Surface, но и во всех остальных шэйдерах. Паттерны не только не теряют детализацию при приближении и не только могут покрывать большие площади неповторяющимся рисунком, главное достоинство паттернов перед растровыми текстурами – параметризация, которая позволяет анимировать любое свойство текстуры.
Создание различных узоров и фракталов требует более глубоких навыков программирования, векторной алгебры и тригонометрии, поэтому здесь рассмотрим достаточно простые примеры (за дополнительной информацией – см. рекомендуемая литература). Создание каждого узора требует анализа необходимого рисунка, нахождение закономерностей и представление их в виде математических функций.

Окружность.

Окружность рисуется на двухмерной поверхности  используя координаты параметрического пространства поверхности s-t (или u-v):

Окружность имеет радиус, координату центра.
Уравнение окружности ω (A; R) имеет вид (x – a)2 + (y – b)2 = R2, где a и b – координаты центра A окружности ω (A; R) .
Код шэйдера:

surface circle(
color inside = color (1, 1, 1);
color outside = color (1, 0, 0) ;  
float radius = 0.3, scenter = 0.5, tcenter = 0.5;
)
{
float sdist, tdist, dist, circle;
sdist = s - scenter;
tdist = t - tcenter;
dist = sqrt(sdist*sdist + tdist*tdist);
circle = step( radius, dist );
Ci = mix( incolor, outcolor, circle);
}

Создайте полигональную плоскость (Ctrl + клик по кнопке Grid на полке Create), оставьте все значения по умолчанию, нажмите U чтобы войти в контекст ноды. Кликните правой кнопкой на выходе ноды grid1 и из появившегося списка выберите UV project. Убедитесь, что поля в разделе Transform выглядит так: Rotation 90 0 0, Scale 10 10 0.

В SHOP контексте создайте материал, в нем шэйдер VOP RSL Surface (для RenderMan) или VOP VEX Surface (для Mantra). Назовите его circle и примените материал к объекту.

Для сборки понадобятся функции
step – нода filterstep

Соберём шэйдер:
sdist = s - scenter;
tdist = t - tcenter;
dist = sqrt(sdist*sdist + tdist*tdist);

ind = step( radius, dist );

Ci = mix( incolor, outcolor, ind );

Установите значения параметров
inside = color (1, 1, 1);
outside = color (1, 0, 0) ;  
radius = 0.3, scenter = 0.5, tcenter = 0.5;

Рендер:

Паттерн нарисовал окружность в каждом полигоне потому что после применения UVProject переменные s и t стали отдельными для каждого отдельного полигона. На объектах, имеющих U-V развёртку нужно использовать соответствующие переменные s и t. Создайте ноду UVCoords и возьмите переменные st из неё:
Рендер:

файл сцены

Поставив ключи на параметр radius, можно анимировать размер окружности – это можно использовать, например, при создании шэйдера роговицы глаза.

Шахматная доска:

Алгоритм следующий: делим ось s и t на несколько равных частей и поочерёдно закрашиваем их чёрным и белым цветом:

surface checker(
float srepeat = 2, trepeat = 2, soffset = 0.25, toffset = 0.25;
color color1 = color (0, 0, 0), color2 = color (1, 1, 1)
)
{
float ss = mod( srepeat * s - soffset, 1 );
float tt = mod( trepeat * t - toffset, 1 );

 

    float chkrS = 1 - step( 0.25, ss ) + step( 0.75, ss );
float chkrT = 1 - step( 0.25, tt ) + step( 0.75, tt );

    float chkr = abs(chkrS - chkrT);

    Ci = mix( color1, color2, ind );
}

Создайте новый шэйдер, назовите его checker.
Для сборки понадобятся функции

2 3 | След.
46135 Автор:
Актуальность: 787
Качество: 791
Суммарный балл: 1578
Выбор Публики
Голосов: 128 оценки

Отзывы посетителей:

2 | След.
аватар
 
Форин 2 0

добавили картинку отрезался текст в низу(((


аватар
 
Форин 2 0

ХЗ в общем про шахматы тема так и не раскрылась(( пунктиры, клеточки короче что угодно только не шахматы((

 

аватар
 
Форин 2 0

а про чекер можно до конца посмотреть, что то не получается у меня, а описание обрывается на тексте "Для сборки понадобятся функции "((


аватар
 
ALeXeY(nord3d) 5 0
Дополнение: ещё, чтобы соответствовало старым (коротким) названиям входов/выходов в нодах, можно в тех же преференсах, в "Network Editor, Nodes and...", убрать галку с "Show Full Input and Output ...".
аватар
 
ALeXeY(nord3d) 5 0
Цитирую DRL:
Можно узнать корректировки к уроку применительно к 11 версии?


В 11-й по-умолчанию отключена поддержка "лишних" рендереров, а именно всех кроме мантры. Для начала можно включить (выделить с шифтом или контролом) все нужные рендеры в едит-преференсес-рендеринг. Т е, в данном случае, добавить к мантре "пиксар'с рендерман". Тогда в ШОПе появятся наборы нод для RSL, например RSL Material Shader Builder. Suboutput там теперь output_collect.
аватар
 
DRL 12 0
Гудини начал осваивать специально для этого урока, чтоб построить нужный RSL-шейдер и использовать его в Майе (слима нет).

Но вот беда: застрял на месте, где только началась практическая часть.
В 11-й версии Гудини нет ноды "Material", только "Material Shader Builder", но в ней нет ни "VOP RSL Surface SHOP", ни "Suboutput". Ещё вместо "Material Shader Builder" можно создать "VOP Network". В нём есть "RSL Surface SHOP", но, опять же, нет Suboutput.

Можно узнать корректировки к уроку применительно к 11 версии?
аватар
 
rsd 20 0
отличнейший урок! очень мне помог!
не понял только момент с volume шейдером: в 10-ой мантре нода трансформ инвертирует эффект атмосферы, без нее все нормально. Наверное, какие-нибудь настройки надо вбить?
аватар
 
stets 22 0
Большое человеческое СПАСИБО!!!
аватар
 
planete 2 0
Ну да, вообще то да. Пожалуй возьму свои слова обратно, насчёт ширпотреба.
аватар
 
wiTcHer 71 0
Цитирую:Я только начал работать с houdini, до это тоже работал 3dsmax и cinema
Про 3dsmax молчу, это вообще ширпотреб, как АЕ и windows, а вот houdini+fusion+mac - для настоящих эстетов. В этом и отличие,

думаю правильнее отталкиваться от задач, а не от отношений с софтом :)
аватар
 
wiTcHer 71 0
проапгрейженую версию на английском давно уже отправил чувакам из SideFX но пока ещё не опубликовали, как опубликуют положу сюда сцылку
аватар
 
planete 2 0
Просто нереально круто.
Такой подробный материал на русском.
Witcher+100
Я только начал работать с houdini, до это тоже работал 3dsmax и cinema
Про 3dsmax молчу, это вообще ширпотреб, как АЕ и windows, а вот houdini+fusion+mac - для настоящих эстетов. В этом и отличие,
windows и иже с ним к тебе относятся тиранически, как надменные учителя к ученикам, а такие программы - как к партнёру - в этом главное отличие. Гибкость в отношениях.
Ещё раз+100 witcher, материал подробный, рациональный и выложен правильно!
аватар
 
KND 2 0
просто сепер-урок! очень нужный и настолько доступный и подробный - спасибо автору за то что не поленился и описал все подробненько! Еще бы неплохо что-то подобное для начинающих-продолжающих по связке Рендерман-мая! Ошибается тот кто считает что это не актуально и все уже давно и так все знают ... Если кто располагает подобной инфой либо знает где ее найти (желательно на русском, потому как без знания специфической терминологии даже знатоки английского будут плавать, а терминологию знают в основном те, кто плавает сам - а им такое уже и не надо ...) пишите в личку, или в комментах к этому уроку! Огромная просьба автору, если есть возможность, уважаемый wiTcHer, напишите нечто подобное для майки!!!! Your Help is very useful!!!! Заранее огромное спасибо за труды! ;)
аватар
 
wiTcHer 71 0
юзай мантру, она местами даже покруче
аватар
 
wiTcHer 71 0
не несталкивался с таким както всё само нормально работает
аватар
 
Ultrus 1 0
Я сделал как здесь написано http://www.sidefx.com/index.php?option=com_forum&Itemid=172&page=viewtopic&p=65578&sid=0b240f9841a56427f32d9b31a3a320c1
он мне вот эту ошибку выводит
P80005 {ERROR} Parameterlist type mismatch in RIB stream. (at line 67 in stdin)
после добавления атрибута Transmission Visibity(я так понял для теней), причем в настройке рендера она тоже есть и там галка стоит, еще чуть выше там галка Diffuse Visibity(для оклюжена чтоли) ее включил.
Отражении все черные с артефактами, жесть.
И еще выводит это - Shaders invoke raytracing, but no traceable objects exist. после этого полность черный мат.
Такое ощущение , что не добавляются атрибуты в ribах или криво жалко , что я в языке не понимаю.
Попробовал атрибут добавить для сглаживания SubdivisionScheme никакой реакции.
Что-то не так делаю, или совсем кривые руки:(
аватар
 
wiTcHer 71 0
не, в улитке гудини пока так и не прижился. по умолчанию рэйтрэйс включен. Если создвать новый Output там в параметрах аутпута всё включается включается - настройки почти такиеже как в mtor
аватар
 
Ultrus 1 0
Ну ваще)))))то что надо. Спасибо! В Улитке под Гудини РендерМаном рендерят:) Вопрос как там рейтрейс включить? какие-то атрибуты добавлял, ничего не получилось...
аватар
 
wiTcHer 71 0
Цитирую Сreate:


Здравствуйте wiTcHer
Вы не могли бы выложить для ознакомления файл сцены собраного шейдера для tangent space, или показать окончание строчки inline VEX ccode, вот на этом скрине мне показалось что она незакончена http://render.ru/images/uploads/Image/Tutor/all/515/images/145.tangent1.jpg поправте меня если я ошибаюсь.
зарание благодарен


патч к тутору v1.0.2:
Сreate (3D Work), спасибо огромное! доглядел!! действительно, видимо потерялся файл :(Смысла прикладывать не вижу (там и по картинкам всё понятно как собрать матрицу) в этом инлайне должна быть процедура:

vop_computeTangents($tanU, $tanV, normalize(N), $uv, 2);

процедура vop_computeTangents() отсутствует в документации (может пожже добавят), нашел её в блоге одного из разрабов/тестеров (ссылка на его блог там есть)

в отличие от других функций, тут вычисляются сразу 2 значения $tanU, $tanV, и нет знака присваивания - обе переменые просто записываются в скобках первыми.

аватар
 
FSV141 11 0
Кла-а-ас-с-с!!!... Обалдеть какой здОровский урок! СПАСИБО! МегаЗачот! :)
2 | След.
Зарегистрируйтесь, чтобы добавить комментарий.
Эту страницу просмотрели: 634 уникальных посетителей