Перспективная проекция с OpenGL

Меня смущает перспективная проекция.

Вот сценарий, который меня смущает. Передняя плоскость моей усадьбы в основном расположена на положительной оси 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.


person John Cassidy    schedule 26.02.2012    source источник
comment
задняя панель на оси -ive Я никогда не слышал о оси -ive. Можете ли вы уточнить это, или это просто опечатка? Кроме того, никогда не помещайте матрицу просмотра в матрицу GL_PROJECTION. Идет в GL_MODELVIEW.   -  person Nicol Bolas    schedule 27.02.2012
comment
Я имею в виду, что передняя плоскость присутствует вдоль + ive z a-xis, а задняя плоскость присутствует на -ive оси z. Что-то вроде glFrustrum (-xval, + xval, -yval, + yval, -10, + 10); где ближняя плоскость становится +10 по оси z, а дальняя плоскость становится -10 по оси z   -  person John Cassidy    schedule 27.02.2012
comment
«+ ive» означает «положительный», а «-ive» означает «отрицательный»?   -  person Bart    schedule 27.02.2012
comment
Я время от времени занимаюсь графикой более десяти лет. Я закончил два семестра графики в колледже. И я никогда не слышал об оси z + ive или оси z -ive. Есть просто ось Z, которая идет в положительном и отрицательном направлениях.   -  person Nicol Bolas    schedule 27.02.2012
comment
да точно извините за странный язык. Положительная ось z и отрицательная ось z   -  person John Cassidy    schedule 27.02.2012
comment
позвольте нам понять концепцию предполагаемой проекции, проверьте эту прекрасную интерактивную демонстрацию того, как три точки d проецируются в двухмерном пространстве mathdisk.com/pub/safi/worksheets/Perspective_Projection   -  person    schedule 08.07.2012


Ответы (3)


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

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

: введите описание изображения здесь

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

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 модели.

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

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

person datenwolf    schedule 27.02.2012

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

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

Есть 2 типа проекций: ортографические и перспективные.

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

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

В любом случае содержимое объема обзора «проецируется» на ближайшую плоскость отсечения.

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

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

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

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

Чтобы построить усеченную пирамиду, вам нужно 8 точек, и вы, как правило, захотите построить симметричную усеченную пирамиду, которая упрощает матрицу проекции.

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

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

Просто помните, что проекция превращает 3D в 2D.

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

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

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

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

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

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

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

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

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

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

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

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

person Mandark    schedule 28.02.2012

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

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

Документация по этому поводу довольно ясна:

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

(курсив мой)

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

person Nicol Bolas    schedule 26.02.2012
comment
Спасибо за ваш ответ. Итак, в основном это нужно обрабатывать как с помощью перевода, так и с помощью вращения. У меня есть еще один вопрос. Пожалуйста, не могли бы вы мне помочь? Чтобы решить описанную выше проблему, когда мне следует оставить файл gluLookAt. Как вы упомянули выше, я должен оставить свой gluLookAt в моей части MODELVIEW. Должны ли части смещения и вращения быть перед gluLookAt или после этого? - person John Cassidy; 27.02.2012
comment
Преобразования просмотра применяются после применения всех преобразований моделирования. Моделирование преобразований позиционирует / ориентирует объект относительно друг друга, а преобразование просмотра применяется после, потому что вы сначала хотите расположить что-либо, а затем взглянуть на сцену. Поскольку OpenGL использует порядок столбцов для своих матриц, которые представляют преобразования, вы пишете gluLookAt перед всеми преобразованиями моделирования в коде, но сгенерированное преобразование представления применяется после применения всех преобразований моделирования. - person Mandark; 28.02.2012