Я пытаюсь понять систему координат OpenGL. Однако в некоторых руководствах говорится, что система координат по умолчанию - левосторонняя (см. Http://www.c-sharpcorner.com/UploadFile/jeradus/OpenGLBasics11172005014307AM/OpenGLBasics.aspx ), а в других - правша (см. Http: // www. .falloutsoftware.com / tutorials / gl / gl0.htm ). Что правильно? Я понимаю, что мы можем преобразовать одно в другое путем зеркалирования, но я хотел бы знать координаты по умолчанию.
opengl
coordinates
341008
источник
источник
Ответы:
Здесь есть некоторая путаница.
OpenGL прав в объектном и мировом пространстве.
Но в оконном пространстве (он же экранное пространство) мы внезапно оказываемся левшами .
Как это случилось ?
Способ перехода от правшей к левым - это отрицательная запись масштабирования по z в матрицах проекции
glOrtho
илиglFrustum
. Масштабирование z на -1 (оставляя x и y такими, какие они были) приводит к изменению управляемости системы координат.Для glFrustum,
дальний и близкий должны быть положительными, а дальний > ближний . Скажите far = 1000 и near = 1. Тогда C = - (1001) / (999) = -1,002.
Смотрите здесь для получения более подробной информации и диаграмм.
С орфографической точки зрения glOrtho генерирует такую матрицу:
Здесь left , right , bottom и top - это просто координаты для левой вертикальной , правой вертикальной , нижней горизонтальной , верхней горизонтальной плоскостей отсечения (соответственно) .
Однако ближняя и дальняя плоскости указываются по-разному . Рядом параметр определен как
и далеко:
Вот типичный канонический объем просмотра
Поскольку множитель z равен (-2 / (далеко-близко)), знак минус эффективно масштабирует z на -1 . Это означает, что «z» поворачивается влево во время преобразования просмотра, без ведома большинства людей, поскольку они просто работают в OpenGL как «правосторонняя» система координат.
Итак, если вы позвоните
Тогда БЛИЖНИЙ САМОЛЕТ будет на 10 единиц впереди вас . Где ты? Почему в начале координат ось x находится справа от вас, ось Y находится на верхней части головы, а ваш нос направлен вниз по отрицательной оси z (это значение по умолчанию "По умолчанию камера расположена в начале координат , указывает вниз по отрицательной оси Z и имеет вектор вверх (0, 1, 0). " ). Таким образом, ближняя плоскость находится на z = -10. Дальний самолет находится на 10 единиц позади вас, на z = + 10 .
источник
gluLookAt
вычислении не имеет ничего общего с изменением направленности координатного пространства, это именно то, как вычисляется эта матрица (и на самом деле + z действительно "назад" в правом пространстве).gluLookAt
не делает ничего, кроме вычисления обычного преобразования твердого тела (вращение + перенос) в правостороннем пространстве. Как вы уже отметили в своем ответе, именно матрицы проекции, используемые фиксированным конвейером функций (и обычно шейдерами тоже), выполняют фактическое изменение руки при отрицании z-компонента.gluLookAt
этого не будет изменения основы, пока этоgluLookAt
происходит? Определенно нет (поскольку вы, вероятно, знаете, что не «все» используютgluLookAt
для вычисления матрицы представления), поскольку, как вы должны знать,gluLookAt
не делает ничего, кроме набора вызовов поворота и перевода (даже если они замаскированы под изменение термина « высокого уровня» base " ) без каких-либо отражений.По умолчанию нормализованная координата устройства левосторонняя.
GlDepthRange по умолчанию [0, 1] (близко, далеко), что делает точку оси + z на экране, а с + x вправо и + y вверх это система для левшей.
Изменение диапазона глубины на [1, 0] сделает систему правосторонней.
Цитата из предыдущего ответа Николая : (зачеркнутый - моя работа, объяснено ниже)
Я поразил одну часть, поскольку она расходилась с моими выводами.
Либо изменение DepthRange, либо DepthFunc и использование ClearDepth (0) работает, но при использовании обоих они компенсируют друг друга обратно в левостороннюю систему.
источник
ТОЛЬКО НДЦ
Вы должны только заметить, что OpenGL знает только NDC! и это левая система координат.
Независимо от того, какую систему координат вы используете - левую или правую систему осевых координат - все они должны быть отражены в NDC. Если хотите, вы можете полностью обрабатывать мировое пространство как левую систему координат.
Почему мы обычно используем правую систему координат в мировом пространстве?
Думаю, это условно. Это просто так. Может, его просто хотят отличить от DirectX.
источник
В книге "Руководство по программированию WebGl" Коити Мацуда почти десять страниц посвящено теме "WebGl / OpenGl: для левой или правой руки?"
По книге:
На практике большинство людей используют праворукую систему.
OpenGl внутренне является системой для левшей
Внутренне, глубже, на самом деле ни то, ни другое. В самом низу OpenGl не заботится о z-значении. Порядок, в котором вы рисуете объекты, определяет, что будет нарисовано сверху (сначала нарисуйте треугольник, затем четырехугольник, четырехугольник переопределяет треугольник).
Я не полностью согласен с «ни то, ни другое», но это, вероятно, в любом случае философский вопрос.
источник
The order in which you draw things determines what is drawn on top (draw a triangle first, then a quad, the quad overrides the triangle).
Это правда, в отсутствие тестирования глубины. При наличии проверки глубины значение z фрагмента сравнивается со значением в буфере глубины, и фрагмент отбрасывается, если он не проходит проверку глубины, поэтому квад может или не может перезаписать треугольник в зависимости от их глубины и Используемая функция глубины.Opengl определенно левша. Вы видите множество руководств, в которых говорится об обратном, потому что они отрицают z-значение в матрице проекции. Когда конечные вершины вычисляются внутри вершинного шейдера, он преобразует вершины, которые вы передаете со стороны клиента (правая координата) в левую, а затем вершины передаются геометрическому шейдеру и фрагментному шейдеру. Если вы используете правую систему координат на стороне клиента, Opengl все равно. Он знает только нормализованную систему координат, которая является левосторонней.
Изменить: если вы мне не доверяете, просто поэкспериментируйте со своим вершинным шейдером, добавив матрицу перевода, и вы легко увидите, левша Opengl или нет.
источник
Используя встроенные функции проекции и трансформации OpenGL, наблюдение за движениями на экране следует правилам правой системы координат. Например, если объект перед вашим видом перемещается в положительном направлении оси z, то этот объект будет двигаться к вам.
Буфер глубины совершенно противоположен, и здесь в игру вступают NDC (нормализованные координаты устройства). Если передача GL_LESS в glDepthFunc означает, что пиксели будут отрисовываться, когда они будут ближе к вам, чем то, что уже находится в буфере глубины, то считается, что пиксели живут в левой системе координат.
Есть еще одна система координат, и это область просмотра! Система координат области просмотра такова, что + x указывает вправо, а + y указывает вниз. Я думаю, что на данный момент своеволие является спорным, так как мы имеем дело только с й, у в этой точке.
Наконец, gluLookAt под капотом должна нейтрализовать вектор взгляда. Поскольку математика предполагает, что вектор направлен в положительном направлении к объекту, на который он смотрит, а камера смотрит вниз -z, вектор взгляда должен быть инвертирован, чтобы он выровнялся с камерой.
Что-нибудь пожевать. Нет смысла называть направление z правой системы координат прямым вектором :). Я думаю, что Microsoft осознала это, когда разработала Direct3D.
источник