3D-ускорители. Теория {ver}
Звуковая часть поддерживала одновременно 50 звуковых каналов, ЗD-ядро было достаточно оригинальным, работа велась с кривыми поверхностями 3-го порядка, поддерживалось затенение по Фонгу (Phong), чего до сих пор нет ни у одного игрового ЗD-ускорителя. С тех пор это наиболее активно развивающаяся область рынка, попробовать себя в которой стремится каждая компания, имеющая (или не имеющая) хоть какое-нибудь отношение к производству чипов ускорителей.
Как это работает
Рассмотрим основные стадии построения изображения ЗD-объекта. Для начала из плоских многоугольников или криволинейных поверхностей создается объект. Его поверхности назначаются текстуры (то есть картинки, имитирующие материал, из которого сделана поверхность моделируемого объекта), вводятся параметры отражения, карта рельефа поверхности, карта отражения и т.д. На сцене размещаются источники света, при необходимости вводится осветляющий (обычный) или затемняющий (для эмуляции ночных условий) туман, и задается направление взгляда наблюдателя (камера). Далее объект обрабатывается в такой последовательности:
- Тесселяция (Tesselation). На этом этапе объект, образованный плоскими или криволинейными поверхностями, приводится к сеточному виду, то есть поверхность разбивается на треугольники (естественно, для криволинейных поверхностей разбиение производится с некой точностью, достаточной для имитации гладкой поверхности, рис. 1).
- Геометрические трансформации (Geometry Transformation, рис. 2), то есть вращение, перемещение, изменение масштаба ЗD-объекта. Полная трансформация подразумевает перемножение соответствующей матрицы преобразований размерностью 4х 4, на векторы вершин полученных треугольников размерностью 4х! (X,Y,Z, 1).
- Расчет освещенности сцены (Lighting). Здесь для каждой вершины вычисляются значения освещенности исходя из расположе ния и типа источников света (рассеянный свет, точечный источник, направленный источник и т.д.) и параметров, характеризующих поверхность объекта (отражения, поглощения).
- Отсечение (Clipping). Производится удаление тех частей объекта, которые не попадают в зону видимости (как в пределах экрана, так и на некотором расстоянии), то есть в общем случае задается некоторая область в пространстве, при выходе из которой части объекта считаются невидимыми (рис. 3).
- Проецирование сеточной поверхности на плоскость (Projection) с учетом (рис. 4) или без учета (рис. 5) перспективы.
- Окончательная подготовка треугольников (Triangle Setup) перед (Рис. 2 Рис. 3) выводом на экран. На этом этапе рассчитывается освещение вдоль ребер треугольников на основании данных об освещенности вершин, а исходя из этих данных и направления градиентов изменения — цвет (затенения) всего треугольника (в случае наиболее простого и популярного затенения по методу Гуро, рис. 6Ь). Также производится преобразование данных о примитивах в форму, удобную для дальнейшей обработки (например, числа с плавающей точкой при необходимости приводятся к целому числу для оптимизации вычислений).
- Окончательное затенение, или растеризация (Rasterisation) объекта и удаление невидимых поверхностей (Hidden Surface Removal), то есть заслоняемых другими. Растеризация включает в себя наложение текстур (их может быть несколько для одной поверхности) с учетом их взаимодействия, то есть производится учет прозрачности, перспективы, уровня и метода детализации (LOD, Level Of Detail), метода фильтрации (линейная, билинейная, бикубическая), затуманивания и т.п.
- Окончательная обработка (Post processing). Самой последней стадией является работа с готовым изображением, куда можно отнести, например, антиалиасинг (antialiasing), заключающийся в сглаживании границ объектов после их растеризации (в частном случае это удаление так называемого лестничного эффекта, проявляющегося на наклонных линиях). Для этого, например, изображение изначально рассчитывается в большем разрешении, чем выводимое на экран, и уменьшается с вычислением среднего значения цвета для матрицы из нескольких рядом стоящих пикселов исходного изображения. Стоит отметить, что термин «растеризация» иногда применяется и по отношению ко всему процессу построения окончательного изображения, но обычно для этого используется термин «рендеринг».
В общем случае если игровой ускоритель имеет только аппаратный блок растеризации (с поддержкой текстурирования), то он выполняет только седьмую и восьмую стадии. Если имеется так называемое ядро подготовки треугольников (Triangle Setup Engine), то ускоритель выполняет при обработке изображения стадии 6, 7 и 8. Ну, а если у ЗD-ускорителя имеется и аппаратный геометрический процессор (geometry processor), то он берет на себя все стадии обработки изображения. Вообще говоря, сейчас принято выделять в ЗD-акселераторе несколько основных частей, характеристики которых дают базовое представление о ЗD-акселераторс. Это блок геометрии, блок растеризации и память, включающая буфер кадров (frame buffer), буфер глубины (2-бу-фер), буфер шаблонов и текстурную память (Texture memory). Рассмотрим все это несколько подробнее и начнем с самого простого — с буферов.
Буфер кадров
Кадровый буфер — это та часть памяти ЗD-ускорителя, в которой строится окончательное изображение 3D-сцены. Обычно используется два кадровых буфера — передний (front) и задний (back). Передний буфер отображается на экране монитора, в нем находится изображение текущего кадра. В заднем буфере происходит построение следующего кадра.
После того как кадр построен, буферы меняются местами. Смена их должна происходить строго в тот момент, когда монитор завершил отображение кадра. Если это правило не соблюдается, то происходит разрыв изображения по горизонтали (в верхней части прежнее изображение, в нижней — уже новое). Некоторые акселераторы позволяют использовать три буфера (в играх это называется triple buffering); в этом случае один кадр отображается, второй держится наготове, а следующий начинает строиться. Это придает большую плавность играм, но одновременно вносит лишние задержки на ответную реакцию пользователя (игрока). Впрочем, если в игре просчитывается более 60 кадров в секунду, то, учитывая скорость опроса клавиатуры, — 30 раз в секунду, это не столь существенно.
От размера буфера кадров зависит, с каким максимальным разрешением и глубиной цвета может работать 3D-yc- (Рис. 6) коритель. Объем памяти, требующийся для буфера кадров, рассчитывается исходя из разрешения по вертикали и горизонтали и глубины цвета, используемого для рендеринга изображения, и числа кадровых буферов. Например, если нужно работать в разрешении 1024Х768 при глубине цвета 32 бит и используется три кадровых буфера, то потребуется ускоритель, имеющий на борту кадровый буфер объемом 1024x768x4x3=9437 184 байт, то есть около 9 Мбайт. Для разрешения же 640Х480 при глубине цвета 16 бит и использовании только переднего и заднего буферов потребуется всего 640x480x2x2=1 228 800 байт, то есть всего 1,2 Мбайт.
Стоит также отметить, что кадровым буфером могут также называть всю ту память ускорителя, которая используется для построения изображения (это две или три страницы и Z-буфер). Так, например, на акселераторах VooDoo память делят на две части — текстурную память, где хранятся текстуры, и Frame buffer, где располагается буфер кадров и Z-буфер.
Z-буфер
Z-буфер используется главным образом для определения перекрывающихся частей полигонов (многоугольников), составляющих ЗD-модель. В более сложных случаях он используется специальным алгоритмом для удаления невидимых линий (поверхностей). В общем случае представляет собой двухмерный массив, содержащий значения глубины расположения соответствующей точки на экране (Z-координату). В результате программа путем простого сравнения глубины расположения точек полигонов узнает, точку какого из них необходимо отобразить. В случае с ЗО-ускорителем таким сравнением занимается не программа, а сам 3D-ускоритель. Естественно, под Z-буфер необходимо отвести память на самом ускорителе. Размерность Z-буфера равна текущему разрешению буфера кадров, а глубина его у каждого ускорителя своя; в большинстве случаев это 16-битный буфер, хранящий целые значения. В современных акселераторах все чаще используются Z-бу-феры глубиной 24 или 32 бита, хранящие значение с плавающей точкой типа Single. При отключенном Z-бу-фере начинают появляться неприятные эффекты, связанные с перекрытием видимых полигонов невидимы-; ми (так называемый Z-aliasing).
В большинстве ускорителей память отводится одновременно под буфер кадров, Z-буфер и текстуры. Поэтому в играх с малым набором пересекающихся поверхностей, например Tomb Raider, где Z-алиасинг несильно заметен, Z-буфером можно пожертвовать, если это позволяют сделать игра и ускоритель, в пользу большего разрешения или большего объема памяти, отводимого под текстуры.
Буфер шаблонов
Буфер шаблонов (Stencil buffer) достаточно недавно получил распространение в игровых ЗD-акселераторах. Принципиально, что, как и Z-буфер, он представляет собой двухмерный массив с размерностью равной текущему разрешению кадрового буфера. Глубина его колеблется от 1 до 32 бит. Используется для некоторых специфических эффектов при растеризации изображения. Например, можно производить вывод окончательного изображения в кадровый буфер только в тех точках, для которых в буфере шаблонов записана некоторая определенная величина.
Ядро подготовки треугольников
Ядро подготовки треугольников (Triangle Setup Engine) занимается только заключительными стадиями геометрической обработки 3D-объектов:
- Переводит координаты вершин из формата strips/fans в полные треугольники.
- Рассчитывает освещение полигонов на основании данных об освещении их вершин.
- Рассчитывает коррекцию перспективы для текстур.
- Преобразует данные к формату, используемому при последующей обработке изображения.
Первый пункт может вызвать у тех, кто не знаком с ЗD-графикой, резонный вопрос: что такое strips/fans. Объяснение начнем с того очевидного факта, что каждый треугольник имеет три вершины, и, соответственно, в ЗП-акселератор нужно передать координаты всех трех вершин для каждого треугольника из сетки, составляющей объект. Это как минимум три тройки чисел в формате с плавающей точкой (4 байта на число для формата single), не считая данных об освещенности и каких-либо дополнительных параметров. В результате получаем, что для описания одного треугольника необходимо передать минимум 36 байт. В современных играх персонажи описываются сетками из сотен треугольников; в будущих играх это число обещают поднять до нескольких тысяч. В результате объем данных, описывающих одного персонажа, состоящего, допустим, из 1000 треугольников, которые необходимы для одной секунды работы при приемлемой скорости обработки 3D-rpa-фики — 30 кадров в секунду, составляет около 1 Мбайт. Очевидно, что при наличии нескольких объектов такой сложности объем передаваемых данных увеличивается прямо пропорционально их числу, и достаточно вам будет в какой-нибудь игре встретить сразу 50 врагов, как передача только координат, описывающих их вершины, займет одну десятую часть от пропускной способности шины AGP, работающей в режиме х2.
Простейшим решением этой проблемы является передача координат только одной вершины для нескольких смежных треугольников, поскольку все треугольники, составляющие объект, соприкасаются между собой. Простейшими фигурами из треугольников являются «полосы» (strips, рис. 7) и «вентиляторы» (fans, рис. 8); полосы представляют собой кусок поверхности, образованный двумя линиями и разделенный на треугольники по всей длине, в результате необходимо передавать только координаты вершин, находящиеся на этих линиях. «Вентилятор» — это фигура, составленная из нескольких треугольников, имеющих общую вершину. На соответствующие треугольники эти фигуры разделяет сам ускоритель. И в идеале описание каждого треугольника, кроме самого первого, сводится к передаче только одной вершины, что уменьшает объем передаваемых данных почти в три раза.
Затенение
Для того чтобы увидеть объект, нам нужно его осветить, как и в программах ЗD-графики. Таким образом, для создания окончательного изображения необходимо задать некоторую модель освещения. Реальная модель освещения исключительно сложна для воспроизведения на персональном компьютере, поэтому в 3D-гpaфике используются упрощенные модели освещения (то есть взаимодействия источников света и 3D-объектов внутри обрабатываемой сцены). Кроме того, необходимо использовать специальные методы раскраски самих объектов, ведь вместо реальной поверхности мы имеем набор плоских треугольников. Чаще всего используются следующие простые методы затенения Flat (плоское, рис. 6а), Gouraud (Гуро, рис. 6Ь) и Phong (Фонга, рис. 6с).
При плоском затенении на основании данных об оснещенности вершин треугольника рассчитывается среднее значение освещенности всей его поверхности. Этот метод самый быстрый, но при его использовании практически невозможно получить сколь-нибудь реальное изображение гладкой поверхности. При затенении по методу Гуро на основании данных об освещенности вершин интерполируются значения освещенности по ребрам треугольника, и далее рассчитываются значения освещенности для каждого пиксела поверхности треугольника. Метод дает существенно лучший по качеству результат, но наблюдается эффект «звездочных» бликов. Затенение по Фонгу работает совершенно иначе: вместо интерполяции данных об освещенности по ребрам треугольника интерполируются нормали к поверхности объекта, заданные в вершинах треугольника, после чего интерполируются нормали для каждой точки треугольника, и на основании данных о кривизне, расположении источников света и наблюдателя для каждой точки поверхности треугольника рассчитывается освещенность. Метод вместе с моделью освещения Фонга дает один из самых лучших результатов освещения и широко используется в программах ЗО-моделиро-вания. К сожалению, этот метод довольно трудоемкий и на современных игровых ЗD-ускорителях пока не применяется.

Взято из книги Real-time Rendering:
1) Model and View Transform
2) Vertex Shading
3) Projection
4) Clipping
5) Screen Maping
6) Triangle Setup
7) Triangle Traversal
9) Merging
1-5 это The Geometry Stage
6-9 относится к Rasterization