Oblique frustum. Внутри скошенной пирамиды видимости

Нижеизложенный материал, вероятно, знаком, или даже хорошо известен, программистам, имевшим опыт работы с OpenGL, между тем, я счел уместным напомнить о модели oblique frustum, отчасти наблюдая (и разделяя) интерес читателей Хабра к вопросам OpenGL и в целом трёхмерного моделирования, отчасти из несогласия с позицией некоторых разработчиков вроде »…чтобы это использовать, вовсе не обязательно разбираться в том, как работает матрица проекции», отчасти из уважения и благодарности к Эрику Ленгелу|Eric Lengyel, изобретательная мысль которого обогатила приемы работы в среде OpenGL.

Если в моделируемых вами сценах присутствуют зеркальные отражения, и вы подзабыли или не слышали про «oblique frustum», то возможно, что эта статья не будет для вас бесполезной.

Несмотря на то, что я, вслед за Эриком Ленгелом, более придерживался при изложении материала представлений OpenGL, все последующие рассуждения легко распространяются на любые другие системы трёхмерного моделирования.

Reflections

Отражения в 3D–сценах


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

arbitrary camera

Рис. 1. Верхняя камера является основной камерой, через которую происходит рендеринг сцены, содержащей отражающую поверхность. Нижняя камера является вспомогательной камерой, предназначенной для рендеринга отражения. Ось X направлена к наблюдателю для обеих пирамид видимости (в принятых для OpenGL представлениях), и очевидно, что координатная система для камеры, осуществляющей рендеринг отражения, является левосторонней.

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

Можно воспользоваться инструкцией «discard» для фрагментного шейдера или ей подобными, специфическими для отдельных реализаций рендеринга в общей идеологии 3D–моделирования (например «kill» в AGALMiniAssembler), однако, если нам желательно решение универсальное, одинаково хорошо работающее на любом процессоре, то стоит обратить внимание на технику, предложеную Эриком Ленгелом.

Идея Эрика Ленгела заключалась в том, чтобы модифицировать проекционную матрицу таким способом, чтобы ближний план пирамиды видимости стал как раз своего рода секущей плоскостью, отделяющей нежелательный в конечном рендере объем основной сцены.

Для дальнейшего уместно напомнить элементарные представления аналитической геометрии.

Плоскость в пространстве


Для удобства изложения, будем придерживаться следующих обозначений:

\begin{center} \begin{array}{|rlc} \textbf{для точек и векторов:} & \vec{A}, \vec{P}\\ \multicolumn{2}{|l}{\textit{отличая их }\mathit{w} \textit{-координатой в однородном представлении,}}\\ \multicolumn{2}{|l}{\textit{координатную запись заключаем в угловые скобки }\langle ,,, \rangle}\\[0.3em] \textbf{для матриц:} & \mathbf{M}, \mathbf{P} \\ \textbf{транспонированная матрица:} &\mathbf{M}^\mathrm{T} \\ \textbf{обратная матрица:} & \mathbf{M}^{-1} \\ \textbf{знак } x:  & sgn(x) =   \begin{cases}     1,       & \quad \text{if } x>0\\     0,       & \quad \text{if } x=0\\     -1,  & \quad \text{if } x<0   \end{cases}\\ \textbf{длина вектора:} & \|\vec{P}\| \\ \textbf{скалярное произведение векторов:} & \vec{Q}\cdot\vec{P} \\ \end{array} \end{center}

Плоскость


Для любой пространственной 3D-точки \vec{P} и вектора \vec{N}, совокупность 3D-точек \vec{Q}, отличных от \vec{P}, удовлетворяющих уравнению \vec{N}\cdot(\vec{Q}-\vec{P}) определяет плоскость, при этом точка \vec{P} является одной из принадлежащих этой плоскости точек, а вектор \vec{N} является её вектором нормали.

Plane


Рис. 2. Плоскость полностью определяется принадлежащей ей точкой \vec{P} и нормаль-вектором \vec{N}.

Уравнение плоскости часто записывается следующим выражением:

bb81929fa089459264878faba089e694.svg

Ax+By+Cz+D=0,


