SlerManualBlockCreating

Руководство пользователя Sler

Создание блока для Sler

Введение


Блоки Sler – это независимые компоненты шейдеров, отвечающие за генерацию определённой части SL кода. Этот документ описывает процесс создания нового блока для Sler.


Описание каждого блока состоит из двух файлов. Первый представляет собой XML файл с описанием входов и выходов (обычные переменные SL), которые использует блок для связывания с другими блоками, а также определяет другие переменные, используемые в шаблоне кода, и имена которых необходимо заменить на другие, чтобы не возникали переопределения в случае появления в других блоках, используемых в том же шейдере, переменных с такими же именами.


Второй файл является шаблоном SL кода, на основе которого создаётся часть шейдера. Все переменные, входы и выходы заключены в скобки следующего вида: $(имя_переменной_входа_или_выхода). Этот шаблон не должен включать код начала и окончания шейдера, например, «surface My Shader?(){" и "}" соответственно. Обычные переменные и выходные должны быть объявлены в коде соответствующим образом, т.е. как перемнные языка Render Man Shading Language, а входы напротив не должны объявляться, т.к. на их место подставляются имена выходных переменных, связанного с каждым входом, блока.

Создание XML описания блока


Рассмотрим процесс трансляции стандартного шейдера plastic в блок Sler. Код шейдера взят из набора Pixie. Он представлен ниже.


/* plastic surface shader
*
* Pixie is:


* (c) Copyright 1999–2003 Okan Arikan. All rights reserved.
*/


surface plastic (float Ka = 1, Kd = 0.5, Ks = 0.5, roughness = 0.1;

color specularcolor = 1;) {
normal Nf = faceforward (normalize(N),I);
Ci = Cs * (Ka*ambient() + Kd*diffuse(Nf)) + specularcolor * Ks*specular(Nf,-normalize(I),roughness);
Oi = Os;
Ci *= Oi;

}


Параметры шейдера являются входными переменными, а выходными переменными для любого surface шейдера будут Oi и Ci. Конечно если вы хотите, то можете добавить и другие выходы, просто создав для них тег в XML описании. Надо заметить, что выходные переменные шейдера (Oi и Ci) уже не будут нести специального значения и становяться обычными переменными, мы может даже переименовать их, что далее и будет сделано. Кроме этого внутри шейдера используется переменная Nf, а т.к. переменная с таким же именем может появиться и в других блоках, то нам для избежания переопределения нужно явно её объявить в XML описании, чтобы в процессе генерации заменить её имя на нечто подобное: plastic0_Nf, в зависимости от имени шейдера.


Кроме этого мы добавим две входные переменные inColor и inOpacity, которые будет использоваться вместо переменных Cs и Os. А выходы Ci и Oi переименуем в outColor и outOpacity соответственно.


Теперь, когда входы, выходы и внутренние переменные определены, можно приступить к написанию XML файла с описанием блока. Ниже представлен файл plastic.xml, который вы можете найти в директории blocks архива Sler.


<block name="plastic"

category="shaders, surface" description="Standard plastic shader"
tested="True">

<input name="inColor" type="color" default="1" description="Input color" />
<input name="inOpacity" type="color" default="1" description="Input opacity" />
<input name="specColor" type="color" default="1" description="Specular color" />
<input name="Ka" type="float" default="1" description="Ambient power" />
<input name="Kd" type="float" default="0.5" description="Diffuse power" />
<input name="Ks" type="float" default="0.5" description="Specular power" />
<input name="Roughness" type="float" default="0.1" description="Roughness of specular light" />
<output name="outColor" type="color" description="Output color" />
<output name="outOpacity" type="color" description="Output opacity" />
<var name="Nf" />
<code sl_file="plastic.sl"/>
<preview

name="default"
function="surface"

module="sler.util.preview"

color="outColor" opacity="outOpacity"/>

</block>


Всё описание заключается в объемлющий тег block (порядок вхождения в него подчинённых тегов не имеет значения), которые имеет cледующие атрибуты:
    • name – название блока в Sler;
    • category – разделённые запятыми имена категорий, в которые входит блок;
    • description – описание блока;
    • tested – флаг, указывающий на то, является ли блок протестированным, т.е. следует ли от него ожидать адекватной работы.

