Почему знак имеет значение в матрице проекции opengl

Я работаю над проблемой компьютерного зрения, которая требует рендеринга 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 на любую неотрицательную скалярную величину и получить точно такие же результаты визуализации, но как только я умножу на отрицательную скалярную величину, ничего не будет визуализировано. Что здесь происходит??

Спасибо!


person Kyle Simek    schedule 18.02.2010    source источник


Ответы (3)


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

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

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

person Bahbar    schedule 18.02.2010
comment
Хороший ответ! Я предположил, что тест на отсечение будет: -1 ‹ x_c / w_c ‹ 1, но я думаю, что opengl избегает операции деления за счет неправильной оценки, когда w_c отрицательный. - person Kyle Simek; 22.02.2010

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

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

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

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

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

person Kyle Simek    schedule 18.02.2010

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

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

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

В разделе часто задаваемых вопросов OpenGL о трансформациях есть более подробная информация.

person charstar    schedule 18.02.2010
comment
После преобразования однородных координат в неоднородные (т. е. путем деления на w_c) координаты по-прежнему попадают между zNear и zFar, потому что отрицательный знак w_c компенсирует инвертированный знак {x,y,z}_c. так что думаю это не то. По той же причине нормализованные координаты устройства, по сути, тоже не инвертируются. Я использую проекционную матрицу только для внутренних параметров камеры (фови, аспект, наклон оси и т. д.); внешние параметры входят в матрицу представления модели. Так что я тоже думаю, что это не проблема. - person Kyle Simek; 22.02.2010
comment
Я не знаю деталей реализации драйвера, но предполагаю, что на самом деле это не так для zNear и zFar. Тестирование клипа, скорее всего, проводится не по дальности, а по глубине, поэтому числовое значение проверяется на большее, чем zNear (отсюда и положительное требование в первую очередь). Если вся система координат и матрица инвертированы, тест не пройден, как указал Бахбар. - person charstar; 24.02.2010