Система координат OpenGL є лівою або правшею?


87

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



3
Чи не залежить це повністю від того, як ви пишете свої трансформації в шейдерах, і тому повністю залежить від вас?
jcoder

Лише мої два центи evl.uic.edu/ralph/508S98/coordinates.html , у ньому є декілька зрозумілих зображень.
rraallvv

Я не думаю, що ви могли б розглянути можливість оновлення прийнятої відповіді?
Джонатан Мі,

Відповіді:


132

Тут є певна плутанина.

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

OpenGL є правою рукою в об'єктному просторі та світовому просторі.

Але у віконному просторі (він же простір на екрані) ми раптом лівші .

Як це сталося ?

Шлях, який ми отримуємо від правші до лівші, - це від’ємний запис масштабування z в матрицях glOrthoабо glFrustumпроекції. Масштабування z на -1 (залишаючи x і y такими, якими вони були) впливає на зміну передачі системи координат.

Для glFrustum,

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

далеко і близько повинні бути позитивними, а далеко > близько . Скажімо далеко = 1000 і близько = 1. Тоді С = - (1001) / (999) = -1,002.

Дивіться тут для більш докладної інформації та діаграм.

З ортографічної точки зору glOrtho генерує матрицю, подібну до цієї:

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

Тут ліворуч , праворуч , знизу та зверху - лише координати для лівої вертикальної , правої вертикальної , нижньої горизонтальної , верхньої горизонтальної площин відсікання (відповідно) .

Однак ближній та далекий літаки вказані по-різному . Параметр ближнього визначається як

  • Близько: відстань до ближчої глибини відсікання. Ця відстань від’ємна, якщо літак повинен знаходитись позаду оглядача.

і далеко:

  • zFar Відстань до дальшої глибини відсікання. Ця відстань від’ємна, якщо літак повинен знаходитись позаду оглядача.

Тут ми маємо типовий обсяг канонічного перегляду

канонічний

Оскільки множник z дорівнює (-2 / (далеко-близько)), знак мінуса ефективно масштабує z на -1 . Це означає, що "z" є повертається лівою рукою під час перегляду перегляду, невідомо для більшості людей, оскільки вони просто працюють у OpenGL як "праворука" система координат.

Отже, якщо зателефонувати

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

Тоді НАЙБЛІЖЧІШИЙ ПЛАВАНЬ на 10 одиниць попереду вас . Де ти? Чому, біля початку координат, з віссю х праворуч, віссю у верхній частині голови та носом, спрямованим до від’ємної осі z (це за замовчуванням "За замовчуванням камера розташована біля початку координат , спрямована вниз по від’ємній осі z і має вектор вгору (0, 1, 0). " ). Отже, ближня площина знаходиться при z = -10. Далекий літак знаходиться на 10 одиниць позаду вас, при z = + 10 .


1
"вектор вперед заперечується в gluLookAt" - чи можете ви підтвердити, що це саме так? Не gluPerspective чи glFrustum чи glOrtho?
Кос

1
Ми раптом лівші від простору для кліпів, а не просто від вікон.
legends2k

3
+1 для всієї відповіді, -1 (зачекайте, швидше -2) для "Шлях, який ми отримуємо від правші до лівші, полягає в тому, що вектор прямої передачі заперечується у стандартній реалізації gluLookAt (), що є функцією всі використовують для створення матриці подання. Коли ви заперечуєте прямий вектор, це впливає на зміну передачі системи координат. " , що є просто сміттям ...
Крістіан Рау,

2
... Отрицання прямого вектора в gluLookAtобчисленні не має нічого спільного зі зміною передачі координатного простору, саме так обчислюється ця матриця (а насправді + z справді "відстає" в праворукому просторі). gluLookAtробить не що інше, як обчислення звичайного твердого перетворення тіла (обертання + переведення) в праворукому просторі. Саме матриці проекції, що використовуються конвеєром з фіксованою функцією (і, як правило, також шейдерами), виконують фактичну зміну передачі при запереченні z-компонента, як ви вже зазначали у своїй відповіді.
Крістіан Рау

2
@bobobobo Ваша приказка, якщо ви обчислюєте свою матрицю перегляду, використовуючи лише функції обертання та перекладу (які, мабуть, ви не звинувачуєте у зміні передачі рук), замість того gluLookAt, що не буде зміни основи, поки gluLookAtце робиться? Однозначно ні (оскільки ви, мабуть, знаєте, що не "всі" використовують gluLookAtдля обчислення матриці перегляду), оскільки, як ви мали б знати, gluLookAtне робить нічого іншого, як купу викликів обертання та перекладу (нехай вони навіть маскуються як зміна терміна " високого рівня" основою " ) без жодних роздумів.
Крістіан Рау

26

За замовчуванням Нормалізована координата пристрою є лівшею.

За замовчуванням glDepthRange [0, 1] (поблизу, далеко) робить вісь + z вказівкою на екран, а + x вправо та + y вгору - це система лівші.

Зміна діапазону глибини на [1, 0] зробить систему правшею.

Цитуючи попередню відповідь Nicol : (закреслення - це моя робота, пояснюється нижче)

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

Викинувши конвеєр із фіксованою функцією, ви маєте справу безпосередньо з "кліп-простором". Специфікація 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) працює, але при використанні обох вони анулювали один одного назад на ліву систему.


