Конвейер преобразования Direct3D
В этой статье содержится техническое объяснение для разработчиков приложений Direct3D о том, как задать параметры конвейера преобразования Direct3D путем прямого обращения с матрицами Direct3D.
Общие сведения
В Direct3D используется три преобразования для перевода координат трехмерной модели в координаты пикселей (пространство экрана). Эти преобразования — мировое преобразование, видовое преобразование и проекционное преобразование.
Преобразование мира управляет тем, как координаты модели преобразуются в мировые координаты. Преобразование мира может включать переводы, повороты и масштабирование, но оно не применяется к свету. Дополнительные сведения о работе с преобразованиями мира см. в разделе Преобразование мира.
Преобразование представления управляет переходом от мировых координат к "пространству камеры", определяя положение камеры в мире. Пример работы с преобразованиями представлений см. в разделе Преобразование представления.
Преобразование проекции изменяет геометрию из пространства камеры в "пространство клипа" и применяет искажение перспективы. Термин "пространство клипа" относится к тому, как геометрия обрезается в томе представления во время этого преобразования. Пример работы с преобразованиями проекции см. в разделе Преобразование проекции.
Наконец, геометрия в пространстве клипа преобразуется в пиксельные координаты (пространство экрана). Это преобразование управляется параметрами окна просмотра.
Обрезка и преобразование вершин должны происходить в однородном пространстве (проще говоря, в пространстве, в котором система координат включает четвертый элемент), но конечным результатом для большинства приложений должны быть неоднородные трехмерные (трехмерные) координаты, определенные в "пространстве экрана". Это означает, что входные вершины и том обрезки должны быть преобразованы в однородное пространство для выполнения обрезки, а затем переведены обратно в неоднородное пространство для отображения.
Три преобразования Direct3D — мир, представление и преобразование проекции — определяются матрицами Direct3D. Матрица Direct3D — это однородная матрица 4x4, определяемая структурой D3DMATRIX . Хотя матрицы Direct3D не являются стандартными объектами, они не представлены интерфейсом COM, их можно создавать и задавать так же, как и любой другой объект Direct3D. Дополнительные сведения о матрицах Direct3D см. в разделе Преобразования.
Конвейер преобразования
Если вершина в координате модели задается pm = (Xm, Ym, Zm, 1), то преобразования, показанные на следующем рисунке, применяются к координатам экрана вычислений Ps = (Xs, Ys, Zs, Ws).
Ниже приведены описания этапов, показанных на предыдущем рисунке:
Мировая матрица Mworld преобразует вершины из пространства модели в мировое пространство. Эта матрица задается следующим образом:
d3dDevice->SetTransform (D3DTRANSFORMSTATE_WORLD, matrix address)
Реализация Direct3D предполагает, что последний столбец этой матрицы — (0, 0, 0, 1). Ошибка не возвращается, если пользователь указывает матрицу с другим последним столбцом, но освещение и туман будут неправильными.
Матрица просмотра Mview преобразует вершины из мирового пространства в пространство камеры. Эта матрица задается следующим образом:
d3dDevice->SetTransform (D3DTRANSFORMSTATE_VIEW, matrix address)
Реализация Direct3D предполагает, что последний столбец этой матрицы — (0, 0, 0, 1). Ошибка не возвращается, если пользователь указывает матрицу с другим последним столбцом, но освещение и туман будут неправильными.
Матрица проекции MPROJ преобразует вершины из пространства камеры в пространство проекции. Эта матрица задается следующим образом:
d3dDevice->SetTransform (D3DTRANSFORMSTATE_PROJECTION, matrix address)
Последний столбец матрицы проекции должен быть (0, 0, 1, 0) или (0, 0, a, 0) для правильных эффектов тумана и освещения; Форма (0, 0, 1, 0) является предпочтительной.
Объем обрезки для всех точек Xp = (Xp, Yp, Zp, Wp) в пространстве проекции определяется следующим образом:
-Wp < Xp <= Wp -Wp < Yp <= Wp 0 < Zp <= Wp
Все точки, которые не удовлетворяют этим уравнениям, будут обрезаются.
Если том представления определен как:
- Ширина окна sw-экрана в пространстве камеры в близкой плоскости обрезки
- Высота окна sh-screen в пространстве камеры в близкой плоскости обрезки
- Zn-расстояние до ближней плоскости обрезки вдоль осей Z в пространстве камеры
- Zf-расстояние до дальней плоскости обрезки вдоль осей Z в пространстве камеры
тогда матрицу проекции перспективы можно написать следующим образом:
где Mij являются членами Mproj.
Для ортогональной проекции мы имеем:
Direct3D предполагает, что матрица проекции перспективы имеет вид:
Если матрица проекции перспективы не имеет такой формы, будут присутствовать некоторые артефакты. Например, табличный туман не будет работать.
Direct3D позволяет пользователю изменять том клипа следующим образом:
Это можно переписать следующим образом:
где:
Cx, Cy - dvClipX, dvClipY from D3DVIEWPORT9 Cw, Ch - dvClipWidth, dvClipHeight from D3DVIEWPORT9 Zmin, Zmax - dvMinZ, dvMaxZ from D3DVIEWPORT9
Это преобразование может обеспечить повышенную точность и эквивалентно масштабированию и смещению тома обрезки.
Соответствующая матрица Маклипа:
Вершина преобразуется следующим образом:
dvClipWidth = 2 dvClipHeight = 2 dvClipX = -1 dvClipY = 1 dvMinZ = 0 dvMaxZ = 1
Если вы не хотите масштабировать том клипа, можно задать для параметров окна просмотра значения по умолчанию:
(Xc, Yc, Zc, Wc) = (Xp, Yp, Zp, Wp) * Mclip
Этап обрезки необязателен, если пользователь указывает флаг D3DDP_DONOTCLIP в вызове DrawPrimitive. В этом случае можно объединить все матрицы (включая Mvs).
Матрица масштабирования окна просмотра Mvs масштабирует координаты в пределах окна окна просмотра и переворачивает ось Y вверх вниз:
где:
dwX, dwY - viewport offsets in pixels from D3DVIEWPORT9 dwWidth, dwHeight - viewport width and height in pixels from D3DVIEWPORT9
Наконец, вычисляются экранные координаты и передаются растеризатору:
Советы по использованию
Ниже приведены некоторые советы по использованию конвейера преобразования Direct3D.
Последний столбец матриц мира и представления должен быть (0, 0, 0, 1), иначе освещение будет неправильным.
Задайте параметры окна просмотра, чтобы создать матрицу Mclip для идентификации, если вы точно не понимаете, для чего она нужна.
dvClipWidth = 2 dvClipHeight = 2 dvClipX = -1 dvClipY = 1 dvMinZ = 0 dvMaxZ = 1