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

Программируемый конвейер и возможности вершинных и пиксельных шейдеров

Модель 2.0 вершинных и пиксельных шейдеров принесла в язык множество значительных усовершенствований, по сравнению с появившимися в DirectX 8.0 версиями 1.0 и 1.1. Поскольку уже вышел DirectX 9.0 и выпущены видеокарты, совместимые с версиями 2.0 вершинных и пиксельных шейдеров, книга сосредотачивается на разработке шейдеров, основанных именно на этой технологии.

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

Я предполагаю, что вы уже обладаете базовыми знаниями трехмерной графики, поэтому позвольте начать с краткого обзора значительных изменений, внесенных во второе поколение шейдеров по сравнению с их предшественниками.

Вершинные шейдеры версий 2.0 и 2.1 включают следующие усовершенствования:

Следующий список перечисляет усовершенствования, внесенные в пиксельные шейдеры 2.0 и 2.x:

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

ПРИМЕЧАНИЕ
Поскольку мы сосредотачиваемся главным образом на использовании Microsoft HLSL, то не будем детально обсуждать инструкции и синтаксис, применяемые при написании шейдеров непосредственно на языке ассемблера. Если вы пишете шейдер на ассемблере, он состоит из набора простых инструкций непосредственно выполняемых процессором видеокарты. Однако это делает программирование более сложным, поскольку вам приходится управлять переменными и регистрами, и некоторые простые концепции транслируются в несколько инструкций ассемблера. С другой стороны, HLSL — это язык высокого уровня, позволяющий вам писать шейдеры более логическим способом, не отвлекаясь на различные надоедливые вопросы микро-управления, возникающие при ручном написании шейдеров на ассемблере.
За дополнительной информацией вы можете обратиться к поставляемой с DirectX 9.0 SDK документации, которая есть на прилагаемом к книге компакт-диске.

Представлять трехмерное окружение в терминах истинного объемного представления слишком дорого. Как я покажу позже, такое представление потребовало бы значительных процессорных мощностей и большого объема памяти. Большинство объектов являются твердыми и непрозрачными, и вы видите только их внешние формы. Когда вы смотрите на яйцо, то видите только его внешнюю сторону и, просто посмотрев на него, не можете сказать есть ли у него что-нибудь внутри. Поэтому трехмерная графика упрощается, беря на вооружение эту идею и представляя только внешнюю оболочку объекта, вместо того, чтобы пытаться представить его в целом. Думайте об этом, как о создании фигурки из папье-маше, для которой сперва надо создать задающий форму проволочный каркас.

В трехмерной графике эта проволочная сетка представляется набором полигонов, соединенных в форме объекта. Каждую оконечность полигона называют вершиной (vertex). Вершины — это ядро трехмерной графики, поскольку они несут всю необходимую для представления геометрии информацию, такую как местоположение, цвет и данные текстуры.

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

При визуализации трехмерной графики информация передается графическому оборудованию через API визуализации, такой как Direct3D или OpenGL. Как только эта информация получена, видеокарта выполняет программу вершинного шейдера для каждой вершины вашей сетки. На рис. 1.1 показана определяемая спецификацией функциональная диаграмма реализации вершинных шейдеров 2.0.


Рис. 1.1. Функциональная диаграмма архитектуры оборудования для вершинных шейдеров

Рис. 1.1. Функциональная диаграмма архитектуры оборудования для вершинных шейдеров


Как видно на рис. 1.1, вершины поступают потоком, который предоставляется разработчиком через API трехмерной визуализации, такой как Direct3D или OpenGL. Поток содержит всю информацию, необходимую для правильной обработки геометрии в процессе визуализации, такую как координаты местоположения, цвета и координаты текстуры. Поступившая информация помещается в соответствующие входные регистры от v0 до v15 и может использоваться программой вершинного шейдера. Это означает, что каждая вершина обрабатывается индивидуально и ее описание может содержать до 16 блоков информации, передаваемых через входные регистры. Программа вершинного шейдера имеет доступ ко многим другим регистрам, необходимым ей для выполнения своей задачи, состоящей в получении входных данных, их обработке и преобразовании в форму, которая используется пиксельным шейдером для выполнения итогового затенения и визуализации.

Регистры констант доступны только для чтения, должны быть инициализированы заранее и используются для хранения статических данных шейдера. Согласно стандарту вершинных шейдеров 2.0, регистры констант являются векторами и могут хранить числа с плавающей точкой, целые числа или логические значения. Обратите внимание, что регистры вершинного шейдера представляют собой четырехкомпонентные векторы, причем их отдельные компоненты могут обрабатываться параллельно или в индивидуальном порядке с помощью адресной выборки и маскирования.