Діапазон глибини не може бути [1, -1]. Думаю, ви мали на увазі [1, 0]. Також на це вказувалося раніше .
Nicol Bolas,

Ваша відповідь чудова, шкода, що це питання DirectX, вам слід розмістити його тут!
hultqvist

3
@SigTerm, чому, на вашу думку, виправляти неправдиве твердження не варто? Я витратив кілька годин на усунення несправностей координат вершин та генерації обертання матриці лише для того, щоб з’ясувати, що система координат за замовчуванням насправді не була правшею.
hultqvist

1
Питання полягало в тому, чи це була ліва чи правша. Ця відповідь містить більше деталей, ніж пояснення двох інших способів отримати її правшею, додавання -1 у перетворенні матриці - ще один спосіб зробити це. Але нічого з цього не має значення, якщо ви вважаєте, що система є правшею за замовчуванням, ви можете щось змінити, лише якщо знаєте, з чого змінюєтесь. Все-таки
hultqvist

1
Я знайшов відповідь дуже просвітницькою, і вона з’явилася в пошуках, тому вона для мене того коштувала.
Вивчіть OpenGL ES

13

ТІЛЬКИ NDC

Потрібно лише помітити, що OpenGL знає лише NDC! а це ліва система координат.

Незалежно від того, яку систему координат ви використовуєте - ліворуку або праворуку вісь - систему координат - все потрібно віддзеркалити в NDC. Якщо хочете, ви можете повністю обробляти світовий простір як ліворуку систему координат.

Чому ми зазвичай використовуємо праворуку систему координат у світовому просторі?

Я думаю, це звичайно. Це просто так. Можливо, його просто хочуть відрізнити від DirectX.


3
Думаю, це недостатньо повторюється. Усі ці діаграми, що відображають "моделювання перетворення", "перетворення перегляду", "перетворення перспективи", не показують, що вони не є невід'ємною частиною OpenGL. Ви навіть можете зробити всі свої перетворення вручну, з шейдерами або без них, з матрицями або без них.
Том,

3
Було б приємніше, якщо повторити це, включивши слова "нормалізовані координати пристрою".
Томмі

6
OpenGL випереджає DirectX на кілька років, тому OpenGL, безумовно, не намагався відрізнити себе від DirectX. Провідний розробник DirectX, Алекс Сент-Джон, заявив, що рішення Microsoft піти на ліворуку систему координат було "частково з особистих переваг" і "довільним вибором".
Chris Nolet

Це не зовсім правильно. OpenGL також знає систему координат відсікання, оскільки в ній відбувається відсікання. Система координат кліпу має ту саму передачу, що і система координат NDC.
plasmacel

7

Книга "Посібник із програмування WebGl" Коуїчі Мацуди витрачає майже десять сторінок на тему "WebGl / OpenGl: лівою чи правою рукою?"

Згідно з книгою:

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

  • OpenGl насправді є лівою системою внутрішньо

  • Внутрішньо, глибше це насправді ні те, ні інше. Внизу OpenGl не хвилює значення z. Порядок, у якому ви малюєте речі, визначає, що буде намальовано зверху (спочатку намалюйте трикутник, потім чотирикутник, квадрат перекриває трикутник).

Я не повністю погоджуюся з "ні тим, ні іншим", але це, мабуть, філософське питання.


7
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 фрагмента порівнюється зі значенням в буфері глибини, а фрагмент відкидається, якщо він не вдається перевірити глибину, тому квадратик може або не може замінити трикутник залежно від їх глибини та використана функція глибини.
chrisvarnz

3

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

Змінити: Якщо ви мені не довіряєте, просто експериментуйте у своєму вершинному шейдері, додавши матрицю перекладу, і ви легко зможете побачити, чи є Opengl лівшею чи ні.


0

Використовуючи вбудовані функції проектування та перетворення OpenGL, спостерігаючи за рухами на екрані, дотримуйтесь правил праворукої системи координат. Наприклад, якщо об’єкт перед вашим видом переведений у позитивному напрямку z, тоді об’єкт рухатиметься до вас.

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

Є ще одна система координат, і це область перегляду! Система координат області перегляду така, що + x вказує праворуч, а + y - вниз. Я думаю, що до цього моменту передача є спірною, оскільки ми маємо справу лише з x, y на даний момент.

Нарешті, gluLookAt під капотом повинен заперечити вектор погляду. Оскільки математика передбачає, що вектор спрямований у позитивному напрямку до об'єкта, який він дивиться, а камера дивиться вниз -z, вектор погляду повинен бути заперечений, щоб він вирівнювався з камерою.

Щось жувати. Немає особливого сенсу називати напрямок z праворукої системи координат прямим вектором :). Думаю, Microsoft зрозуміла це, коли розробила Direct3D.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.