Система координат OpenGL - левша или правша?

Я пытаюсь понять систему координат OpenGL. Тем не менее, некоторые учебники говорят, что система координат по умолчанию левша (см. http://www.c-sharpcorner.com/UploadFile/jeradus/OpenGLBasics11172005014307AM/OpenGLBasics.aspx), а другие говорят, что она правша (см. http://www.falloutsoftware.com/tutorials/gl/gl0.htm). Что правильно? Я понимаю, что мы можем преобразовать одно в другое путем зеркального отражения, но я хотел бы знать координаты по умолчанию.

5 ответов

Решение

Система координат правша. Первая статья кажется неправильной.

Здесь есть некоторая путаница.

OpenGL правша в пространстве объектов и мировом пространстве.

Но в пространстве окна (он же пространство экрана) мы вдруг оказались левшами.

Как это случилось?

То, как мы получаем от правой руки к левой руке, является отрицательной Z-масштабирующей записью в glOrtho или же glFrustum проекционные матрицы. Масштабирование z на -1 (оставляя x и y без изменений) приводит к изменению управляемости системы координат.

Для glFrustum,

дальний и ближний должны быть положительными, а дальний > ближний. Скажи далеко =1000, а рядом =1. Тогда C= -( 1001) / ( 999) = -1,002.

Смотрите здесь для более подробной информации и диаграмм.

С орфографической точки зрения, glOrtho генерирует такую ​​матрицу:

Здесь, слева, справа, снизу и сверху - это координаты для левой вертикальной, правой вертикальной, нижней горизонтальной, верхней горизонтальной плоскостей отсечения (соответственно).

Однако ближняя и дальняя плоскости указаны по-разному. Ближайший параметр определяется как

  • Рядом: расстояние до ближайшей плоскости отсечения глубины. Это расстояние отрицательно, если самолет должен быть позади зрителя.

и далеко:

  • zFar Расстояние до плоскости отсечения глубины. Это расстояние отрицательно, если самолет должен быть позади зрителя.

Здесь мы имеем типичный канонический объем представления

канонический

Поскольку множитель z равен (-2/(далеко-близко)), знак минус эффективно масштабирует z на -1. Это означает, что "z" поворачивается левой рукой во время преобразования просмотра, без ведома большинства людей, поскольку они просто работают в OpenGL как "правая" система координат.

Итак, если вы позвоните

glOrthof(-1, 1, -1, 1, 10, -10) ; // near=10, FAR=-10,

Тогда ближайший самолет на 10 единиц впереди вас. Где ты? Почему, в начале координат, с осью X справа от вас, с осью Y в верхней части головы, а нос направлен вниз по отрицательной оси Z (это значение по умолчанию ). По умолчанию камера расположена в исходной точке., указывает на отрицательную ось z и имеет вектор увеличения (0, 1, 0). "). Таким образом, ближняя плоскость находится в точке z=-10. Дальний самолет находится на расстоянии 10 единиц позади вас, при z = + 10.

По умолчанию нормализованная координата устройства - левша.

По умолчанию glDepthRange [0, 1] (ближний, дальний) направляет ось +z на экран, а +x вправо и +y вверх - это левосторонняя система.

Изменение диапазона глубины на [1, 0] сделает систему правой рукой.

Цитирую предыдущий ответ Николя: (зачеркнутая работа - моя работа, объясненная ниже)

Я удивлен, что никто не упомянул что-то: OpenGL работает и в левой системе координат. По крайней мере, так происходит, когда вы работаете с шейдерами и используете диапазон глубины по умолчанию.

После того, как вы выбросили конвейер с фиксированной функцией, вы имеете дело непосредственно с "clip-space". Спецификация OpenGL определяет пространство клипа как 4D однородную систему координат. Когда вы следуете за преобразованиями через нормализованные координаты устройства и до места в окне, вы найдете это.

Пространство окна находится в пространстве пикселей окна. Начало координат находится в нижнем левом углу, +Y идет вверх, а +X направо. Это очень похоже на правую систему координат. Но как насчет Z?

Диапазон глубины по умолчанию (glDepthRange) устанавливает близкое значение Z в 0, а дальнее значение Z в единицу. Так что +Z уходит от зрителя.

Это левая система координат. Да, ты можешь изменить тест глубины с GL_LESS на GL_GREATER и измените glDepthRange с [0, 1] на [1, 0]. Но стандартное состояние OpenGL - работа в левой системе координат. И ни одно из преобразований, необходимых для того, чтобы попасть в пространство окна из пространства клипа, не отменяет Z. Таким образом, пространство клипа, вывод вершинного (или геометрического) шейдера, является пространством для левши (вроде. Это однородное пространство 4D, поэтому трудно придавить руки).

В конвейере с фиксированной функцией стандартные проекционные матрицы (созданные glOrtho, glFrustum и т.п.) все преобразуются из правостороннего пространства в левостороннее. Они переворачивают значение Z; просто проверьте матрицы, которые они генерируют. В глазном пространстве +Z движется к зрителю; в пост-проекционном пространстве он уходит.

Я подозреваю, что Microsoft (и GLide) просто не удосужились выполнить отрицание в своих матрицах проекции.

Я ударил одну часть, так как она отличалась от моих выводов.

Изменение либо DepthRange, либо DepthFunc и использование ClearDepth(0) работает, но при использовании обоих они отменяют друг друга обратно в левостороннюю систему.

ТОЛЬКО НДЦ

Вы должны только заметить, что OpenGL only knows NDC!! и это левая координата. Независимо от того, какую координату вы используете, левую, правую координату оси и т. д. Все должно быть отражено в NDC. Если хотите, вы можете полностью написать мировое пространство в левой координате.

Почему мы используем правую правую координату в мировом пространстве?

Я думаю, что это обычное дело. Просто так. Может, просто хочется отличить его от DirectX.

Книга Куиджи Мацуда "Руководство по программированию WebGl" посвящена почти десяти страницам "WebGl/OpenGl: влево или вправо?"

Согласно книге:

  • На практике большинство людей используют правостороннюю систему

  • OpenGl на самом деле внутренняя левосторонняя система

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

Я не полностью согласен с "это ни то, ни другое", но это, вероятно, философский вопрос в любом случае.

Opengl определенно левша. Вы видите много обучающих программ, утверждающих обратное, потому что они отрицают z-значение в матрице проекции. Когда окончательные вершины вычисляются внутри вершинного шейдера, он преобразует вершины, которые вы передаете от клиентской части (правая координата), в левую, и вершины затем передаются в геометрический шейдер и фрагментный шейдер. Если вы используете правую систему координат на стороне клиента, Opengl не волнует. Он знает только нормализованную систему координат, которая левша.

Изменить: Если вы не доверяете мне, просто поэкспериментируйте в своем вершинном шейдере, добавив матрицу перевода, и вы легко сможете увидеть, является ли Opengl левшой или нет.

Используя встроенные в OpenGL функции проецирования и трансформации, наблюдение за движениями на экране следует правилам правой системы координат. Например, если объект перед вашим видом перемещается в положительном направлении оси z, то этот объект будет двигаться к вам.

Буфер глубины совершенно противоположен, и здесь в игру вступают NDC (нормализованные координаты устройства). Если передача GL_LESS в glDepthFunc означает, что пиксели будут отрисовываться, когда они будут ближе к вам, чем то, что уже находится в буфере глубины, то считается, что пиксели находятся в левой системе координат.

Есть еще одна система координат, и это область просмотра! Система координат области просмотра такова, что +x указывает вправо, а +y указывает вниз. Я думаю, что на данный момент своеволие является спорным, так как мы имеем дело только с й, у в этой точке.

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

Что-нибудь пожевать. Нет особого смысла называть направление z правой системы координат прямым вектором:). Я думаю, что Microsoft осознала это, когда разработала Direct3D.

Другие вопросы по тегам