Перспективная проекция с OpenGL - PullRequest
9 голосов
/ 27 февраля 2012

Я запутался в перспективной проекции.

Вот сценарий, который меня смущает. Передняя плоскость моего фруструма в основном расположена на положительной оси z, а задняя плоскость на отрицательной оси и повернута на несколько градусов вдоль положительной оси z.

Теперь, когда я прохожу примеры, я вижу, что ближняя и дальняя плоскости все присутствуют на отрицательной оси z.

Мой подход в этом случае был примерно таким:

glMatrixMode(GL_PROJECTION);    
glLoadIdentity();
glFrustrum(-xval,+xval,-yval,+yval,-10,+10);
gluLookAt(); // some point lying on this axis of symmetry about the point
glMatrixMode(GL_MODELVIEW);

Итак, в вышеприведенном случае, какое поведение я должен ожидать для glFrustum с отрицательным и положительным значением для z. в этом случае от -10 до +10.

Ответы [ 3 ]

7 голосов
/ 28 февраля 2012

Объем просмотра определяет, сколько мира вы на самом деле видите, каждый объект снаружи объем просмотра не виден, и все внутри потенциально является видимым (если оно не скрытообъект перед ним).

Форма объема просмотра определяется типом проекции, которую вы используете.

Существует 2 типа проекций: ортографическая и перспективная проекции.

Ортография не учитывает расстояние от зрителя (не естественно, но полезно для программного обеспечения САПР и т. Д.) И перспективные проекции, которые учитывают расстояние от зрителя и, следовательно, объекты, которые находятся дальше, кажутся меньше.

В ортографической проекции объем просмотра представляет собой куб, а в проекции перспектива объем просмотра имеет форму усеченного конуса (ближняя плоскость отсечения меньше, чем дальняя плоскость отсечения).

В любом случае содержимое тома просмотра «проецируется» на ближнюю вырезанную пластинуne.

Конечно, этот процесс немного сложнее, чем простое умножение projection_matrix с каждой вершиной в объеме представления;но в основном это объясняется почти в каждой книге, связанной с OpenGL.

форма объема просмотра до некоторой степени моделирует свойства камеры ... насколько широко вы видите, как далеко вы видите и т. д.

Красная книга хорошо объясняет это в отдельной главе просмотра.

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

Для построенияfrustum вам нужно 8 точек, и вы, как правило, захотите построить симметричный frustum, который упрощает матрицу проекции.

Вместо того, чтобы указывать 8 точек вручную, вы будете использовать вспомогательные методы, такие как gluPerspective (fovy, aspect_ratio, near, far) , который использует "более интуитивные" параметры для построения усеченного конуса;в основном это оболочка для glFrustum, которая вычисляет для вас 8 баллов, а затем вызывает вместо вас glFrustum.

Для OpenGL 3.0 и выше вы предоставите собственную реализацию gluPerspective, вы можете просто погуглить код.

Только помните, что проекция делает 3D 2D.

Что касается просмотра, OpenGL использует правую систему координат (ось x направлена ​​влево, ось y направлена ​​вверх, а ось z направлена ​​наружу экрана).;DirectX использует левостороннюю систему координат.

Помните, что в трехмерном пространстве у вас есть только 2 ориентации системы координат (левая и правая).

Разница заключается в ориентации zось;если вы направите ось z внутрь, это система для левой руки или если вы направите точку z наружу, это будет система для правой руки .

Любое другое направление дляОсь z не сделает ось z перпендикулярной осям x и y, и поэтому у вас не будет системы координат.

Рукопожатие определяет такие вещи, как, в каком направлении происходит положительное вращение и т. д.

Ваша камера расположена в начале координат (0,0,0) и по умолчанию направлена ​​вниз по оси -z ;и так будет до тех пор, пока вы не примените какое-либо преобразование.

Положение вашего взгляда строится вокруг направления просмотра, а ближняя плоскость отсечения расположена в точке z = - около камеры, которая расположенаизначально в начале координат.

Когда вы указываете около и далеко в качестве положительных значений для glFrustum, вы не указали их z расположение, простотак получается, что ближняя плоскость отсечения расположена в z = -near из-за ориентации камеры по умолчанию вдоль отрицательной оси z и потому, что камера изначально находится в исходном положении (0,0,0), а вашаближняя плоскость отсечения всегда вблизи вдали от положения глаз зрителя или положения камеры.

И всякий раз, когда вы меняете вид (изменяете положение камеры, меняете ориентацию камеры или и то, и другое), ваше усеченное кольцо все равно будет «оборачиваться вокруг нового направления просмотра», а ближняя плоскость отсечения будет по-прежнему «близко» от нового положения камеры. .

Надеюсь, вы поняли концепцию.

Frustum определяет, сколько.

Независимо от того, где стоит камера и укажите.

4 голосов
/ 27 февраля 2012

Итак, в приведенном выше случае, какое поведение я должен ожидать для glFrustum с отрицательным и положительным значением для z. в данном случае от -10 до +10.

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

Документация совершенно ясна в этом:

nearVal , farVal : Укажите расстояния до ближней и дальней глубинных плоскостей отсечения. Оба расстояния должны быть положительными.

(выделение добавлено)

Передача отрицательного числа (или нуля) для этих значений вызовет ошибку.

2 голосов
/ 27 февраля 2012

Теперь, когда я перехожу через примеры, я вижу, что ближняя и дальняя плоскости присутствуют на оси -ive z.

Конечно.В противном случае вы получите что-то вроде этого

: enter image description here

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

glMatrixMode(GL_PROJECTION);    
glLoadIdentity();
glFrustrum(-xval,+xval,-yval,+yval,-10,+10);
gluLookAt(); // some point lying on this axis of symmetry about the point
glMatrixMode(GL_MODELVIEW);

Проекция не предназначена для размещения вида,Проекция - это своего рода «объектив» вашей виртуальной камеры.Вы можете использовать его для наклона и сдвига объектива и установки «фокусного расстояния».Но это не значит «разместить камеру».Это должно происходить через модель view matrix.

Итак, в вышеприведенном случае, какое поведение я должен ожидать для glFrustum с отрицательным и положительным значением дляв этом случае zie от -10 до + 10.

От дальнего до «ближнего» плана объекты будут увеличиваться по мере приближения к 0, для Z = 0 они находятся в сингулярности и дуютвверх, а затем приближаясь к ближнему, они станут меньше, но будут инвертированы, то есть повернуты на 180 ° вокруг оси Z, а значения глубины повернуты, т.е. сортировка по глубине с помощью проверки глубины отклонит фрагменты ближе, чем к 0.

...