Написание скриптов для Blender 2.49
Шрифт:
Мы заканчиваем нашу функцию __init__ определением множества констант и словаря распределений цвета, который мы будем использовать при генерации шестиугольной текстуры.
Следующим шагом будет определение функции __call__:
Функция __call__ начинается с определения нескольких сокращений для входных величин и умножения координатного входа на выбранный масштаб, чтобы растянуть или уменьшить сгенерированный узор. Следующий шаг должен установить тип желательного узора и вызвать подходящую функцию для вычисления выходного цвета для данных координат. Результирующий цвет назначается в наш единственный выходной сокет:
Все различные функции генерации узоров очень похожи; они берут координаты x и y и два или три цвета в качестве аргументов и возвращают единственный цвет. Так как это функции-члены класса, они также принимают дополнительный первый аргумент self.
Функция checker проверяет, в какой строке и колонке мы находимся, и если номер строки и номер колонки - оба нечетные или четные (что устанавливает оператор исключающее или), она возвращает один цвет, если нет, то возвращает другой цвет.
Функция triangle сначала одновременно вращает как x, так и y координаты на угол 45 градусов (превращение квадратов в вертикальные ромбы). Затем она определяет цвет, основываясь на номерах строки и колонки в точности подобно функции checker, но с уловкой: третье условие (выделено) проверяет, слева ли мы от диагонали, пересекающей квадрат, и поскольку мы вращали нашу сетку, на самом деле мы проверяем действительно ли координаты выше горизонтальной линии, делящей наш ромб. Это может звучать немного сложным, но Вы можете посмотреть на следующую иллюстрацию, чтобы понять идею:
Функция hexagon (шестиугольник) во многих отношениях похожа на функцию triangle (в конце концов шестиугольник - шесть треугольников, склеенных вместе). Следовательно, в ней применяется та же хитрость с вращением, но, вместо выбора цвета с использованием простой формулы, здесь всё несколько сложнее, и, следовательно, мы используем цветовую карту (выделено в предыдущем фрагменте кода). В основном, мы делим экран на горизонтальные и вертикальные полосы, и выбираем цвет, основываясь на том, в какую полосу мы попали.
Последняя часть магии - на последней строке нашего скрипта:
В текущей реализации Pynodes, Блендеру нужно это присвоение, чтобы идентифицировать класс в качестве нода. Наш нод появится в выпадающем меню скриптовых нодов как Tilings. Полный код доступен как tilings.py в файле tilings.blend вместе с примером нодовой сети. Некоторые возможные узоры показаны на следующем скриншоте:
< image l:href="#"/>Соответствующая нодовая сеть показана на следующем скриншоте. Заметьте, что мы не подключили никаких нодов к цветовым входам, но можно создать даже более сложные узоры, если мы это сделаем.
Если вы посмотрите внимательно на диагональные границы шестиугольного или треугольного узора, вы должны обратить внимание на некоторые артефакты наподобие лестницы, даже если oversampling был установлен на большое значение.
Сам Блендер достаточно умён, чтобы прилагать выбранный уровень anti-aliasing, например, к границам объектов, но в большинстве случаев текстуры на поверхности должны самостоятельно заботиться о наложении anti-aliasing. Встроенные текстуры Блендера, конечно, разработаны именно таким образом, но наши собственные текстуры, произведенные с помощью Pynodes, должны заниматься этим явно.
Существуют многочисленные математические методы, позволяющие уменьшить aliasing в сгенерированных текстурах, но большинство из них не так просто осуществить, или они требуют специфических знаний о способе генерации узора. К счастью, Блендер предоставляет нам опцию Full OSA (окно Кнопок | контекст Затенения | кнопки Материала | панель Links and pipeline). Если мы включим эту опцию, Блендер будет вынужден производить oversample с каждым пикселем в нашей текстуре в количестве, выбранном в кнопках рендера. Это дорогой вариант, но он позволит отделаться от эффектов aliasing без необходимости осуществлять специфические параметры фильтрации в нашем текстурном Pynode.