Почему знак имеет значение в проекционной матрице OpenGL - PullRequest
13 голосов
/ 18 февраля 2010

Я работаю над проблемой компьютерного зрения, которая требует рендеринга 3d-модели с использованием калиброванной камеры. Я пишу функцию, которая разбивает калиброванную матрицу камеры на матрицу вида модели и матрицу проекции, но я столкнулся с интересным явлением в opengl, которое не поддается объяснению (по крайней мере, мне).

Краткое описание состоит в том, что отрицание матрицы проекции приводит к тому, что ничего не отображается (по крайней мере, по моему опыту). Я ожидал бы, что умножение матрицы проекции на любой скаляр не будет иметь никакого эффекта, потому что оно преобразует однородные координаты, которые не зависят от масштабирования.

Ниже приводятся мои соображения, почему я нахожу это неожиданным; возможно, кто-то может указать, где мои рассуждения ошибочны.

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

    [ a b c 0 ]
P = [ 0 d e 0 ]
    [ 0 0 f g ]
    [ 0 0 h 0 ]

Умножение этого на координаты камеры дает однородные координаты клипа:

[x_c]   [ a b c 0 ]   [X_e]
[y_c] = [ 0 d e 0 ] * [Y_e]
[z_c]   [ 0 0 f g ]   [Z_e]
[w_c]   [ 0 0 h 0 ]   [W_e]

Наконец, чтобы получить нормализованные координаты устройства, мы разделим x_c, y_c и z_c на w_c:

[x_n]   [x_c/w_c]
[y_n] = [y_c/w_c]
[z_n]   [z_c/w_c]

Теперь, если мы отрицаем P, результирующие координаты клипа должны быть аннулированы, но, поскольку они являются однородными координатами, умножение на любой скаляр (например, -1) не должно иметь никакого влияния на результирующие нормализованные координаты устройства. Однако в openGl отрицание P приводит к тому, что ничего не отображается. Я могу умножить P на любой неотрицательный скаляр и получить точно такие же результаты рендеринга, но как только я умножусь на отрицательный скаляр, ничего не отрендерим. Что здесь происходит ??

Спасибо!

Ответы [ 3 ]

10 голосов
/ 18 февраля 2010

Ну, суть в том, что тестирование отсечения выполняется через:

-w_c < x_c < w_c
-w_c < y_c < w_c
-w_c < z_c < w_c

Умножение на отрицательное значение нарушает этот тест.

2 голосов
/ 18 февраля 2010

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

Из Красной книги, приложение G:

Избегайте использования отрицательных координат вершин w и отрицательных координат текстуры q. OpenGL может некорректно обрезать такие координаты и может делать ошибки интерполяции при затенении примитивов, определенных такими координатами.

Инвертирование матрицы проекции приведет к отрицательной координате отсечения W, и, очевидно, opengl это не нравится. Но кто-нибудь может объяснить, почему opengl не обрабатывает этот случай?

ссылка: http://glprogramming.com/red/appendixg.html

0 голосов
/ 18 февраля 2010

Причины, о которых я могу подумать:

  • При инвертировании матрицы проекции координаты больше не будут находиться в плоскостях zNear и zFar усеченного вида (обязательно больше 0).
  • Для создания координат окна нормализованные координаты устройства переводятся / масштабируются в области просмотра. Таким образом, если вы использовали отрицательный скаляр для координат клипа, нормализованные координаты устройства (теперь инвертированные) переводят окно просмотра в координаты окна, которые находятся ... вне вашего окна (если хотите, слева и снизу)

Кроме того, поскольку вы упомянули использование матрицы камеры и инвертировали матрицу проецирования, я должен спросить ... к каким матрицам вы применяете какую матрицу камеры? Работа с матрицей проекции save near / far / fovy / aspect вызывает всевозможные проблемы в буфере глубины, включая все, что использует z (тестирование глубины, выборку лица и т. Д.).

Раздел часто задаваемых вопросов OpenGL о преобразованиях содержит некоторые подробности.

...