С левой стороны рис. 1.1 расположены временные регистры, предназначенные для хранения генерируемых вершинным шейдером промежуточных результатов. Очевидно, что согласно своему назначению, эти регистры доступны и для чтения и для записи. Обратите внимание на регистры с именами a0 и aL. Это счетчики для индексной адресации и управления циклами. Это особый случай, а все остальные регистры могут использоваться внутри вашего шейдера для любых нужных вам целей. Также следует помнить, что поскольку HLSL — это язык высокого уровня, вам не надо заботиться о распределении регистров. Это происходит независимо от вас во время компиляции шейдера в его исполняемую форму.

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

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

Интерполяцией (interpolation) называется процесс в ходе которого на основании данных вершин полигона формируются соответствующие данные для каждого его пикселя. Вообразите линию от одной вершины к другой. Если одна вершина белая, а другая черная, то для точек в середине линии вам требуется промежуточный цвет, серый. Интерполяция осуществляет тот же процесс, но для всего треугольника. Процесс отсечения, в свою очередь, проверяет какие части треугольника видны на экране. Он позволяет не тратить впустую драгоценное время, занимаясь затенением невидимых частей полигонов. Благодаря этому сокращается общий объем работы, которую должна выполнить видеокарта. После того, как растеризатор определит параметры пикселя, для каждого отображаемого на экране пикселя вызывается пиксельный шейдер. На рис. 1.2 приведена функциональная диаграмма архитектуры пиксельных шейдеров.


Рис. 1.2. Функциональная диаграмма архитектуры оборудования для пиксельных шейдеров

Рис. 1.2. Функциональная диаграмма архитектуры оборудования для пиксельных шейдеров


Как видно из диаграммы на рис. 1.2, аппаратура передает вычисленные пиксели через входные регистры цвета и регистры текстуры. Эти значения вычисляются путем перспективной интерполяции значений, сформированных вершинным шейдером. Регистры v0 и v1 предназначаются для интерполяции рассеиваемой и отражаемой компонент освещения. Регистры с t0 по tN содержат интерполированные координаты просмотра текстуры. Можно заметить, что на рис. 1.2 к регистрам текстуры идут двунаправленные стрелки. Это объясняется конструкторским решением, которое позволяет выполнять запись в регистры текстуры и использовать их в качестве временных регистров. И, наконец, регистры с s0 по sN указывают на текстуры из которых пиксельный шейдер будет осуществлять выборку во время обработки пикселя. Хотя назначение этих регистров явно указано, они могут применяться для передачи от вершинного шейдера к пиксельному любой информации.

Регистры констант с c0 по cN доступны только для чтения и разработчик должен заранее записать в них значения, которые будут использоваться шейдером. И, наконец, временные регистры с r0 по rN, доступны для чтения и для записи и используются для хранения промежуточных результатов в ходе обработки пикселя. Когда вы используете HLSL распределение регистров выполняется автоматически без участия пользователя.

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

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

Большинство регистров в пиксельных шейдерах, за исключением нескольких адресных регистров, являются векторами, состоящими из четырех значений с плавающей точкой. Преимущество векторной архитектуры состоит в возможности одновременной обработки нескольких значений. По умолчанию все значения с плавающей точкой обрабатываются как 32-разрядные. Однако спецификация пиксельных шейдеров позволяет работать и с 16-разрядными значениями с плавающей точкой, для чего предусмотрены специальные инструкции. В некоторых аппаратных реализациях вычисления с 16-разрядными значениями выполняются значительно быстрее.

Следует отметить еще, что для векторов в вершинных и пиксельных шейдерах предусмотрены операции адресной выборки и маскирования, позволяющие работать с отдельными компонентами. Операция адресной выборки (swizzling) позволяет получить произвольную комбинацию компонент вектора. Дополнительную информацию об адресной выборке и маскировании вы найдете в справочнике по HLSL из приложения А.

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

ПРИМЕЧАНИЕ
Хотя в DirectX 9 появились вершинные и пиксельные шейдеры версии 3.0, мы не будем сосредотачиваться на использовании их новых возможностей. Они были добавлены как поддержка возможностей будущих видеокарт и во время написания книги не могли применяться для визуализации в реальном времени.

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

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