Вернемся к нашему RIB’y. Вот строка из него, которая определяет новый подключенный материал:
Surface “noisetest”
Это строку можно модифицировать, чтобы передать шейдеру параметры, например, вот так: Surface “noisetest” “freq” 100
Дальше - больше. Поскольку язык SL является потомком языка С, нам доступны такие возможности С, как препроцессор и макросы. Проиллюстрируем это на простом примере. Немного изменим наш шейдер:
surface noisetest ( float freq=FREQD; )
{
Ci = color(noise(freq*s,freq*t));
}
и строку вызова его компиляции:
shader -DFREQD=2 noisetest.si
Обратите внимание на то, что мы ввели в шейдер новую символьную константу (для удобства она обозначена большими буквами - FREQD), которую можем переопределять вне шейдера, в командной строке компилятора. Результат рендеринга будет, естественно, другим (мы вернули строку подключения шейдера в исходное состояние):
Учтите, что если бы мы вызвали компилятор без этого параметра, например, так
shader noisetest.si то получили бы ошибку - ведь константа останется неопределенной.
Уже вкусно? Сейчас будет еще вкуснее. Поскольку в наших руках почти что язык С, мы можем вынести куски кода в подключаемые файлы (included files) или, наоборот, использовать уже готовые подключаемые файлы в своем шейдере. Один из самых интересных для изучения начинающими include-файлов можно найти в RManNotes, небольшом онлайновом пособии по Renderman Shading Language (его перевод на русский язык доступен на сайте Renderman.ru). Мы же воспользуемся стандартными возможностями из поставки Renderman Pro Server. Подключаем к нашему шейдеру библиотеку материалов:
#include “materials.h”
surface noisetest (float freq=FREQD; )
{
Ci = color(MATERIAL_bronze*noise(freq*s,freq*t));
)
и вызываем компиляцию: shader -l%RMANTREE%\lib\shaders -DFREQD=2 noisetest.si и рендеринг дает нам:
Для продвинутых. -D и I - это флаги препроцессора языка С. Подробнее о них можно почитать в справке или в любой книжке по С. Обратим наше внимание на то, что в традиционных компиляторах препроцессор и компилятор - это две разных программы, которые связываются пайпингом. В некоторых Renderman-совместимых рендерерах используется аналогичный подход, например, в BMRT и Aqsis. Есть такой препроцессор и у shader; его назвали slpp и спрятали в поддиректорию %rmantree%\etc.
А как вы смотрите насчет того, чтобы выстроить цепочку из нескольких программ-генераторов шейдеров? Или, например, написать внутри шейдера небольшую программу на Perl, затем обработать шейдер еще одной небольшой программой на Perl - и получить таким образом динамически настраиваемый шейдер? А не изволите ли анимированных шейдеров? Возможностей
- море, нужно только помнить, что вы ничего не можете сделать с самим шейдером после компиляции - только передать параметры из RIB’a.
txmake.exe
В этом случае все совсем просто. Парадигма тотального ускорения рендеринга и разумного потребления памяти требует, чтобы все, что поступало на вход рендерера, было максимально оптимизировано. Для RIB’ob таким вариантом является бинарный формат, для SL