суббота, 9 февраля 2013 г.

нарисовать виды архитектур

Интерфейсы могут друг от друга наследоваться, и большинство COM-интерфейсов, в том числе в Direct3D, наследуются от особенного интерфейса IUnknown, который реализует управление временем жизни объекта, реализующего интерфейс, через подсчет ссылок, и позволяет получать от объекта указатели на интерфейсы различных типов по их GUID.

Концепт COM-интерфейса близок по своей сути к концепту интерфейсов из .NET(потому как .NET это, фактически, развитие COM). По своей сути, это абстрактный класс, у которого есть только методы, и которому поставлен в соответствие некоторый 16-байтовый идентификатор(GUID). Физически, интерфейс это коллекция функций, то есть, указатель на массив с указателями на функции(с Си-совместимым ABI, и обычно с stdcall-конвенцией вызова), у которых первым аргументом идет указатель на сам интерфейс. За каждым интерфейсом стоит некоторый объект, который его реализует, и каждый объект может реализовать несколько различных типов интерфейсов. Microsoft постулирует, что единственный способ связаться с объектом, который реализует некоторый интерфейс это через указатель на этот интерфейс, а именно вызывая его методы.

Для тех, кто незнаком с понятием COM-интерфейса небольшое лирическое отступление.

API Direct3D основано на облегченном COM(Microsoft Component Object Model). Облегченном настолько, что от «полновесного» COM в нем остался только концепт интерфейсов.

Теперь собственно об API.

Output Merger(OM) последняя стадия графического конвейера. Для каждого фрагмента, полученного от пиксельного шейдера, проводит тест глубины и стенсил-тест, определяя, должен ли фрагмент попасть во фреймбуфер и производит смешивание цветов, если оно включено.

Pixel Shader(пиксельный шейдер, PS) работает с фрагментами изображения, полученными от растеризатора. Используется для реализации огромного многообразия графических эффектов, и на выход, в стадию Output Merger’а, отдает цвет фрагмента, и, опционально, значение глубины(значение, используемое для определения, какие фрагменты лежат ближе к камере).

Rasterizer (растеризатор, RS) «сердце» графического конвейера. Назначение этой стадии, как понятно из названия растеризация примитивов, то есть разбиение их на пиксели(хотя название «пиксель» не совсем корректно под пикселем обычно понимается то, что находится непосредственно во фреймбуфере, т.е. то, что отображается на экране, так что правильнее будет «фрагменты»). Растеризатор получет на вход векторную информацию о вершинах, от предыдущих стадий конвейера, и преобразовывает ее в растровую, отсекая примитивы вне области видимости, интерполируя значения, связанные с вершинами(такие, как текстурные координаты) и проецируя их позиции на двумерную область просмотра(англ. viewport). Данные от растеризатора поступают к пиксельному шейдеру, если тот установлен.

Stream Output(SO) необязательная стадия конвейера, используется для выгрузки обработанных конвейером вершин обратно в системную память(чтобы выхлоп SO мог быть считан CPU или использоваться конвейером при следующем запуске). Данные получает либо от геометрического шейдера, либо, в случае его отсутствия от вершинного или доменного.

Geometry Shader(геометрический шейдер, GS) обрабатывает примитивы(точки, линии или треугольники), собранные из вершин, обработанных предыдущими стадиями конвейера. Геометрические шейдеры могут генерировать новые примитивы на лету(то есть их выхлоп не обязательно должен быть 1-к-1, как в случае, например, вершиных шейдеров). Используются для генерации геометрии теней(shadow volume), спрайтов(системы частиц и пр.), отражений(напр. однопроходная отрисовка в cube map) и тому подобного. Хотя могут использоваться и для тесселяции, это не рекомендуется. Данные от геометрического шейдера поступают либо в Stream Output, либо в растеризатор.

Hull Shader(поверхностный шейдер, HS), Domain Shader(доменный шейдер, DS) и Tesselator(тесселятор) стадии, добавленные в Shader Model 5.0 (и D3D11, соответственно), и используемые в процессе тесселяции(разбиения примитивов на более мелкие, для повышения детализации изображения). Эти стадии конвейера опциональны, а так как в моей сцене они не используются, я не буду на них подробно останавливаться. Желающие могут почитать о них, например, на MSDN.

Vertex Shader (вершинный шейдер, VS) обязательная, и полностью программируемая стадия конвейера. Как несложно догадаться, запускается для каждой вершины(англ. vertex), и получает на вход данные о ней от Input Assembler’а. Используется для различного преобразования вершин, для трансформации их координат из одной координатной системы в другую, для генерации нормалей, текстурных координат, обсчета освещения и другого. Данные от вершинного шейдера поступают либо непосредственно растеризатору, либо в Stream Output(если данная стадия конвейера установлена, но геометрический шейдер нет), либо геометрическому шейдеру, либо поверхностному шейдеру.

Input Assembler (сокращенно IA) получает данные о вершинах из буферов, находящихся системной памяти и собирает из них примитивы, которые используются последующими стадиями конвейера. Также, IA прикрепляет к вершинам некоторые метаданные, генерируемые рантаймом D3D, такие как номер вершины.

Теперь объясню каждую из стадий по отдельности.

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

API Direct3D является прямым отражением архитектуры современных видеокарт, и инкапсулирует в себе графический конвейер следующего вида:

Начать следует с описания архитектуры Direct3D.

В этой статье, разделенной на несколько частей, я в общих чертах объясню архитектуру современных версий Direct3D(10-11), а также покажу, как с помощью этого API нарисовать вот такую вот сцену кораллового рифа, основным достоинством которой является простая в реализации, но красивая и относительно убедительно выглядящая вода:

Рисуем воду на Direct3D. Часть 1. Архитектура графического конвейера и API

Рисуем воду на Direct3D. Часть 1. Архитектура графического конвейера и API « Все об DirectX

Комментариев нет:

Отправить комментарий