Каждый вход описывается тегом input, с такими атрибутами:
    • name – название входа;
    • type – тип языка SL, который имеет вход;
    • default – значение входа по умолчанию, т.е. в том случае если в этот вход не перенаправляется значение выхода другого блока;
    • description – описание смысла входной переменной;

Выходы описываются тегом output, и имеют те же атрибуты, что и input, кроме значения default, т.к. для выхода оно не имеет смысла.


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


Тег code имеет единственный атрибут sl_file, который должен содержать путь до файла шаблона этого блока. Путь задаётся относительно текущего XML файла.


Этот тег используется для описания способа предпросмотра. Таких тегов может быть несколько и следовательно каждый блок можеть быть просмотрен различными сособами. Блок может вообще не имееть способов предпросмотра, это обычная ситуация для таких блоков как PI, sin, cos и др. Однако, если предпросмотры присутствуют, то хотя бы один должен иметь название default, что будет указывать на его статус предпросмотра по умолчанию. Если существуют несколько тегов preview с одинаковыми именами, то более поздний тег переопределяет предыдущие.
    • name – название этого способа предпросмотра;
    • function – имя функции которая выполнит все действия по генерации изображения для предпросмотра;
    • module – модуль для Python, в котором находится вышеуказанная функция, стандартные способы предпросмотра находятся в модуле sler.util.preview, однако, можно указать любой другой модуль, но он должен находится в путях поиска, в которых интерпретатор Python ищет модули ;

Дополнительные атрибуты, такие как color и opacity записываются в специальный словарь, который передаётся в указанную функцию в качестве аргумента. Основное его назначение определить отображение выходов блока на результирующие переменные шейдера, но ничто не мешает передавать в функцию параметры любого назначения. Как называются эти атрибуты зависит от обрабатывающей функции. Например, функция surface ожидает атрибутов color и opacity, любой из который может быть опущен, тогда будут использоваться значения по умолчанию. Существует также функция displacement, которая создаёт предпросмотр для шейдеров смещения и ожидает атрибуты point и normal. Она также может обрабатывать атрибут surface, определяющий имя шейдера поверности, который будет использоваться при рендеринге предпросмотра смещения. Если не указано, то будет использоваться plastic.

Трансляция SL кода в шаблон Sler


Теперь удалим из оригинального кода шейдера plastic начало и конец, заменим имена переменных, входов и выходов, если это имеет смысл, и заключим их в специальную форму: $(имя_переменной). Ниже показан шаблон блока plastic, который уже используется в Sler.


/* Plastic shader begin (taken from Pixie) */


/* plastic surface shader
*


* Pixie is:


* (c) Copyright 1999–2003 Okan Arikan. All rights reserved.
*/


normal $(Nf) = faceforward(normalize(N), I);


color $(outColor) = $(inColor) * ($(Ka) * ambient() +

$(Kd) * diffuse($(Nf))) + $(specColor) * $(Ks) *
specular($(Nf), -normalize(I), $(Roughness));

color $(outOpacity) = $(inOpacity);
$(outColor) *= $(outOpacity);
/* Plastic shader end */


Теперь наш шаблон готов для обработки генератором.

Добавление блоков в Sler


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


На данный момент Sler может загружать только правильный XML, и если будет ошибка в XML разметке, то Sler в лучшем случае не запустится. А вот ошибки в шаблоне SL кода никак не влияют на функциальнальность программы, однако в этом случае, сгенерированный код не скомпилируется компилятором шейдеров вашего рендерера и что вы получите, зависит от реакции последнего на ошибку.

Заключение


Как видно преобразовать кусок SL кода в блок Sler совсем не сложно.


Если вы создали какой-либо полезный блок и хотите им поделиться, то отправте его по адресу qewerty@gmail.com и скорее всего он будет добавлен в стандартный дистрибутив Sler.


Copyleft © 2007 Константин Евдокименко