Конвейер компьютерной графики , также известный как конвейер рендеринга или графический конвейер , представляет собой структуру компьютерной графики, которая описывает необходимые процедуры для преобразования трехмерной (3D) сцены в двумерное (2D) представление на экране. [1] После создания 3D-модели, будь то для видеоигры или любой другой формы компьютерной 3D- анимации , графический конвейер преобразует модель в визуально воспринимаемый формат на дисплее компьютера. [2] Из-за зависимости от конкретного программного обеспечения , аппаратных конфигураций и желаемых атрибутов отображения универсально применимого графического конвейера не существует. Тем не менее, интерфейсы программирования графических приложений (API), такие как Direct3D и OpenGL , были разработаны для стандартизации общих процедур и контроля графического конвейера данного аппаратного ускорителя. Эти API обеспечивают уровень абстракции над базовым оборудованием, избавляя программистов от необходимости писать код, явно ориентированный на различные аппаратные графические ускорители, такие как AMD , Intel , Nvidia и другие.
Модель графического конвейера обычно используется при рендеринге в реальном времени. Часто большинство шагов конвейера реализуются аппаратно, что позволяет проводить специальные оптимизации . Термин «конвейер» используется в том же смысле, что и конвейер в процессорах: отдельные шаги конвейера выполняются параллельно до тех пор, пока на каждом шаге есть то, что ему нужно.
3D-конвейер обычно относится к наиболее распространенной форме компьютерного 3D-рендеринга, называемой 3D - рендерингом полигонов , в отличие от трассировки лучей и рейкастинга . При рейкастинге луч возникает в точке, где находится камера, и если этот луч попадает на поверхность, вычисляется цвет и освещение точки на поверхности, куда попадает луч. При рендеринге 3D-полигонов происходит обратный процесс: вычисляется область, находящаяся в поле зрения камеры, а затем из каждой части каждой поверхности в поле зрения камеры создаются лучи, которые прослеживаются обратно к камере. [3]
Графический конвейер можно разделить на три основные части: приложение, геометрия и растеризация. [4]
Шаг приложения выполняется программным обеспечением на главном процессоре ( ЦП ). На этапе приложения в сцену вносятся изменения по мере необходимости, например, при взаимодействии пользователя с помощью устройств ввода или во время анимации. Новая сцена со всеми ее примитивами , обычно треугольниками, линиями и точками, затем передается на следующий шаг конвейера.
Примерами задач, которые обычно выполняются на этапе приложения, являются методы обнаружения столкновений , анимации, морфинга и ускорения с использованием схем пространственного подразделения, таких как Quadtrees или Octrees . Они также используются для уменьшения объема оперативной памяти, необходимой в данный момент. «Мир» современной компьютерной игры гораздо больше того, что может сразу уместиться в памяти.
Шаг геометрии (с Geometry Pipeline ), отвечающий за большинство операций с полигонами и их вершинами (с Vertex Pipeline ), можно разделить на следующие пять задач. То, как эти задачи организованы как реальные параллельные этапы конвейера, зависит от конкретной реализации.
Вершина (множественное число: вершины ) — это точка мира. Для соединения поверхностей используется множество точек. В особых случаях облака точек рисуются напрямую, но это все же исключение.
Треугольник – самый распространенный геометрический примитив компьютерной графики . Он определяется тремя вершинами и вектором нормали — вектор нормали служит для обозначения передней грани треугольника и представляет собой вектор, перпендикулярный поверхности. Треугольник может быть снабжен цветом или фактурой ( поверх него «наклеено» изображение). Треугольники предпочтительнее прямоугольников, поскольку три их точки всегда находятся в одной плоскости .
Мировая система координат — это система координат, в которой создается виртуальный мир. Это должно соответствовать нескольким условиям, чтобы можно было легко применить следующую математическую формулу:
Определение единицы измерения системы координат остается на усмотрение разработчика. Таким образом, будет ли единичный вектор системы соответствовать на самом деле одному метру или ангстрему, зависит от приложения.
Объекты, содержащиеся в сцене (дома, деревья, автомобили), часто проектируются в собственной системе координат объекта (также называемой системой координат модели или локальной системой координат) из соображений упрощения моделирования. Чтобы присвоить этим объектам координаты в мировой системе координат или глобальной системе координат всей сцены, координаты объекта преобразуются посредством перевода, вращения или масштабирования. Это делается путем умножения соответствующих матриц преобразования . Кроме того, из одного объекта может быть образовано несколько по-разному преобразованных копий, например из дерева лес; Этот метод называется созданием экземпляров.
Во-первых, нам нужны три матрицы вращения , а именно по одной на каждую из трех осей самолета (вертикальная ось, поперечная ось, продольная ось).
Мы также используем матрицу перемещения, которая перемещает самолет в нужную точку нашего мира: .
Теперь мы могли вычислить положение вершин самолета в мировых координатах, последовательно умножив каждую точку на эти четыре матрицы. Поскольку умножение матрицы на вектор является довольно дорогостоящим (отнимает много времени), обычно выбирают другой путь и сначала перемножают четыре матрицы вместе. Умножение двух матриц еще дороже, но должно выполняться только один раз для всего объекта. Умножения и эквивалентны. После этого полученную матрицу можно применить к вершинам. На практике, однако, умножение на вершины пока не применяется, а сначала определяются матрицы камер (см. ниже).
Порядок применения матриц важен, поскольку умножение матриц не является коммутативным . Это также относится к трем поворотам, что можно продемонстрировать на примере: Точка (1, 0, 0) лежит на оси X, если повернуть ее сначала на 90° вокруг X-, а затем вокруг Y-. оси, он оказывается на оси Z (вращение вокруг оси X не влияет на точку, находящуюся на оси). С другой стороны, если сначала вращаться вокруг оси Y, а затем вокруг оси X, результирующая точка окажется на оси Y. Сама последовательность произвольна, пока она всегда одинакова. Последовательность с x, затем y, затем z (крен, тангаж, курс) часто является наиболее интуитивно понятной, поскольку вращение приводит к совпадению направления компаса с направлением «носа».
Существует также два соглашения для определения этих матриц, в зависимости от того, хотите ли вы работать с векторами-столбцами или векторами-строками. Разные графические библиотеки имеют здесь разные предпочтения. OpenGL предпочитает векторы-столбцы, векторы-строки DirectX . Решение определяет, с какой стороны точечные векторы должны быть умножены на матрицы преобразования. Для векторов-столбцов умножение выполняется справа, т. е . где v out и v in — векторы-столбцы 4x1. Конкатенация матриц также производится справа налево, т.е., например , при сначала повороте, а затем сдвиге.
В случае векторов-строок это работает с точностью до наоборот. Умножение теперь происходит слева, как и в случае векторов размером 1x4, а конкатенация происходит тогда, когда мы также сначала вращаемся, а затем перемещаемся. Матрицы, показанные выше, действительны для второго случая, тогда как матрицы для векторов-столбцов транспонируются. Применяется правило [5] , которое для умножения на векторы означает, что вы можете переключать порядок умножения, транспонируя матрицу.
В цепочке матриц каждое преобразование определяет новую систему координат, что позволяет гибко расширять ее. Например, пропеллер самолета, смоделированный отдельно, можно прикрепить к носовой части самолета посредством перемещения, которое лишь смещается от модели к системе координат пропеллера. Чтобы визуализировать самолет, сначала вычисляется его матрица преобразования для преобразования точек, а затем умножается матрица модели пропеллера на матрицу самолета для точек пропеллера. Эта рассчитанная матрица известна как «мировая матрица», необходимая для каждого объекта в сцене перед рендерингом. Затем приложение может динамически изменять эти матрицы, например обновлять положение самолета в каждом кадре в зависимости от скорости.
Вычисленную таким образом матрицу еще называют мировой матрицей . Перед рендерингом его необходимо определить для каждого объекта в мире. Приложение может вносить сюда изменения, например менять положение самолета в зависимости от скорости после каждого кадра.
Помимо объектов, сцена также определяет виртуальную камеру или средство просмотра, которое указывает положение и направление обзора, относительно которого визуализируется сцена. Сцена трансформируется так, что камера находится в начале координат и смотрит вдоль оси Z. Результирующая система координат называется системой координат камеры, а преобразование называется преобразованием камеры или преобразованием представления .
Zaxis = normal(cameraPosition - cameraTarget)
Xaxis = normal(cross(cameraUpVector, Zaxis))
Yaxis = cross(Zaxis, Xaxis )
Шаг 3D-проекции преобразует объем вида в куб с координатами угловой точки (-1, -1, 0) и (1, 1, 1); Иногда используются и другие целевые тома. Этот шаг называется проекцией , хотя он преобразует один объем в другой объем, поскольку полученные координаты Z не сохраняются в изображении, а используются только в Z-буферизации на последующем этапе растрирования. На перспективной иллюстрации используется центральная проекция . Для ограничения количества отображаемых объектов используются две дополнительные плоскости отсечения; Таким образом, зрительный объем представляет собой усеченную пирамиду ( frustum ). Параллельная или ортогональная проекция используется, например, для технических изображений, поскольку она имеет то преимущество, что все параллели в пространстве объекта также параллельны в пространстве изображения, а поверхности и объемы имеют одинаковый размер независимо от расстояния от зрителя. . В картах используется, например, ортогональная проекция (так называемая ортофото ), но косые изображения ландшафта таким образом использовать нельзя — хотя технически их можно визуализировать, но они кажутся настолько искаженными, что мы не можем ими воспользоваться. Формула для расчета матрицы отображения перспективы:
Причины, по которым здесь необходимо указывать наименьшее и наибольшее расстояние, заключаются, с одной стороны, в том, что это расстояние делится на, чтобы достичь масштабирования сцены (более удаленные объекты на перспективном изображении меньше, чем близкие объекты). , а с другой стороны, масштабировать значения Z до диапазона 0..1 для заполнения Z-буфера . Этот буфер часто имеет разрешение всего 16 бит, поэтому значения ближнего и дальнего света следует выбирать осторожно. Слишком большая разница между ближним и дальним значением приводит к так называемой Z-борьбе из-за низкого разрешения Z-буфера. Из формулы также видно, что ближайшее значение не может быть равно 0, поскольку эта точка является точкой фокуса проекции. На данный момент изображения нет.
Для полноты картины формула параллельной проекции (ортогональной проекции):
Из соображений эффективности камера и матрица проекции обычно объединяются в матрицу преобразования, так что система координат камеры опускается. Результирующая матрица обычно одинакова для одного изображения, тогда как мировая матрица выглядит по-разному для каждого объекта. Таким образом, на практике вид и проекция заранее рассчитываются так, что во время отображения необходимо адаптировать только мировую матрицу. Однако возможны и более сложные преобразования, такие как смешивание вершин. Также могут быть выполнены свободно программируемые шейдеры геометрии , которые изменяют геометрию.
На этапе фактического рендеринга вычисляется мировая матрица * матрица камеры * матрица проекции, а затем, наконец, применяется к каждой отдельной точке. Таким образом, точки всех объектов переносятся непосредственно в экранную систему координат (по крайней мере почти, диапазон значений осей по-прежнему -1..1 для видимого диапазона, см. раздел «Окно-Вьюпорт-Трансформация»).
Часто сцена содержит источники света, расположенные в разных местах, чтобы освещение объектов выглядело более реалистичным. В этом случае коэффициент усиления текстуры рассчитывается для каждой вершины на основе источников света и свойств материала, связанных с соответствующим треугольником. На более позднем этапе растеризации значения вершин треугольника интерполируются по его поверхности. Ко всем поверхностям применяется общее освещение (рассеянный свет). Это рассеянная и, следовательно, независимая от направления яркость сцены. Солнце — это направленный источник света, который можно считать бесконечно далеким. Освещенность, действующая на поверхность солнцем, определяется путем формирования скалярного произведения вектора направления от Солнца и вектора нормали к поверхности. Если значение отрицательное, поверхность обращена к солнцу.
Только примитивы, находящиеся в пределах визуального объема, должны быть растрированы (нарисованы). Этот визуальный объем определяется как внутренняя часть усеченной пирамиды , формы в виде пирамиды со срезанной вершиной. Примитивы, полностью находящиеся за пределами визуального объема, отбрасываются; Это называется отбраковкой усеченного конуса . Дальнейшие методы отбора, такие как обратный отбор, которые уменьшают количество рассматриваемых примитивов, теоретически могут выполняться на любом этапе графического конвейера. Примитивы, которые лишь частично находятся внутри куба, должны быть обрезаны по кубу. Преимущество предыдущего шага проецирования состоит в том, что отсечение всегда происходит по одному и тому же кубу. На последний шаг передаются только примитивы (возможно, обрезанные), находящиеся в пределах визуального объема.
Чтобы вывести изображение в любую целевую область (окно просмотра) экрана, необходимо применить другое преобразование — преобразование «Окно-Вьюпорт ». Это сдвиг, за которым следует масштабирование. Полученные координаты являются координатами устройства вывода. Окно просмотра содержит 6 значений: высоту и ширину окна в пикселях, верхний левый угол окна в координатах окна (обычно 0, 0), а также минимальное и максимальное значения Z (обычно 0 и 1).
На современном оборудовании большая часть шагов вычисления геометрии выполняется в вершинном шейдере . Это, в принципе, свободно программируется, но обычно выполняет как минимум преобразование точек и расчет освещенности. Для интерфейса программирования DirectX начиная с версии 10 необходимо использование собственного вершинного шейдера, тогда как в более старых версиях все еще есть стандартный шейдер.
Шаг растеризации — это последний шаг перед конвейером фрагментного шейдера, с помощью которого растеризуются все примитивы . На этапе растеризации из непрерывных примитивов создаются дискретные фрагменты.
На этом этапе графического конвейера точки сетки также называются фрагментами для большей различимости. Каждый фрагмент соответствует одному пикселю в буфере кадра, а это соответствует одному пикселю экрана. Они могут быть цветными (и, возможно, с подсветкой). Кроме того, необходимо определить видимый, ближайший к наблюдателю фрагмент в случае перекрывающихся полигонов. Для определения так называемой скрытой поверхности обычно используется Z-буфер . Цвет фрагмента зависит от освещения, текстуры и других свойств материала видимого примитива и часто интерполируется с использованием свойств вершины треугольника. Там, где это возможно, фрагментный шейдер (также называемый пиксельным шейдером ) запускается на этапе растра для каждого фрагмента объекта. Если фрагмент виден, его теперь можно смешать с уже существующими значениями цвета в изображении, если используется прозрачность или множественная выборка. На этом этапе один или несколько фрагментов становятся пикселями.
Чтобы пользователь не видел постепенной растеризации примитивов, используется двойная буферизация. Растеризация осуществляется в специальной области памяти. После полной растеризации изображения оно копируется в видимую область памяти изображений.
Все используемые матрицы невырождены и, следовательно, обратимы. Поскольку умножение двух неособых матриц создает еще одну неособую матрицу, вся матрица преобразования также обратима. Обратное требуется для пересчета мировых координат из экранных координат - например, чтобы определить по положению указателя мыши объект, по которому щелкнули. Однако, поскольку экран и мышь имеют только два измерения, третье неизвестно. Поэтому в месте положения курсора проецируется луч в мир и затем определяется пересечение этого луча с полигонами в мире.
Классические видеокарты все еще относительно близки к графическому конвейеру. С ростом требований к графическому процессору ограничения постепенно снимались, чтобы обеспечить большую гибкость. Современные видеокарты используют свободно программируемый конвейер, управляемый шейдерами, который обеспечивает прямой доступ к отдельным этапам обработки. Чтобы разгрузить основной процессор, дополнительные этапы обработки были перенесены на конвейер и графический процессор.
Наиболее важными модулями шейдеров являются вершинные шейдеры , геометрические шейдеры и пиксельные шейдеры .
Был введен унифицированный шейдер , позволяющий в полной мере использовать преимущества всех юнитов. Это дает один большой пул шейдерных блоков. По мере необходимости пул делится на разные группы шейдеров. Поэтому строгое разделение типов шейдеров больше не имеет смысла.
Также можно использовать так называемый вычислительный шейдер для выполнения любых вычислений без отображения графики на графическом процессоре. Преимущество в том, что они работают очень параллельно, но есть ограничения. Эти универсальные вычисления также называются вычислениями общего назначения на графических процессорах , или сокращенно GPGPU .
Меш-шейдеры — это недавнее дополнение, целью которого является преодоление узких мест фиксированной компоновки геометрического конвейера. [6]