netlib.narod.ru< Назад | Оглавление | Далее >

Ваш первый шейдер

Ваш первый шейдер будет максимально простым. Вы нарисуете небольшой чайник без текстуры, окрашенный в фиксированный цвет. Затем вы добавите чайнику текстуру и больше цветов. Подготовьтесь к работе, запустив на вашем компьютере RenderMonkey. Обратите внимание, что все, необходимые для шейдера материалы, находятся в каталоге с исходными текстами к данной главе на прилагаемом к книге CD-ROM.

Первое, что вам понадобится — группа эффектов, которая будет содержать ваш шейдер. Чтобы создать ее, щелкните правой клавишей мыши по корневому узлу рабочего пространства и в контекстном меню выберите Add Effect Group | Effect Group w/DirectX Effect. Вы сразу увидите результат визуализации в окне предварительного просмотра. Это объясняется тем, что RenderMonkey помещает в создаваемую новую группу эффектов пример эффекта, как показано в рабочем пространстве на рис. 4.1. Поскольку в этой главе мы хотим проделать все с самого начала, нам надо удалить все узлы в группе эффектов за исключением узла эффекта. Чтобы сделать это, выберите узел, который хотите удалить, и нажмите клавишу Delete. Того же самого результата можно достигнуть, если при создании новой группы эффектов в контекстном меню выбрать Add Effect Group | Empty Effect Group. Вы можете переименовать группу эффектов, задав ей более осмысленное имя, например, MyEffect, щелкнув правой кнопкой мыши по узлу группы эффектов и выбрав в контекстном меню команду Rename.


Рис. 4.1. Группа эффектов, созданная RenderMonkey

Рис. 4.1. Группа эффектов, созданная RenderMonkey


Не беспокойтесь, если удаляя узлы из эффекта, вы увидите сообщения об ошибках. Это RenderMonkey сообщает вам, что из-за отсутствия необходимых узлов он не может выполнить визуализацию шейдера. Сейчас эти ошибки можно игнорировать, поскольку позже мы добавим необходимые элементы.

ПРИМЕЧАНИЕ
При создании новых узлов для группы эффектов и эффекта RenderMonkey может поместить в них используемые по умолчанию данные для эффекта. В дальнейшем это сэкономит нам много времени. В этой главе мы создаем все с нуля, чтобы узнать как все должно инициализироваться.

Чтобы получить что-нибудь на экране, очевидно, нам необходима геометрия для визуализации. Поэтому сейчас мы добавим к нашему шейдеру модель. Щелкните правой кнопкой мыши по только что созданному узлу эффекта и выберите в контекстном меню команду Add Model. Будет создан новый узел модели. Вы можете переименовать узел модели, через контекстное меню, вызываемое щелчком правой кнопки мыши, и выбрать файл с геометрическим объектом, дважды щелкнув левой кнопкой мыши по узлу модели. Диалоговое окно выбора модели показано на рис. 4.2. Выберите в папке с исходным кодом для этой главы файл teapot.3ds и щелкните по кнопке Open.


Рис. 4.2. Выбор файла модели для вашего шейдера

Рис. 4.2. Выбор файла модели для вашего шейдера


Когда геометрия выбрана и готова к использованию, вам надо указать RenderMonkey как данные геометрии будут передаваться в вершинный шейдер. Это делается с помощью узла Stream Mapping. Он содержит параметры, необходимые для преобразования данных модели в форму, пригодную для их использования шейдером. Фактически, узел содержит карту, определяющую, как данные геометрии будут поступать через входные регистры в ваш вершинный шейдер. Щелкните правой кнопкой мыши по узлу эффекта и выберите в контекстном меню команду Add Stream Mapping. Двойной щелчок по новому узлу Stream Mapping выведет на экран диалоговое окно редактирования карты отображения потока, показанное на рис. 4.3. Для нового узла редактор содержит только информацию о местоположении, но, щелкнув по кнопке Add, вы сможете добавить данные об отображении другой необходимой для шейдера информации из потока, такой как нормали и координаты текстур. Когда вы завершите указание правил отображения потока, закройте окно редактора.


Рис. 4.3. Создание карты отображения потока для модели чайника

Рис. 4.3. Создание карты отображения потока для модели чайника


Поскольку наш шейдер очень простой, для него потребуется добавить только одну переменную — матрицу вид-проекция. Хотя это и встроенная переменная, предоставляемая RenderMonkey, она все равно должна быть добавлена к рабочему пространству до того, как мы будем использовать ее в шейдере. Щелкните правой кнопкой мыши по узлу эффекта и выберите в контекстном меню Add variable | Matrix | Predefined | matViewProjection. В результате будет создана матрица, элементы которой будут автоматически заполняться RenderMonkey из комбинированной матрицы модель/вид/проекция вашего объекта. Эта матрица обеспечивает преобразование поступающих вершин из пространства объекта в экранное пространство.

