2013-03-23 3 views
25

Как я изучаю OpenGL, я часто спотыкаюсь на так называемые координаты пространства глаз.Что такое координаты пространства глаз?

Если я прав, у вас обычно есть три матрицы. Модельная матрица, матрица представлений и матрица проекций. Хотя я не совсем уверен, как работает математика, я знаю, что конвертировать координаты в мировое пространство, просматривать пространство и пространство экрана.

Но где пространство для глаз и какие матрицы мне нужно, чтобы превратить что-то в пространство для глаз?

ответ

55

Возможно, следующий рисунок, показывающий взаимосвязь между различными пространствами поможет: The OpenGL transformation pipeline

В зависимости, если вы используете фиксированную функцию трубопровод (вы, если вы звоните glMatrixMode(), например), или с помощью шейдеров, операции идентичны - речь идет только о том, закодируете ли вы их непосредственно в шейдере, или конвейер OpenGL помогает в вашей работе.

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

В унаследованной OpenGL (то есть версии до OpenGL 3.1, или с использованием профилей совместимости), определяются две матричные стеки: модель-представление и проекции, а когда приложение начинает матрицу в верхней части каждой stack - это единичная матрица (1.0 по диагонали, 0.0 для всех остальных элементов). Если вы рисуете координаты в этом пространстве, вы фактически показываете в нормализованных координатах устройства (NDC), которые вырезают любые вершины вне диапазона [-1,1] как в X, Y, так и в Z. Поле просмотра преобразование (как установлено по телефону glViewport()) - это то, что отображает НДЦ в координаты окна (ну, координаты видового экрана, действительно, но чаще всего окно просмотра и окна имеют одинаковый размер и местоположение), а значение глубины в диапазоне глубин (по умолчанию это [0,1]).

Теперь в большинстве приложений первое преобразование, которое указано, представляет собой проекционное преобразование , которое представлено в двух вариантах: орфографических и перспективных проекциях. Профильная проекция сохраняет углы и обычно используется в научных и технических приложениях, поскольку она не искажает относительные длины сегментов линии. В устаревшем OpenGL орфографические проекции указаны либо glOrtho, либо gluOrtho2D. Чаще всего используются перспективные преобразования, которые имитируют работу глаз (т. Е. Объекты далеко от глаза меньше, чем те, которые находятся близко), и указаны либо glFrustum, либо gluPerspective. Для перспективных проекций они определили просмотр усеченного конуса, который представляет собой усеченную пирамиду, закрепленную на месте глаз, которые указаны в координатах глаз. В координатах глаз «глаз» расположен в начале координат и смотрит вниз по оси -Z. Ваши вблизи и плоских плоскостях отсечения указаны как расстояния вдоль оси -Z. Если вы визуализируете координаты глаз, любая геометрия, заданная между плоскостями ближнего и дальнего отсечения, и внутренняя часть смотрового усечения не будет отбракована и будет преобразована, чтобы появиться в окне просмотра.Вот диаграмма перспективной проекции и ее отношение к плоскости изображения Viewing frustum.

Глаз расположен на вершине смотрового усечения.

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

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

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

Теперь, если вы делаете этот современный OpenGL (основные профили 3.1 и вперед), вы должны выполнять все эти операции логически самостоятельно (вы можете указать только одно преобразование, складывающее преобразования модели и проекции в однократная матрица умножается). Матрицы указываются обычно как шейдер uniforms. Нет матричных стеков, разделения преобразований модели и проекции, и вам нужно правильно вычислить математику для эмуляции конвейера. (BTW, разделение перспективы и шаги преобразования видового экрана выполняются OpenGL после завершения вашего вершинного шейдера - вам не нужно делать математику [вы можете, это ничего не болит, если вы не сможете установить w до 1.0 в вашем выводе вершинного шейдера gl_Position).

+3

Ничего себе, это очень подробное и понятное описание. Мне эта тема понятна. Кстати, я использую шейдеры. – danijar

+2

На самом деле, z-координата в NDC также находится в диапазоне [-1,1], и это преобразование вида, которое помещает его в диапазон [0,1], используя параметры 'glDepthRange'. Поэтому координаты окна не должны рассматриваться как 2D, но 3D. –

+0

@AndreasHaferburg: На самом деле, вы оба правы. В D3D NDC фактически имеет диапазон Z [** 0 **, ** 1 **], что означает, что NDC не является технически кубом в D3D. GL использует [** - 1 **, ** 1 **] во всех направлениях для NDC (таким образом, это куб), но диапазон глубины по умолчанию (и он *** зажимается *** до этого диапазона) в GL - ** 0.0 ** -> ** 1.0 **. Учитывая вопрос о GL, я бы проигнорировал поведение D3D, но я даю радикальное преимущество в сомнении - *** может быть ** он думал о D3D? * –

36

Пространство глаз, пространство для просмотра и пространство для камеры являются синонимами для одного и того же: мир относительно камеры.