• Как создавать шейдеры, которые реагируют на угол падающего света
Для того, чтобы немного проиллюстрировать эту силу, мы начнём с рассмотрения скрипта, который создает регулярные цветные узоры, созданные из треугольников, прямоугольников, или шестиугольников.
Материалы, шейдеры, и текстуры - термины, которые часто используются как синонимы, хотя между ними есть разница в значении. Для наших целей мы попытаемся придерживаться следующих определений: текстура является основным строительным блоком, например, цветной или нормальный узор или просто некоторая функция, которая возвращает значение в зависимости от позиции на поверхности. Шейдер принимает на вход любое количество текстур или просто базовый цвет и возвращает цвет, основанный на влиянии падающего света и, возможно, направления вида. Материал — это набор текстур, шейдеров, и всех типов свойств, которые могут быть приложены к объекту. Pynodes могут быть текстурами, а также шейдерами.
Основы
Когда мы разрабатываем Pynode, мы в основном разрабатываем нечто, что предоставляет функцию, которая вызывается для каждого пикселя на экране, который должен быть затенен (shaded) этим нодом (или даже неоднократно, если включен oversampling). Эта функция получает, кроме прочего, координаты x, y, и z точки на затеняемом объекте, которая соответствует пикселю на экране, который мы к настоящему времени вычисляем. Затем функция должна вернуть что-то полезное, такое как цвет, значение интенсивности, или что-то чуть менее интуитивное, например, нормаль.
В окне редактора Нодов Блендера каждый нод материала, включая Pynode, представлен прямоугольником, который имеет входы слева и выходы справа. Эти входы и выходы, часто называемые сокетами, представлены небольшими цветными кругами (смотрите следующий скриншот). Эти сокеты можно использовать для связи нодов вместе; щелкая по выходному сокету одного нода и перетаскивая мышь ко входному сокету другого нода, эти ноды будут связаны. Так, комбинируя требуемым образом множество различных нодов, можно создать очень сложные и мощные шейдеры.
Сила системы Нодов Блендера проистекает не только из её многочисленных встроенных типов нодов, и множества способов, которыми эти ноды могут быть связаны, но также из того, что мы можем написать новые ноды на Питоне, которые можно связывать так же, как обычные ноды.
Для Pynodes нужен способ получать доступ к информации, передаваемой входными сокетами и способ посылать рассчитанные результаты в выходные сокеты. Понятие нода и сокетов структурировано в соответствии с объектно-ориентированной моделью. Давайте бросим первый взгляд на небольшой пример кода, чтобы доказать, что это не страшно (ветераны объектно-ориентированного программирования: поглядите в другую сторону или смотрите сквозь пальцы, чтобы просто разобраться с определением класса из следующего примера):
from Blender import Node
class MyNode(Node.Scripted):
def __init__(self, sockets):
sockets.input = [Node.Socket('Coords',
val= 3*[1.0])]
sockets.output = [Node.Socket('Color',
val = 4*[1.0])]
def __call__(self):
x,y,z = self.input.Coords
self.output.Color = [abs(x),abs(y),abs(z),1.0]
Прежде чем мы посмотрим на этот код подробно, попробуем его в Блендере, чтобы посмотреть, как он работает на практике:
1. Откройте новый файл в текстовом редакторе и дайте ему значимое имя.
2. Скопируйте код примера.
3. Создайте простую сцену, например, простую UV-сферу в начале координат с парой ламп и камерой.
4. Назначьте Нодовый материал сфере как обычно.
5. Наконец, добавьте динамический (Dinamic) нод в Нодовом редакторе (Add | Dynamic) и выберите имя файла, который Вы отредактировали, щелчком на кнопке выбора динамического нода и выбрав файл из списка.
Результирующая сеть нодов (часто называемая макаронами (noodle)), может выглядеть похоже на это:
Если Вы рендерите сферу, результатом будет красочный шар, похожий на виджет выбора цвета.
Теперь вернёмся к коду.
На первой строке мы импортируем модуль Node из Блендера, поскольку мы создаём новый тип нода, но основное его поведение уже определено в модуле Node.
Затем мы определяем класс MyNode, подкласс Node.Scripted, который будет вести себя просто подобно ноду Scripted, за исключением тех частей, которые мы переопределим.