К этому моменту вы указали все, что необходимо для вашего эффекта за исключением собственно прохода визуализации. Чтобы добавить новый проход визуализации, щелкните правой кнопкой по узлу эффекта и в контекстном меню выберите команду Add Pass. В результате будет создан новый проход для эффекта, заполненный данными примера эффекта. Переименуйте проход визуализации, присвоив ему имя MyPass, и удалите все его содержимое, поскольку мы будем создавать его с нуля.

Две первых вещи, необходимые проходу визуализации — это ссылки на модель и на карту отображения потока. Вы можете в RenderMonkey добавлять модели и карты отображения в любом месте вашего эффекта, но вам необходимо указать какая именно модель и карта используются в данном проходе. Чтобы указать ссылку на модель, просто щелкните правой кнопкой мыши по узлу прохода визуализации и выберите в контекстном меню команду Add Model Reference. В результате будет создан контейнер для ссылки на модель, но вам по-прежнему требуется указать существующую модель. Чтобы указать ссылку на существующую модель, щелкните правой кнопкой мыши по новому узлу ссылки на модель и выберите команду Reference Node, как показано на рис. 4.4. Вам будет показан список моделей, которые могут быть выбраны, из которого следует выбрать ту модель, которую вы намереваетесь использовать (для данного примера это модель чайника). Для добавления ссылки на карту отображения потока, проделайте те же самые действия, но в контекстном меню узла прохода, вызываемом щелчком правой кнопки мыши, выберите команду Add Stream Mapping Reference.


Рис. 4.4. Создание карты отображения потока для модели чайника

Рис. 4.4. Создание карты отображения потока для модели чайника


Последняя вещь, которая вам необходима — это код вершинного и пиксельного шейдеров. Давайте начнем с добавления к проходу визуализации вершинного шейдера, щелкнув по узлу прохода визуализации и выбрав в контекстном меню Add Vertex Shader | DirectX HLSL. Созданный вершинный шейдер будет содержать предлагаемый по умолчанию код, но мы полностью заменим его на свой собственный. Вы можете сейчас дважды щелкнуть по узлу вершинного шейдера, чтобы перейти к окну редактирования.

Как видите, переменная matViewProjection уже присутствует в коде шейдера, поскольку она необходима для большинства шейдеров. Вообще, чтобы установить эту переменную, просто добавьте ее к коду шейдера, также как вы объявляете любые другие переменные. За дополнительной информацией можете обратиться к справочному руководству HLSL из приложения A. Объявление переменной для матрицы вид-проекция выглядит следующим образом:

float4x4 matViewProjection;

Если вашему шейдеру нужны другие переменные, вы должны объявить их здесь же. Но сейчас этого достаточно, и можно перейти к добавлению кода вершинного шейдера. Сначала вам необходимо определить структуру, используемую для передачи данных вершин из вершинного шейдера в пиксельный. Мы будем использовать структуру с именем VS_OUTPUT, хотя вы можете выбрать имя по своему вкусу. Поскольку сейчас нам необходимо знать только местоположение вершины, структура должна иметь следующий вид (это структура, создаваемая RenderMonkey по умолчанию):

struct VS_OUTPUT
{
    float4 Pos: POSITION;
};

Структура создает векторную переменную с именем Pos и семантикой POSITION. Семантика определяет назначение переменной и то, как она должна передаваться в пиксельный шейдер.

Ядром шейдера является функция-точка входа, указанная в поле Entry Point окна редактирования вершинного шейдера. Подразумевается, что вы будете вызывать функцию с именем vs_main, и вы можете определить пустую функцию с этим именем, которая будет служить в качестве шаблона вашего вершинного шейдера. Также должны быть определены параметры функции таким образом, чтобы указанные в карте отображения потока значения передавались в функцию. Для нашего примера шейдера требуется только местоположение вершины, поэтому пустая функция вершинного шейдера будет выглядеть так:

VS_OUTPUT vs_main(float4 inPos: POSITION)
{
    VS_OUTPUT Out;

    return Out;
}

Обратите внимание, что за входным параметром inPos следует объявление семантики POSITION. Это говорит вершинному шейдеру о том, какая информация из потока геометрических данных отображается на данный параметр. Также заметьте, что и сама функция и возвращаемое значение имеют тип VS_OUTPUT. Это информация, которая будет передана от вашего вершинного шейдера пиксельному после того, как вершина будет обработана. Пиксельному шейдеру передается именно та информация, которую возвращает ваша функция вершинного шейдера. Поскольку простейшему вершинному шейдеру достаточно отобразить вашу геометрию без дополнительной обработки, необходимо только выполнить преобразование полученной вершины согласно матрице вида-проекции и вернуть полученные значения. Это выполняется путем умножения вектора местоположения вершины на матрицу matViewProjection:

