Происхождение (glu)lookAt

Я пытаюсь изучить (современный) OpenGL, и я полностью запутался в различных преобразованиях...

Матрица просмотра меня смутила, поэтому мне нужно некоторое разъяснение.

Вот что я понял о (обычном) конвейере.

  1. Вершины задаются в мировом пространстве, которые масштабируются, перемещаются, поворачиваются и т. д. в требуемые положения с помощью матрицы моделирования.
  2. (Здесь я начинаю путаться) Мы можем (опционально) расположить виртуальную камеру в нужном месте с помощью функции «lookAt» (gluLookAt). Я следил за выводом матрицы здесь: http://www.youtube.com/watch?v=s9FhcvjM7Hk. Я понял до того момента, когда профессор вычисляет вектор "взгляда". Он говорит, что вектор взгляда = глаз - центр. Теперь вот где я начинаю теряться. Мой первый инстинкт заключается в том, что вектор должен быть в центре - глаз. Предположим, что вектор центра задан как (0,0,0), а вектор глаза равен (0,0,5). Чтобы посмотреть на объект, камера должна быть направлена ​​в центр - глаз = (0,0,-5). Однако профессор заявляет, что мы хотим переместить центр — глаз в направлении -z (что это значит?). Следовательно, глазоцентр даст взгляду направление. Меня это смущает. Далее он добавляет, что в OpenGL есть камера в начале координат, смотрящая на (0,0,-1). Вот этого я совершенно не понимаю. Я понимаю, что преобразование просмотра - это не что иное, как применение обратного преобразования к объектам. Я немного поэкспериментировал и обнаружил, что когда я рисовал треугольник со значением z, равным 1 (и абсолютно без преобразований модели/проекции), он все еще рисовался на экране. Однако я бы не ожидал, что это так, поскольку камера находится в начале координат.

Теперь, подытоживая...

  • Почему смотреть на = глаз - центр?
  • Что такого в том, что камера находится в начале координат и смотрит на z=-1?

Любые объяснения/указатели?


person Sumanth    schedule 03.11.2013    source источник


Ответы (2)


Когда вы визуализируете треугольник, координаты вершин интерпретируются следующим образом:

  • Координата x будет влиять на горизонтальное положение в окне просмотра. -1 — левый край, а +1 — правый край.
  • Координата Y будет влиять на вертикальное положение в окне просмотра. -1 — это нижний край, а +1 — верхний край.
  • Координата z будет влиять на информацию о глубине. -1 — это положение в плоскости камеры (ближняя), а +1 — дальняя плоскость. Это значение обычно используется для записи в буфер глубины.

Вот почему ваш простой пример отображает видимый треугольник в дальней плоскости.

Теперь давайте перейдем к преобразованию вида. Преобразование будет построено из четырех векторов. Изображение (1, 0, 0), изображение (0, 1, 0), изображение (0, 0, 1) и вектор переноса. Однако, поскольку преобразование представления является обратным преобразованием, результирующую матрицу необходимо инвертировать.

Вы правы, что направление взгляда center - eye. Однако это не то, что нам нужно для матрицы. Нам нужно изображение (0, 0, 1). Обычно программы OpenGL используют правую систему координат. В этой системе камера смотрит в отрицательном направлении по оси Z. Таким образом, center - eye на самом деле является изображением (0, 0, -1). Изображение (0, 0, 1) тогда просто eye - center. Это то, что вам нужно.

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

person Nico Schertler    schedule 03.11.2013
comment
Я поэкспериментировал немного дальше и нарисовал два треугольника, один со значением z, равным 1, а другой — с -1. Тот, у которого значение z равно 1, появился перед тем, у которого -1 (я включил буфер глубины). Это как-то противоречит вашему ответу. Что касается происхождения gluLookAt и преобразования перспективы, зачем следовать такому соглашению? Вместо этого, разве матрицы просмотра и проекции не могут иметь положительное значение z? - person Sumanth; 04.11.2013
comment
Я ошибся насчет диапазона значений глубины. На самом деле это от -1 до 1. Но все равно -1 стоит перед 1. Вы уверены, что ваш тест действителен (т.е. glEnable(GL_DEPTH_TEST) и абсолютно без преобразования вида модели и проекции?). Мои быстрые тесты дали ожидаемые результаты (tri с более высоким z-значением отстает от tri с более низким z-значением). Кстати, треугольники с z-значением 1 уже обрезаны, поэтому я использовал немного более низкое значение. Конечно, вы можете использовать преобразования видов и проекций с положительными значениями z (т.е. левосторонняя система координат). Но оба преобразования должны соответствовать друг другу. - person Nico Schertler; 04.11.2013
comment
Кроме того, убедитесь, что вы запрашиваете буфер глубины при создании окна. В противном случае вы не сможете сохранить информацию о глубине, и треугольник, нарисованный последним, всегда будет сверху. - person Nico Schertler; 04.11.2013
comment
Упс, я допустил ошибку в вызове glEnable. Вы правы, ближняя плоскость равна -1, а дальняя плоскость +1. Означает ли это, что клип-пространство в OpenGL левостороннее (по умолчанию)? - person Sumanth; 04.11.2013
comment
Да, это в основном то, что это означает. - person Nico Schertler; 04.11.2013

При использовании виртуальной камеры обычно определяется пространство для глаз. Это определение может быть произвольным, но есть некоторые широко распространенные соглашения (и старый матричный стек GL определил или предпочел некоторые из соглашений). gluLookAt указывается для следующего соглашения:

  1. камера находится в начале координат
  2. камера смотрит в отрицательном направлении z, +x — это правая ось, а +y — направление вверх (так что у нас правая система координат)

Вы должны знать, что world space на самом деле не имеет значения при рендеринге. Все, что имеет значение, — это взаимное расположение объектов относительно виртуальной камеры/глаза (и именно поэтому старый стек матриц GL имеет объединенную матрицу ModelView, а не две отдельные матрицы для трансформаций Model и View). Использование мирового пространства, в котором размещены все объекты, и указание виртуальной камеры в этом пространстве просто более интуитивно понятно. Именно это и должен делать gluLookAt. Если вы оставите матрицу view в Identity, это будет так, как если бы ваша камера находилась в начале координат в мировом пространстве и смотрела в направлении -z. Таким образом, чтобы получить эффект перемещения камеры в определенную точку наблюдения, это то же самое, что перемещать все объекты в этом мировом пространстве в обратном направлении. То же самое верно и для вращений. А gluLookAt просто настроит поворот и перевод. Взгляните на мой предыдущий ответ о gluLookAt, чтобы узнать некоторые детали.

person derhass    schedule 03.11.2013
comment
Спасибо, но это все еще не отвечает на мой вопрос; почему рисуется мой треугольник? Если камера действительно находится в начале координат, то не должен ли позади камеры находиться треугольник со значением z = 1? - person Sumanth; 04.11.2013