OpenGL 좌표계는 왼손잡이입니까, 오른 손잡이입니까?


85

OpenGL 좌표계를 이해하려고합니다. 그러나 일부 자습서에서는 기본 좌표계가 왼손잡이 라고 말하고 ( http://www.c-sharpcorner.com/UploadFile/jeradus/OpenGLBasics11172005014307AM/OpenGLBasics.aspx 참조 ) 다른 자습서에서는 오른 손잡이 라고 말합니다 ( http : // www 참조 .falloutsoftware.com / tutorials / gl / gl0.htm ). 어느 것이 맞습니까? 미러링을 통해 서로 변환 할 수 있다는 것을 이해하지만 기본 좌표를 알고 싶습니다.



2
이것은 셰이더에서 트랜스 폼을 작성하는 방법에 전적으로 의존하지 않습니까?
jcoder 2013 년

내 2 센트 evl.uic.edu/ralph/508S98/coordinates.html , 몇 가지 자명 한 이미지가 있습니다.
rraallvv

수락 된 답변을 업데이트하는 것을 고려하지 않겠습니까?
Jonathan Mee

답변:


132

여기에 약간의 혼란이 있습니다.

여기에 이미지 설명 입력

OpenGL은 오른 손잡이입니다. 객체 공간과 세계 공간에서 입니다.

그러나 창 공간 (일명 화면 공간)에서는 갑자기 왼손잡이가 됩니다.

어떻게 된 일 입니까?

오른 손잡이에서 왼손잡이로가는 방법은 glOrtho또는 glFrustum투영 행렬 의 음의 z 스케일링 항목입니다 . z를 -1로 축척하면 (x와 y는 그대로두고) 좌표계의 손길을 변경하는 효과가 있습니다.

glFrustum의 경우

여기에 이미지 설명 입력 여기에 이미지 설명 입력

farnear 는 양수 여야하며 far > near . 말 까지 = 1000 근처 = 1. 그러면 C =-(1001) / (999) = -1.002.

자세한 내용과 다이어그램 은 여기 를 참조 하십시오 .

에서 직교 사시도 , glOrtho 이런 행렬을 생성한다 :

여기에 이미지 설명 입력

여기서 left , right , bottomtopleft vertical , right vertical , bottom horizontal , top horizontal clip planes (resp) 의 좌표입니다 .

그러나 근거리원거리 평면 은 다르게 지정됩니다 . 근처 파라미터로 정의

  • 근거리 : 더 가까운 깊이 클리핑 평면까지 의 거리 입니다. 비행기가 시청자 뒤에있을 경우이 거리는 음수입니다.

그리고 멀리 :

  • zFar 더 먼 깊이 클리핑 평면까지 의 거리 입니다. 비행기가 시청자 뒤에있을 경우이 거리는 음수입니다.

여기에 일반적인 표준 뷰 볼륨이 있습니다.

정식

z 승수가 (-2 / (근거리))이기 때문에 마이너스 기호는 z를 -1로 효과적으로 스케일 합니다. 이것은 "z"가 왼손잡이 임을 의미합니다. , OpenGL에서 단순히 "오른손"좌표계로 작업하기 때문에 대부분의 사람들이 모르는 사이에보기 변환 중에 바뀝니다.

그래서 전화하면

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

그러면 NEAR PLANE이 10 단위 앞서 있습니다 . 어디야? 원점에서 x 축은 오른쪽, y 축은 머리 위에, 코 는 음의 z 축을 가리키고 있습니다 (기본값 "기본적으로 카메라는 원점에 있습니다. , 음의 z 축 아래를 가리키고 상향 벡터가 (0, 1, 0)입니다. " ). 따라서 가까운 평면은 z = -10에 있습니다. 먼 평면은 z = + 10에서 10 단위 뒤에 있습니다 .


1
"순방향 벡터는 gluLookAt에서 부정됩니다."-이것이 사실임을 확인할 수 있습니까? gluPerspective, glFrustum 또는 glOrtho가 아닙니까?
Kos

1
창 공간뿐만 아니라 클립 공간에서 갑자기 왼손잡이가 됩니다.
legends2k 2013

3
전체 답변에 +1, "오른 손잡이에서 왼손잡이로가는 방법은 함수 인 gluLookAt ()의 표준 구현에서 포워드 벡터가 부정되기 때문입니다. 모두가 뷰 행렬을 만드는 데 사용합니다. 전방 벡터를 부정하면 좌표계의 손이 닿는 정도를 변경하는 효과가 있습니다. " , 이는 단순한 쓰레기는 ...이다
기독교 라우

2
... gluLookAt계산 에서 순방향 벡터를 부정하는 것은 좌표 공간의 손길을 변경하는 것과는 아무 관련이 없습니다. 이것이 바로이 행렬이 계산되는 방식입니다 (실제로 + z는 실제로 오른쪽 공간에서 "뒤" 입니다). gluLookAt오른 손잡이 공간에서 일반적인 강체 변형 (회전 + 이동)을 계산하는 것 외에는 아무것도하지 않습니다. 답변에서 이미 언급했듯이 z 구성 요소의 부정에서 실제 손재주 변경을 수행하는 것은 고정 함수 파이프 라인 (일반적으로 셰이더에서도 사용)에서 사용하는 프로젝션 행렬입니다.
Christian Rau 2013 년

2
@bobobobo 회전 및 변환 기능 만 사용하여 뷰 매트릭스를 계산하면 (손잡이를 변경하는 것에 대해 비난하지 않을 것이라고 생각합니다) 대신 gluLookAt에 기준이 변경되지 않을 것이라고 생각 gluLookAt하십니까? 확실히 아닙니다 ( "모든 사람"gluLookAt 이 뷰 매트릭스 계산에 사용 하는 것은 아님을 아마 알고 있기 때문입니다). 알고 있어야하는 것처럼 gluLookAt회전 및 변환 호출 ( "고수준" 용어 "변화의 변화 " 로 위장한 경우 기초 " ) 반사가 전혀 포함되지 않습니다.
Christian Rau 2013 년

26

기본적으로 정규화 된 장치 좌표는 왼손잡이입니다.

glDepthRange는 기본적으로 [0, 1] (근거리, 원거리)로 + z 축이 화면을 가리 키도록하고 + x를 오른쪽으로, + y를 위로하면 왼손잡이 시스템입니다.

깊이 범위를 [1, 0]으로 변경하면 시스템이 오른 손잡이가됩니다.

Nicol 의 이전 답변 인용 : ( 취소 선 은 내 작업이며 아래에 설명되어 있습니다)

아무도 언급하지 않은 것에 놀랐습니다. OpenGL은 왼손 좌표계에서도 작동합니다. 적어도 셰이더로 작업하고 기본 깊이 범위를 사용할 때 수행됩니다.

고정 함수 파이프 라인을 버리면 "클립 공간"을 직접 처리합니다. OpenGL 사양은 클립 공간을 4D 동종 좌표계로 정의합니다. 정규화 된 장치 좌표를 통해 변환을 수행하고 창 공간으로 내려 가면 이것을 찾을 수 있습니다.

창 공간은 창의 픽셀 공간에 있습니다. 원점은 왼쪽 아래 모서리에 있으며 + Y는 위로, + X는 오른쪽으로 이동합니다. 그것은 오른손 좌표계와 매우 흡사하게 들립니다. 하지만 Z는 어떻습니까?

기본 깊이 범위 (glDepthRange)는 가까운 Z 값을 0으로 설정하고 먼 Z 값을 1로 설정 합니다. 따라서 + Z는 뷰어에서 멀어 집니다.

그것은 왼손 좌표계입니다. 그래 넌 할수있어깊이 테스트를 GL_LESS에서 GL_GREATER로 변경하고glDepthRange를 [0, 1]에서 [1, 0]으로 변경합니다. 그러나 OpenGL 의 기본 상태는 왼손 좌표계 에서 작동하는 것입니다 . 클립 공간에서 창 공간에 도달하는 데 필요한 변환은 Z를 무효화하지 않습니다. 따라서 클립 공간, 정점 (또는 지오메트리) 셰이더의 출력은 왼손잡이 공간입니다 (일종. 4D 동종 공간입니다. 손을 잡는 것은 어렵다).

고정 된 함수 파이프 라인에있어서, 표준 돌출부 행렬은 (glOrtho, glFrustum와 같이 제조) 모두에 오른손 공간으로 변형 왼손잡이 하나. 그들은 Z의 의미를 뒤집습니다. 그들이 생성하는 행렬을 확인하십시오. 눈 공간에서 + Z는 시청자쪽으로 이동합니다. 투사 후 공간에서는 멀리 이동합니다.

나는 마이크로 소프트 (그리고 GLide)가 그들의 프로젝션 매트릭스에서 부정을 수행하는 것을 귀찮게하지 않았다고 생각합니다.

나는 그것이 내 발견과 갈라 졌기 때문에 한 부분을 공격했습니다.

DepthRange 또는 DepthFunc를 변경하고 ClearDepth (0)을 사용하면 작동하지만 둘 다 사용할 때 서로를 취소하여 왼손잡이 시스템으로 되돌립니다.


깊이 범위는 [1, -1] 일 수 없습니다. [1, 0]을 의미한다고 생각합니다. 또한 이것은 이전에 지적되었습니다 .
Nicol Bolas 2012

귀하의 답변은 훌륭합니다. DirectX 질문에 대한 답이 너무 나쁩니다. 여기에 다시 게시해야합니다!
hultqvist

3
@SigTerm 왜 거짓 진술을 수정하는 것이 그만한 가치가 없다고 생각합니까? 실제로 기본 좌표계가 오른 손잡이가 아니라는 것을 알아 내기 위해 정점 좌표 및 행렬 회전 생성 문제를 해결하는 데 몇 시간을 보냈습니다.
hultqvist

1
문제는 그것이 왼손잡이인지 오른 손잡이 시스템인지였다. 이 답변은 그보다 더 많은 세부 정보를 가지고 있으며, 오른 손잡이를 얻는 두 가지 다른 방법을 설명합니다. 행렬 변환에 -1을 추가하는 것은 또 다른 방법입니다. 그러나 시스템이 기본적으로 오른 손잡이라고 생각하는 경우 그 어느 것도 중요하지 않으며, 무엇을 변경하고 있는지 알고있는 경우에만 변경할 수 있습니다. 그럼에도 불구하고
hultqvist

1
나는 그 답이 매우 깨달음을 얻었고 검색에서 나왔기 때문에 그만한 가치가있었습니다.
OpenGL ES 배우기

13

NDC 만

당신은 통지해야 OpenGL을 만 NDC을 알고있다! 그것은 왼손 좌표계입니다.

사용하는 좌표계 (왼손잡이 또는 오른 손잡이 축 좌표계)에 관계없이 모두 NDC에 미러링되어야합니다. 원한다면 왼손 좌표계로 월드 공간을 완전히 다룰 수 있습니다.

왜 우리는 일반적으로 세계 공간에서 오른손 좌표계를 사용합니까?

나는 그것이 전통적인 것이라고 생각합니다. 그냥 그렇습니다. DirectX와 구별하고 싶을 수도 있습니다.


3
나는 이것이 충분히 반복되지 않는다고 생각한다. "모델링 변환", "뷰 변환", "원근 변환"을 보여주는 이러한 모든 다이어그램은 OpenGL의 본질적인 부분이 아님을 보여주지 못합니다. 셰이더를 사용하거나 사용하지 않고 매트릭스를 사용하거나 사용하지 않고 모든 변환을 수동으로 수행 할 수도 있습니다.
Tom

3
"정규화 된 장치 좌표"라는 단어를 포함하도록 반복하면 더 좋을 수 있습니다.
Tommy

6
OpenGL은 DirectX보다 몇 년 앞선 것이므로 OpenGL은 확실히 DirectX와 구별되지 않았습니다. DirectX의 수석 개발자 인 Alex St. John은 왼손잡이 좌표계를 사용하기로 한 Microsoft의 결정은 "부분적으로 개인적 선호도"와 "임의의 선택"이라고 말했습니다.
Chris Nolet 2017

이것은 전적으로 정확하지 않습니다. OpenGL은 또한 클리핑이 발생하기 때문에 클리핑 좌표계를 알고 있습니다. 클립 좌표계는 NDC 좌표계와 동일합니다.
plasmacel

7

Kouichi Matsuda의 "WebGl Programming Guide"책은 "WebGl / OpenGl : Left or Right Handed?"에 대해 거의 10 페이지를 씁니다.

책에 따르면 :

  • 실제로 대부분의 사람들은 오른 손잡이 시스템을 사용합니다.

  • OpenGl은 실제로 내부적으로 왼손잡이 시스템입니다.

  • 내부적으로 더 깊게 말하자면 실제로 둘 다 아닙니다. 맨 아래에서 OpenGl은 z 값에 대해 신경 쓰지 않습니다. 그리는 순서에 따라 맨 위에 그려지는 항목이 결정됩니다 (삼각형을 먼저 그린 다음 쿼드를 그리면 쿼드가 삼각형보다 우선합니다).

나는 "그것도 아니다"에 완전히 동의하지는 않지만 어쨌든 그것은 아마도 철학적 인 질문 일 것이다.


6
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 (Normalized Device Coordinates)가 작동합니다. GL_LESS를 glDepthFunc에 전달하면 픽셀이 이미 깊이 버퍼에있는 것보다 더 가까이있을 때 픽셀이 그려진다는 것을 의미한다면 픽셀은 왼손 좌표계 에있는 것으로 간주됩니다 .

좌표계가 하나 더 있습니다. 이것이 바로 뷰포트입니다! 뷰포트의 좌표계는 + x가 오른쪽을 가리키고 + y가 아래를 가리 키도록합니다. 나는이 시점에서 우리가 x, y만을 다루고 있기 때문에 손 잡음이 문제라고 생각합니다.

마지막으로 gluLookAt은 look-at 벡터를 무효화해야합니다. 수학에서는 벡터가보고있는 객체를 향한 양의 방향을 가리키고 카메라가 -z를 내려다보고 있다고 가정하므로, 룩앳 벡터는 카메라와 정렬되도록 부정해야합니다.

씹을 것. 오른손 좌표계의 z 방향을 전방 벡터라고 부르는 것은 의미가 없습니다. :). 나는 마이크로 소프트가 Direct3D를 설계했을 때 이것을 깨달았다 고 생각합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.