где \mathit{A, B} и \mathit{C} есть \mathit{x, y, z} компоненты нормального вектора \vec{N}, причем D=-\vec{N}\cdot\vec{P}. Значение |D|/\|\vec{N}\| равно расстоянию до плоскости от начала координат (помним, что компоненты нормального вектора, деленные на его длину, есть направляющие косинусы единичного вектора нормали плоскости).

В случае нормализованного вектора нормали, выражение

a79cafe65ea1ccf1f75352901195b537.svg

d=\vec{N}\cdot\vec{Q}+D,


может быть использовано, для нахождения расстояния от плоскости до произвольной точки \vec{Q}. Если d=0, \vec{Q} лежит в плоскости. В случае, если d>0, точка \vec{Q} находится с положительной стороны плоскости, т.е. со стороны нормального вектора плоскости, при d<0, точка \vec{Q} располагается в стороне от плоскости, в направлении противоположном направлению нормального вектора плоскости \vec{N}.
Удобно записать плоскость четырехмерным вектором. Коротко уравнение плоскости запишется так: \langle \vec{N}, D \rangle. Очевидно, что для произвольной точки \vec{Q}, имеющей в однородных 4-хмерных координатах \mathit{w}-координату равную 1, Выражение (2) может быть переписано как d=\vec{L}\cdot\vec{Q}, где \vec{L}=\langle \vec{N}, D \rangle и точка \vec{Q} лежит в плоскости, если \vec{L}\cdot\vec{Q}=0.

Преобразование плоскости


Для понимания особенности пространственного преобразования плоскости, потребуется некоторое внимание уделить преобразованию нормального вектора. При пространственном преобразовании полигональной модели, вектора касательные к поверхности полигонов и вектора нормальные ведут себя неодинаково. Вектор касательный часто можно представить как разницу между двумя преобразованными вершинами, т.е. между двумя естественным образом преобразованными точками, и, вследствие этого, характер преобразованного вектора совпадает с нашими ожиданиями. Но, в общем случае пространственного преобразования, матрица \mathbf{M} которого не является ортогональной, прямое применение матрицы преобразования к нормальному вектору приведет к тому, что этот вектор перестанет быть нормальным — перпендикулярным к поверхности полигона.

Поскольку вектор касательный \vec{T} и вектор нормальный \vec{N}, принадлежащие одному полигону, должны оставаться перпендикулярными, для скалярного произведения преобразованных векторов \vec{T}{^'} и \vec{N}{^'} должно выполняться то же условие что и для исходных векторов: \vec{T}{^'}\cdot\vec{N}{^'}=0. Совершим несколько простых алгебраических операций, чтобы прояснить природу нормального вектора:

если \mathbf{M} — 3×3-матрица трансформации пространства (для случая касательного и нормального векторов пространственные перемещения несущественны), и \vec{T}{^'}=\mathbf{M}\vec{T}, то зададимся целью найти матрицу преобразования \mathbf{G} для \vec{N}, такую, чтобы выполнялось

6a475999d4080311ef78a1e9424aac0f.svg

\vec{N}{^'}\cdot\vec{T}{^'}=(\mathbf{G}\vec{N})\cdot(\mathbf{M}\vec{T})=0,


вспомним, что умножение векторов можно записать и следующим образом (совершенно равнозначным):

0af1f09396086076b8030446fa70e628.svg

(\mathbf{G}\vec{N})\cdot(\mathbf{M}\vec{T})=(\mathbf{G}\vec{N})^\mathrm{T}(\mathbf{M}\vec{T})=\vec{N}^\mathrm{T}\mathbf{G}^\mathrm{T}\mathbf{M}\vec{T},


Поскольку \vec{N}^\mathrm{T}\vec{T}=0, выражение \vec{N}^\mathrm{T}\mathbf{G}^\mathrm{T}\mathbf{M}\vec{T}=0 выполняется, если \mathbf{G}^\mathrm{T}\mathbf{M}=\mathbf{I}, где \mathbf{I} — единичная матрица. Из чего следует, что \mathbf{G}=(\mathbf{M}^{-1})^\mathrm{T}. Вектор, трансформация которого происходит подобным образом (посредством транспонированной обратной матрицы преобразования), является вектором ковариантным, тогда как вектор, трансформирующийся подобно вектору касательному, является вектором контравариантным.

Однако, плоскость в однородных координатах, в отличие от нормального вектора, имеет ненулевую \mathit{w}-координату, и следует дополнительно исследовать её поведение при 4×4-преобразованиях.

Расстояние до плоскости от начала координат, после применения пространственного преобразования, с учетом особенностей преобразования нормального вектора, для лежащей в этой плоскости точки \vec{P}, через знакомое скалярное произведение:

0187e5abdd5d89e56ac358a91f005fdd.svg

\begin{array}{l}D{^'}= -((\mathbf{M}{^{-1}})^\mathrm{T}\vec{N})\cdot(\mathbf{M}\vec{P}+\vec{T})\\   \qquad {}=-((\mathbf{M}^{-1})^\mathrm{T}\vec{N})^\mathrm{T}\mathbf{M}\vec{P}-((\mathbf{M}^{-1})^\mathrm{T}\vec{N})^\mathrm{T}\vec{T}\\ \qquad {}=-\vec{N}^\mathrm{T}\mathbf{M}^{-1}\mathbf{M}\vec{P}-\vec{N}^\mathrm{T}\mathbf{M}^{-1}\vec{T}\\ \qquad{}=D -\vec{N}\cdot\mathbf{M}^{-1}\vec{T},\end{array}


Мы воспользовались в данных вычислениях матрицей преобразования \mathbf{F}, дополненной к операциям поворота, масштабирования и скоса операцией сдвига:

34b082223798ff10c0fcd50a3302364e.svg

\mathbf{F}=\left[\:\; \begin{matrix} \quad{} &\quad{}  &\vline &\quad{}\\  \quad{} &\mathbf{M}\quad{} &\vline  &  \vec{T} \\ \quad{} &\quad{}  &\vline &\quad{}\\ \hline  \quad{} &0\quad{} &\vline & 1 \end{matrix}\:\;\right] =\left[\:\; \begin{matrix} M_{11} &M_{12} &M_{13}  &\vline \,&T_x\\ M_{21} &M_{22} &M_{23}  &\vline \,&T_y\\ M_{31} &M_{32} &M_{33}  &\vline \,&T_z\\ \hline 0 &0 &0 &\vline \,&1\\ \end{matrix}\:\;\right],


Матрица обратного преобразования к матрице \mathbf{F} ищется обычным алгоритмом обращения матриц:

ac6f02875612deb38e5865b2a037d51f.svg

\mathbf{F}^{-1}=\left[\:\; \begin{matrix} \quad{} &\quad{}  &\vline &\quad{}\\  \quad{} &\mathbf{M}^{-1}\quad{} &\vline  &-\mathbf{M}^{-1}\vec{T} \\ \quad{} &\quad{}  &\vline &\quad{}\\ \hline  \quad{} &0\quad{} &\vline & 1 \end{matrix}\:\;\right] =\left[\:\; \begin{matrix} M_{11}^{-1} &M_{12}^{-1} &M_{13}^{-1}  &\vline \,&-\mathbf{M}^{-1}T_x\\ M_{21}^{-1} &M_{22}^{-1} &M_{23}^{-1}  &\vline \,&-\mathbf{M}^{-1}T_y\\ M_{31}^{-1} &M_{32}^{-1} &M_{33}^{-1}  &\vline \,&-\mathbf{M}^{-1}T_z\\ \hline 0 &0 &0 &\vline \,&1\\ \end{matrix}\:\;\right],


Транспонируем обратную матрицу:

30db67121f43037bdee27ac875c4cd48.svg

{\left(\mathbf{F}^{-1}\right)^\mathrm{T}}=\left[\:\; \begin{matrix} \quad{} &\quad{}  &\vline &\quad{}\\  \quad{} &{\left(\mathbf{M}^{-1}\right){}^\mathrm{T}}\quad{} &\vline  &0 \\ \quad{} &\quad{}  &\vline &\quad{}\\ \hline  \quad{} &-\mathbf{M}^{-1}\vec{T}\quad{} &\vline & 1 \end{matrix}\:\;\right],


Можем видеть, что D -\vec{N}\cdot\mathbf{M}^{-1}\vec{T} из Выражения (5) есть результат умножения четвёртой строки транспонированной обратной матрицы преобразования на четырёхмерный вектор в однородной координатной записи \langle N_x, N_y, N_z, D \rangle, т.е. для плоскости \vec{C}=\langle \vec{N}, D\rangle, её образ при пространственной трансформации, описываемой 4×4 матрицей превращения \mathbf{F}, выражается:

0d119c0647973f0dec8f8d2f4e333d96.svg

\vec{C}{^'}={\left(\mathbf{F}^{-1}\right){}^\mathrm{T}}\vec{C}.


Для дальнейшего существенно, что плоскость подчиняется ковариантному характеру пространственного преобразования.

Перспективная проекция


Перспективное проецирование применяется, чтобы создать у наблюдателя ощущение глубины на проекционном плане, матрица перспективного преобразования должна отобразить пространство пирамиды видимости в нормализованное пространство куба видимости. Пирамида видимости обычно может быть выражена через термины top, bottom, left, right, far, near или fovy, aspect, near, far, некоторые реализации OpenGL имеют среди своих инструментов средства работы как для правосторонней так и для левой координатных систем. Отличия и порядок умножения матрицы на вектор в каждой из систем, должны быть ясны любому программисту.

frustum

Рис. 3. Усеченная пирамида видимости (frustum) в системах компьютерной графики отсекает зону видимости, для целей последующего рендеринга, с боков и вдоль осей проецирования. Пирамида видимости, в пространстве камеры вида, располагается в правосторонней системе координат так, что вершина пирамиды лежит в центре координатной системы, а направление вида из камеры противоположно оси z, ближний план находится на удалении n вдоль отрицательного направления оси z, дальний план — на удалении f вдоль отрицательного направления оси z.

В общем случае, пирамида видимости не обязана иметь форму правильной усеченной пирамиды, она может быть и асимметричной, поэтому модель с top, bottom, left, right, far, near является более подходящей для иллюстраций особенностей oblique frustum («скошенной пирамиды видимости»). «Сжатое пространство» куба видимости, замкнутое в объёме, ограниченном плоскостями x=\pm 1, y=\pm 1, z=\pm 1, для единообразия с англоязычной терминологией будем в дальнейшем называть пространством клипа.

Чтобы организовать задуманное нами отсечение части объектов в исходной пирамиде видимости, нам потребуется модифицировать применяемую в нашей модели матрицу перспективной проекции. Параметры таковой матрицы программисты OpenGL могут найти на сайте основной документации по OpenGL, программисты на Flash (AS3), вероятнее всего обратятся к классу PerspectiveMatrix3D, программисты Direct3D имеют свои источники, пишущие для андроида найдут всё необходимое в классе android.opengl.Matrix, и т.д. Не исключено, что кто-то, поняв основную идею, предпочтет расширить свой собственный класс перспективного преобразования дополнительной функциональностью.


Точка из пространства пирамиды видимости камеры вида отображается в пространство клипа канонического куба, например, следующим 4×4-матричным преобразованием (воспользуемся матрицей перспективного преобразования генерируемой glFrustum ()-функцией OpenGL):

5c6892b58d1fb621ce534afa2c8be444.svg

\vec{P}{^'}=\mathbf{M}_{frustum}\vec{P}= \begin{bmatrix} \frac{2n}{r-l} &0 &\frac{r+l}{r-l} & 0\\[0.3em] 0 &\frac{2n}{t-b} &\frac{t+b}{t-b} &0 \\[0.3em] 0 & 0 &-\frac{f+n}{f-n} &-\frac{2nf}{f-n}\\[0.3em] 0 &0 &-1 & 0 \end{bmatrix}\!\!\begin{bmatrix} P_x\\ P_y\\ P_z\\ 1 \end{bmatrix}.


При таком преобразовании, \mathit{w}-координата преобразованной точки в однородном пространстве клипа имеет знак противоположный знаку \mathit{z}-координаты точки в пространстве камеры вида.

Особенности искажения пространства стандартной матрицей преобразования видны из Рис. 4:
\mathit{z}-координата из пространства пирамиды видимости отражается в диапазон [-1, 1] NDC, причём бесконечный диапазон за дальним планом пирамиды видимости из камеры вида сжимается в конечный промежуток \left[1, \tfrac{f+n}{f-n}\right] внутри NDC; конечное расстояние от камеры до ближнего плана вдоль оси Z расширяется до бесконечного промежутка ]{-\infty}, -1] NDC;, а точки вдоль оси Z, находящиеся до камеры, отражаются в диапазон \left[ \tfrac{f+n}{f-n}, \infty\right[.

Normalized Device Coordinates

Рис. 4. Отражение \mathit{z}-координаты точки из пространства камеры вида в пространство нормализованных координат устройства (NDC — normalized device coordinates).

Заменяя ближний план пирамиды видимости плоскостью отсечения, мы должны сохранить основные особенности матрицы перспективного преобразования, \mathit{z}-координата точки, лежащей на модифицированном ближнем плане, в нормализованных координатах устройства (NDC) должна остаться равной -1. Все дальнейшие наблюдения являются универсальными для любых обратимых проекционных матриц, и использование матрицы проекции из Выражения (10) служит лишь целям иллюстрации общего процесса модификации матрицы преобразования.

Если \vec{C}{^'} является одной из плоскостей, ограничивающих пространство клипа, и при этом матрица преобразования \mathbf{M} является матрицей проекции из пространства камеры в пространство клипа, то не сложно осуществить отображение этой плоскости \vec{C}{^'} в пространство камеры из пространства клипа посредством транспонированной матрицы \mathbf{M}^\mathrm{T}, что очевидно следует из Выражения (9):

8535c6326bd0ccb37584caab2210329d.svg

\vec{C}=\left[\left(\mathbf{M}^{-1}\right){}^{-1}\right]{}^\mathrm{T}\vec{C}{^'}=\mathbf{M}^\mathrm{T}\vec{C}{^'}


Модифицирование ближнего плана пирамиды видимости


Для начала, извлечем из произвольной проекционной матрицы \mathbf{M} четырехмерные векторы, соответствующие шести плоскостям отсечения пирамиды видимости. Эрик Ленгел исходил из того, что плоскости в пространстве клипа всегда неизменны: нормаль любой плоскости параллельна одной из главных координатных осей.

На Рис. 5 показаны элементы »x-z» трёхмерного среза четырехмерного однородного пространства клипа. Внутри этого среза \mathit{w}-координата любой точки равна 1, таким образом, и \mathit{w}-координата каждой плоскости равна 1, и, разумеется, одна из x-, y-, или z-координат равна ±1, что отражено в Таблице 1. Для понимания Таблицы 1 надо ещё раз внимательно посмотреть на Выражение (11): сумма некоторых двух столбцов матрицы \mathbf{M}^\mathrm{T} не что иное, как сумма соответствующих двух строк матрицы \mathbf{M}.

slice of homogeneous clip space

Рис. 5. Нормальные векторы для левой, правой, ближней и дальней плоскостей, ограничивающих однородное кубическое пространство клипа. Нормальные векторы для верхней и нижней плоскостей пространства клипа направлены от и к наблюдателю.

Табл. 1. Взаимосвязь между координатами пространства клипа и пространства усеченной пирамиды видимости камеры вида. Матрица проекции \mathbf{M} переводит пространство камеры вида в пространство клипа, и обозначение \mathbf{M}_i представляет i-ую строку матрицы \mathbf{M}.
\begin{center} \begin{array}{rcc} \hline \textbf{Frustum plane} & \textbf{Clip-space} & \textbf{Camera-space} \\ \hline \text{Near}\qquad{} & \langle 0, 0, 1,1\rangle &\vec{M}_4 + \vec{M}_3 \\ \text{Far}\qquad{} & \langle 0, 0, -1,1\rangle & \vec{M}_4 - \vec{M}_3 \\ \text{Left}\qquad{} & \langle 1, 0, 0,1\rangle &\vec{M}_4 + \vec{M}_1 \\ \text{Right}\qquad{} & \langle -1, 0, 0,1\rangle &\vec{M}_4 - \vec{M}_1 \\ \text{Bottom}\qquad{} & \langle 0, 1, 0,1\rangle &\vec{M}_4 + \vec{M}_2 \\ \text{Top}\qquad{} & \langle 0, -1, 0,1\rangle &\vec{M}_4 - \vec{M}_2 \\ \hline \end{array} \end{center}

Пусть \vec{C}=\langle C_x, C_y, C_z, C_w\rangle — некоторая плоскость, показанная ни Рис. 6, в координатном пространстве камеры вида, посредством которой мы и намереваемся ограничить нашу геометрию. Камера располагается с отрицательной стороны плоскости (со стороны противоположной направлению вектора плоскости), поэтому C_w<0. Именно этой плоскостью мы намерены заменить ближний план пирамиды видимости, поэтому, в соответствии с соотношениями из Таблицы 1, для \vec{C} должно выполняться:

07ab8a8df41b989e7e0ce890eeffe6df.svg

\vec{C}=\vec{M}_4+\vec{M}_3.


Мы не можем модифицировать четвертую строку матрицы перспективной проекции, т.к. она используется для отражения отрицательной z-координаты в w-координату, и необходима для дальнейшей корректной работы графического конвеера. Однако, со вторым слагаемым правой части Выражения (12) мы можем поступать более свободно:

e435c4d42fc60eed80548fbba57c5e28.svg

\vec{M}_3{^'}=\vec{C}-\vec{M}_4.


cut clip space


Рис. 6. Замена ближнего плана пирамиды видимости плоскостью \vec{C}.

Поскольку, согласно Таблицы 1, третья строка матрицы проекции входит в состав выражения для дальнего плана пирамиды видимости, то очевидно, что её модифицирование необходимо учесть для дальнего плана:

50e8ab7e1b6684fa6e67441e2a27071c.svg

\begin{array}{|c|}\hline \;\\ \vec{F}=\vec{M}_4-\vec{M}_3^'}\;\\[0.3em]    \qquad {}=2\vec{M}_4-\vec{C}\;\\[1em] \hline \end{array}\:.


И этот результат являет собой заметную проблему для перспективной проекции: поскольку \vec{M}_4=\langle0, 0, -1, 0 \rangle, то дальний план и ближний план пирамиды видимости перестают быть параллельными, в случае отличных от нуля значений для C_x и C_y. Более того, форма усеченной пирамиды приобретает вид крайне нежелательный в последующем рендеринге: рассмотрим некоторую точку \vec{P}=\langle x, y, 0, w \rangle, для которой выполняется \vec{C}\cdot\vec{P}=0, и это влечет за собой равенство нулю и \vec{F}\cdot\vec{P}, из чего мы должны заключить, что наши новые ближний и дальний планы пересекутся образом подобным показанному на Рис. 7 (а).

Проекция глубины точки, ранее достигавшая максимума на дальнем плане, и необходимая нам для процесса графической растеризации, более не представляет собой проекцию вдоль оси z, а скорее, становится значением, зависящим от положения между ближним и дальним планами. Зависимость глубины проекции от направления внутри пирамиды видимости серьезнейшим образом скажется на правильности значений буфера глубины. Однако, этот нежелательный эффект, можно снизить до приемлимого для задачи растеризации уровня, уменьшив угол между ближним и дальним планами до минимально возможного. Как и всякую плоскость, плоскость \vec{C} можно масштабировать, и это её свойство как нельзя кстати в нашем случае. Масштабирование плоскости \vec{C} скажется на ориентации дальнего плана \vec{F}, так что нам требуется лишь подобрать коэффициент масштабирования таким образом, чтобы минимизировать угол между \vec{C} и \vec{F} без ущерба для содержания сцены внутри пирамиды видимости как показано на Рис. 7 (b).

modified far plane


Рис. 7. (а) Пересечение измененного в соответствии с Выражением (14) дальнего плана \vec{F} с модифицированным ближним планом \vec{C} в »x-y»-плоскости. (b) Масштабирование ближнего плана \vec{C} параметром \alpha, введенным Выражением (17) изменяет угол между дальним и ближним планом до минимально возможного, не повреждая при этом начального вида усечения. Затененная область относится к объему пространства, не подвергнутого усечению.

Пусть \vec{C}{^'}=\left(\mathbf{M}^{-1}\right){}^\mathrm{T}\vec{C} является проекцией нового ближнего плана в пространстве клипа (\mathbf{M} — исходная матрица проекции). Угол \vec{Q}^' внутри пирамиды видимости, лежащий напротив плоскости \vec{C}, будет иметь следующие координаты:

61c5ffa314b3c4d942ddbd817ad3761b.svg

\vec{Q}{^'}=\langle sgn(C{^'} _x), sgn(C{^'} _y), 1, 1\rangle.


Для большинства перспективных проекций, знаки компонент C{^'} _x и C{^'} _y у преобразованных плоскостей совпадут со знаками соответствующих компонент C _x и C _y, что нам позволяет воспользоваться знаками координатного разложения исходной плоскости.
Имея компоненты преобразованного угла \vec{Q}{^'}, мы уже можем вычислить компоненты оригинального угла \vec{Q}, лежащего напротив плоскости \vec{C}, как \vec{Q}=\mathbf{M}{^{-1}}\vec{Q}{^'}. В обычной пирамиде видимости, точка \vec{Q} в вершине угла, образованного пересечением двух боковых плоскостей и дальнего плана, лежащая напротив плоскости \vec{C}, является наиболее удаленной от плоскости \vec{C} точкой.

Чтобы наш дальний план содержал точку \vec{Q}, должно выполняться условие \vec{F}\cdot\vec{Q}=0, дополним Выражение (14) масштабирующим плоскость \vec{C} фактором \alpha

2bafa621fd89b5e10fbddab891cd6278.svg

\vec{F}=2\vec{M}_4-\alpha\vec{C}


и найдем из условия \vec{F}\cdot\vec{Q}=0 масштабирующий фактор:

926801dedc4e64d2c029df06e3a99da6.svg

\alpha=\frac{2\vec{M}_4\cdot\vec{Q}}{\vec{C}\cdot\vec{Q}.


Замена \vec{C} на \alpha\vec{C} в Выражении (13)

d7bfe3165983e5a404e01de82e68dce2.svg

\vec{M}_3{^'}=\alpha\vec{C}-\vec{M}_4


и позволит нам оптимальным образом сориентировать дальний план пирамиды видимости, как показано на Рис. 7 (b) (данная техника замещения работает корректно и для пирамиды видимости, дальний план которой удален на бесконечность, — случай бесконечной проекционной матрицы, — для этого достаточно потребовать, чтобы дальний план был параллелен одной из двух образующих противоположный плоскости \vec{C}угол граней).

Практическое использование произведенных выше наблюдений


Все ранее проделанные теоретические изыскания распространяются на любые обратимые проекционные матрицы, но, поскольку, в качестве примера уже привлекалась стандартная для OpenGL матрица в Выражении (10), то логично продолжить цепочку примеров с нею же.

Обратная матрица к ней будет выглядеть таким образом:

2c60397ce093f75f4f20810802a83635.svg

\mathbf{M}{^{-1}}= \begin{bmatrix} \frac{r-l}{2n} &0  & 0 &\frac{r+l}{2n}\\[0.3em] 0 &\frac{t-b}{2n}  &0 &\frac{t+b}{2n}\\[0.3em] 0 & 0 &0 &-1\\[0.3em] 0 &0 &-\frac{f-n}{2nf} & \frac{f+n}{2nf} \end{bmatrix}


Получим значение для третьей строки модифицированной проекционной матрицы, как предложено Выражением (18) с учетом \alpha из Выражения (17):

952ad037c9407a4e3705b00f63f7be3f.svg

\vec{M}_3{^'}={\frac{2\vec{M}_4\cdot\vec{Q}}{\vec{C}\cdot\vec{Q}} \vec{C}-\vec{M}_4


Поскольку \vec{M}_4=\langle 0, 0, -1, 0\rangle, то это выражение можно записать к

© Habrahabr.ru