Поделиться через


Преобразование проекции (Direct3D 9)

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

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

В видимом пространстве расстояние между камерой и началом координат видимого пространства преобразования определяется произвольно как D, поэтому матрица проекции выглядит, как показано на следующем рисунке.

иллюстрация матрицы проекции

Матрица просмотра переносит камеру в начало координат, перемещаясь в направлении z на –D. Матрицы преобразования выглядит, как показано на следующем рисунке.

иллюстрация матрицы преобразования

Умножение матрицы преобразования на матрицу проекции (T*P) дает составную матрицу проекции, как показано на следующем рисунке.

иллюстрация составной матрицы проекции

Преобразование перспективы превращает видимое пространство в новое пространство координат. Обратите внимание, что усеченная пирамида становится кубоидом, а начало координат перемещается из правого верхнего угла сцены в центр, как показано на следующем рисунке.

схема изменения усеченной пирамиды обзора в новое пространства координат за счет преобразования перспективы

При преобразовании перспективы ограничения направлений x и y равны –1 и 1 соответственно. Ограничения по оси z равны 0 для передней плоскости и 1 для задней плоскости.

Эта матрица преобразует и масштабирует объекты на основе определенного расстояния между камерой и ближней плоскостью отсечения, но при этом не учитывается, что поле зрения (fov) и z-значения, создаваемые для объектов, на расстоянии могут быть практически идентичными, что усложняет сравнение глубины. Следующая матрица решает эти проблемы и корректирует вершины для учета пропорций окна просмотра, что хорошо подходит для проекции перспективы.

иллюстрация матрицы для проекции перспективы

В этой матрице Zₙ — это z-значение ближней плоскости отсечения. Переменные w, h и Q имеют следующие значения. Обратите внимание, что fovw и fovₖ представляют горизонтальные и вертикальные поля зрения окна просмотра в радианах.

формулы значений переменных

В вашем приложении использование углов полей зрения для определения коэффициентов масштабирования осей x и y может быть не так удобно, как применение горизонтального и вертикального измерения окна просмотра (в пространстве камеры). В следующих двух уравнениях для w и h используются измерения окна просмотра, при этом они эквивалентны предыдущим формулам.

формулы значений переменных w и h

В этих формулах Zₙ представляет положение ближней плоскости отсечения, а переменные Vw и Vₕ представляют ширину и высоту окна просмотра в пространстве камеры.

Для приложения C++ эти два измерения напрямую соответствуют элементам Width и Height структуры D3DVIEWPORT9 .

Какую бы формулу вы ни выбрали, обязательно установите для Zₙ максимально возможное значение, так как z-значения, очень близкие к камере, не сильно отличаются. Это относительно усложняет сравнение глубины с помощью 16-разрядных z-буферов.

Как и в случае с преобразованиями мира и представления, вы вызываете метод IDirect3Device9::SetTransform , чтобы задать преобразование проекции.

Настройка матрицы проекции

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

D3DXMATRIX 
ProjectionMatrix(const float near_plane, // Distance to near clipping 
                                         // plane
                 const float far_plane,  // Distance to far clipping 
                                         // plane
                 const float fov_horiz,  // Horizontal field of view 
                                         // angle, in radians
                 const float fov_vert)   // Vertical field of view 
                                         // angle, in radians
{
    float    h, w, Q;

    w = (float)1/tan(fov_horiz*0.5);  // 1/tan(x) == cot(x)
    h = (float)1/tan(fov_vert*0.5);   // 1/tan(x) == cot(x)
    Q = far_plane/(far_plane - near_plane);

    D3DXMATRIX ret;
    ZeroMemory(&ret, sizeof(ret));

    ret(0, 0) = w;
    ret(1, 1) = h;
    ret(2, 2) = Q;
    ret(3, 2) = -Q*near_plane;
    ret(2, 3) = 1;
    return ret;
}   // End of ProjectionMatrix

После создания матрицы задайте для нее значение IDirect3DDevice9::SetTransform , указав D3DTS_PROJECTION.

Служебная библиотека D3DX предоставляет следующие функции, которые помогут вам настроить матрицу проекции.

Матрица проекции с поддержкой W

Direct3D может использовать компонент w вершины, которая была преобразована абсолютной матрицей, а также матрицами представления и проекции для вычислений на основе глубины при использовании буфера глубины или эффекта тумана. Для таких вычислений требуется, чтобы матрица проекции нормализовала переменную w как эквивалентную координате z в абсолютном пространстве. Иными словами, если матрица проекции включает коэффициент (3,4), не равный 1, необходимо масштабировать все коэффициенты, инвертируя коэффициент (3,4) для получения правильной матрицы. Если не предоставить совместимую матрицу, эффекты тумана и буферизация глубины не будут правильно применены.

На следующем рисунке показана несоответствующая требованиям матрица проекции и та же матрица, масштабированная для применения тумана туман относительно зрителя.

иллюстрации несоответствующей матрицы проекции и матрицы с туманом относительно зрителя

В предыдущих матрицах предполагается, что все переменные не равны нулю. Дополнительные сведения о тумане относительно глаз см. в разделе Глубина относительного взгляда и Z. Сведения о буферизации глубины на основе W см. в разделе Буферы глубины (Direct3D 9).

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

Преобразования