Out.Pos = mul(matViewProjection, inPos);

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

float4x4 matViewProjection;

struct VS_OUTPUT
{
    float4 Pos: POSITION;
};

VS_OUTPUT vs_main( float4 inPos: POSITION )
{
    VS_OUTPUT Out;

    // Возвращаем преобразованную и спроецированную вершину
    Out.Pos = mul(matViewProjection, inPos);

    return Out;
}

С вершинным шейдером закончили; теперь вам необходимо определить пиксельный шейдер для эффекта. Закройте окно редактирования, щелкните правой кнопкой мыши по узлу прохода визуализации и выберите в контекстном меню команду Add Pixel Shader | DirectX HLSL. Если вы дважды щелкните по новому узлу Pixel Shader, то на экран будет выведено окно редактирования с кодом, предлагаемым RenderMonkey по умолчанию для пиксельного шейдера. Этот код выглядит следующим образом:

float4 ps_main( float4 inDiffuse: COLOR0 ) : COLOR0
{
    // Возвращаем фиксированный цвет:
    float4 color;

    color[0] = color[3] = 1.0;
    color[1] = color[2] = 0.0;

    return color;
}

 

ПРИМЕЧАНИЕ
Работая с DirectX и OpenGL вы можете выполнять визуализацию, используя только вершинный шейдер, только пиксельный шейдер, или сразу оба; если используется только один шейдер, то вместо второго работают функции фиксированного конвейера. Но, поскольку RenderMonkey является средой разработки шейдеров, при работе с ним вам, чтобы получить изображение на экране, необходимо создать и вершинный и пиксельный шейдер.

Обратите внимание, что предлагаемый по умолчанию шейдер возвращает значение типа float4 с семантикой COLOR0. Это означает, что возвращаемое функцией значение является итоговым цветом для визуализации на экране, и именно этот дескриптор семантики будет использоваться в большинстве ваших пиксельных шейдеров. Также заслуживает упоминания входная переменная inDiffuse, для которой также указана семантика COLOR0. Эта переменная задает отображение выходной переменной вершинного шейдера с той же семантикой на входную переменную пиксельного шейдера. Вам не требуется исходный цвет, поскольку ваш вершинный шейдер не предоставляет такой информации, так что данный входной параметр можно исключить. Кроме того, вы можете сейчас изменить шейдер таким образом, чтобы объект был красным. Если выполнить эти два изменения, то полученный пиксельный шейдер будет выглядеть так:

float4 ps_main() : COLOR0
{
    // Возвращаем фиксированный цвет:
    float4 color = float4(0,0,0,0);
    color.r = 1.0;

    // Устанавливаем зналение альфа равным 1.0
    // чтобы предотвратить альфа-смешивание
    color.a = 1.0;

    return color;
}

 

ПРИМЕЧАНИЕ
Вы можете заметить, что и для вершинного и для пиксельного шейдера в качестве целевой платформы компиляции указана версия 1.1. Хотя для большинства шейдеров, которые мы будем разрабатывать в этой книге, в качестве целевой платформы компиляции необходимо указывать версию 2.0, шейдеры из данной главы очень просты и не требуют изменять целевую версию. В общем случае, если ваш шейдер достаточно прост, чтобы работать с меньшим номером версии пиксельных и вершинных шейдеров, указывайте минимально допустимый номер версии, поскольку на ряде видеокарт это приводит к повышению эффективности работы шейдера.

Ваш первый шейдер готов. Теперь вы можете щелкнуть по кнопке панели инструментов Compile All Shaders in Active Effect (или нажать клавишу F7). В окне предварительного просмотра вы должны увидеть красный чайник, как показано на рис. 4.5. Если окна предварительного просмотра нет на экране, щелкните по кнопке Preview на панели инструментов. Если вы не увидели чайник, посмотрите на информацию, выводимую в окне отладки — возможно, вводя код шейдера вы допустили опечатку, которая мешает правильной компиляции. Функционирующая версия данного шейдера находится в файле shader_1.rfx в каталоге с исходными кодами для данной главы на прилагаемом к книге CD-ROM.


Рис. 4.5. Рабочее пространство и окно предварительного просмотра для вашего первого шейдера

Рис. 4.5. Рабочее пространство и окно предварительного просмотра для вашего первого шейдера



netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz