Hệ tọa độ OpenGL thuận tay trái hay tay phải?


85

Tôi đang cố gắng hiểu hệ tọa độ OpenGL. Tuy nhiên, một số hướng dẫn nói rằng hệ tọa độ mặc định là người thuận tay trái (xem http://www.c-sharpcorner.com/UploadFile/jeradus/OpenGLBasics11172005014307AM/OpenGLBasics.aspx ) và những người khác nói rằng nó thuận tay phải (xem tại http: // www .falloutsoftware.com / tutorial / gl / gl0.htm ). Câu nào đúng? Tôi hiểu rằng chúng ta có thể biến đổi cái này sang cái kia bằng cách phản chiếu nhưng tôi muốn biết tọa độ mặc định.



2
Điều này không phụ thuộc hoàn toàn vào cách bạn viết các biến đổi của mình trong shader và do đó hoàn toàn phụ thuộc vào bạn?
jcoder

Chỉ hai xu evl.uic.edu/ralph/508S98/coctures.html của tôi , nó có một vài hình ảnh tự giải thích.
rraallvv

Tôi không cho là bạn đang cân nhắc cập nhật câu trả lời được chấp nhận của mình?
Jonathan Mee

Câu trả lời:


131

Có một số nhầm lẫn ở đây.

nhập mô tả hình ảnh ở đây

OpenGL phù hợp với không gian đối tượng và không gian thế giới.

Nhưng trong không gian cửa sổ (hay còn gọi là không gian màn hình), chúng ta đột nhiên thuận tay trái .

Làm thế nào điều này xảy ra ?

Cách chúng ta chuyển từ tay phải sang tay trái là một mục nhập tỷ lệ z âm trong ma trận glOrthohoặc glFrustumma trận chiếu. Chia tỉ lệ z bằng -1 (trong khi vẫn giữ nguyên x và y) có tác dụng thay đổi độ thuận của hệ tọa độ.

Đối với glFrustum,

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

xagần được cho là tích cực, với xa > gần . Nói xa = 1000 và nói gần = 1. Khi đó C = - (1001) / (999) = -1,002.

Xem tại đây để biết thêm chi tiết và sơ đồ.

Từ góc độ trực quan , glOrtho tạo ra một ma trận như sau:

nhập mô tả hình ảnh ở đây

Ở đây, trái , phải , dướitrên chỉ là tọa độ cho các mặt phẳng cắt ngang trái , dọc phải , ngang dưới , trên cùng (tương ứng) .

Các gầnxa máy bay, tuy nhiên, được quy định khác nhau . Các gần tham số được định nghĩa là

  • Gần: Khoảng cách đến mặt phẳng cắt độ sâu gần hơn. Khoảng cách này là âm nếu máy bay ở phía sau người xem.

và xa:

  • zFar Khoảng cách đến mặt phẳng cắt độ sâu xa hơn. Khoảng cách này là âm nếu máy bay ở phía sau người xem.

Ở đây chúng tôi có một lượng chế độ xem chuẩn điển hình

kinh điển

Vì cấp số nhân của z là (-2 / (xa-gần)), nên dấu trừ sẽ chia z thành -1 . Điều này có nghĩa là "z" được quay sang trái trong quá trình chuyển đổi chế độ xem, hầu hết mọi người không biết vì họ chỉ làm việc trong OpenGL như một hệ tọa độ "thuận tay phải".

Vì vậy, nếu bạn gọi

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

Khi đó KẾ HOẠCH GẦN hơn bạn 10 đơn vị . Bạn ở đâu? Tại sao, tại điểm gốc, với trục x ở bên phải, trục y ở trên đầu và mũi của bạn hướng xuống trục z âm (đó là mặc định "Theo mặc định, máy ảnh được đặt ở điểm gốc , hướng xuống trục z âm và có vectơ hướng lên là (0, 1, 0). " ). Vậy mặt phẳng gần nhất là z = -10. Máy bay xa sau bạn 10 đơn vị, tại z = + 10 .


1
"vectơ chuyển tiếp bị phủ định trong gluLookAt" - bạn có thể xác nhận rằng đây là trường hợp không? Không phải gluPerspective hay glFrustum hay glOrtho?
Kos

1
Chúng ta đột nhiên thuận tay trái từ không gian clip trở đi chứ không chỉ không gian cửa sổ.
Legends2k

3
+1 cho toàn bộ câu trả lời, -1 (chờ, đúng hơn là -2) cho "Cách chúng ta đi từ người thuận tay phải sang người thuận tay trái là do vectơ chuyển tiếp bị phủ định trong việc triển khai tiêu chuẩn của gluLookAt (), là hàm mọi người sử dụng để tạo ma trận chế độ xem. Khi bạn phủ định vectơ chuyển tiếp, điều này có tác dụng thay đổi độ thuận của hệ tọa độ. " , chỉ là rác rưởi ...
Christian Rau

2
... Việc điều chỉnh véc tơ thuận trong gluLookAtphép tính không liên quan gì đến việc thay đổi tính thuận của không gian tọa độ, đó chỉ là cách tính ma trận này (và trên thực tế + z thực sự là "lùi" trong không gian bên phải). gluLookAtkhông làm gì khác hơn là tính toán một chuyển đổi cơ thể cứng nhắc thông thường (xoay + tịnh tiến) trong không gian thuận tay phải. Các ma trận chiếu được sử dụng bởi đường ống hàm cố định (và thường là bởi các trình tạo bóng) thực hiện thay đổi độ thuận tay thực tế trong việc phủ định thành phần z, như bạn đã lưu ý trong câu trả lời của mình.
Christian Rau

2
@bobobobo Câu nói của bạn nếu bạn tính toán ma trận chế độ xem của mình chỉ bằng cách sử dụng các chức năng xoay và dịch (mà tôi đoán bạn sẽ không buộc tội thay đổi độ thuận tay), thay vào đó gluLookAt, sẽ không có sự thay đổi cơ sở gluLookAtnào? Chắc chắn là không (vì bạn có thể biết rằng không phải "mọi người" sử dụng gluLookAtđể tính toán ma trận xem), vì như bạn nên biết, gluLookAtkhông có gì khác hơn là một loạt các lệnh gọi xoay vòng và dịch (thậm chí chúng được ngụy trang dưới dạng thuật ngữ "cấp cao" "thay đổi của cơ sở ” ) hoàn toàn không có phản ánh liên quan.
Christian Rau

26

Theo mặc định, Tọa độ thiết bị chuẩn hóa là người thuận tay trái.

Theo mặc định, glDepthRange là [0, 1] (gần, xa) làm cho trục + z hướng vào màn hình và với + x ở bên phải và + y lên thì nó là hệ thống thuận tay trái.

Thay đổi phạm vi độ sâu thành [1, 0] sẽ làm cho hệ thống thuận tay phải.

Trích dẫn câu trả lời trước đây của Nicol : (cuộc đình công là công việc của tôi, giải thích bên dưới)

Tôi ngạc nhiên là không ai đề cập đến điều gì đó: OpenGL cũng hoạt động trong một hệ tọa độ thuận tay trái. Ít nhất, điều này xảy ra khi bạn đang làm việc với trình đổ bóng và sử dụng phạm vi độ sâu mặc định.

Khi bạn loại bỏ hệ thống chức năng cố định, bạn sẽ xử lý trực tiếp với "clip-space". Đặc tả OpenGL xác định clip-space là một hệ tọa độ đồng nhất 4D. Khi bạn theo dõi các chuyển đổi thông qua tọa độ thiết bị chuẩn hóa và xuống không gian cửa sổ, bạn tìm thấy điều này.

Không gian cửa sổ nằm trong không gian pixel của cửa sổ. Điểm gốc nằm ở góc dưới bên trái, với + Y đi lên và + X đi sang phải. Điều đó nghe rất giống một hệ tọa độ thuận tay phải. Nhưng Z thì sao?

Phạm vi độ sâu mặc định (glDepthRange) đặt giá trị Z gần thành 0 và giá trị Z xa thành một . Vì vậy, dấu + Z sẽ biến mất khỏi người xem.

Đó là hệ tọa độ thuận tay trái. Có, bạn có thểthay đổi kiểm tra độ sâu từ GL_LESS thành GL_GREATER vàthay đổi glDepthRange từ [0, 1] thành [1, 0]. Nhưng trạng thái mặc định của OpenGL là hoạt động trong hệ tọa độ thuận tay trái . Và không có phép biến đổi nào cần thiết để có được không gian cửa sổ từ không gian clip-không gian phủ định Z. Vì vậy, không gian clip-không gian, đầu ra của bộ đổ bóng đỉnh (hoặc hình học) là một không gian bên trái (đại loại là không gian thuần nhất 4D, vì vậy thật khó để xác định độ thuận tay).

Trong đường ống hàm cố định, các ma trận chiếu tiêu chuẩn (được tạo bởi glOrtho, glFrustum và những thứ tương tự) đều chuyển đổi từ không gian thuận tay phải sang không gian thuận tay trái . Họ lật nghĩa của Z; chỉ cần kiểm tra các ma trận mà chúng tạo ra. Trong không gian mắt, + Z di chuyển về phía người xem; trong không gian sau chiếu, nó di chuyển ra xa.

Tôi nghi ngờ rằng Microsoft (và GLide) chỉ đơn giản là không bận tâm thực hiện phủ định trong ma trận chiếu của họ.

Tôi đã thực hiện một phần vì nó khác với những phát hiện của tôi.

Thay đổi DepthRange hoặc DepthFunc và sử dụng ClearDepth (0) đều hoạt động nhưng khi sử dụng cả hai, chúng sẽ loại bỏ nhau để trở lại hệ thống thuận tay trái.


Phạm vi độ sâu không được là [1, -1]. Tôi nghĩ ý bạn là [1, 0]. Ngoài ra, điều này đã được chỉ ra trước đây .
Nicol Bolas

Câu trả lời của bạn rất hay, quá tệ đối với một câu hỏi DirectX, bạn nên đăng lại nó ở đây!
hultqvist

3
@SigTerm bạn nghĩ tại sao việc sửa một tuyên bố sai là không đáng? Tôi đã dành vài giờ khắc phục sự cố tọa độ đỉnh và tạo vòng quay ma trận chỉ để phát hiện ra rằng hệ tọa độ mặc định trên thực tế không thuận tay phải.
hultqvist

1
Câu hỏi đặt ra là đó là hệ thống thuận tay trái hay phải. Câu trả lời này có nhiều chi tiết hơn thế, giải thích hai cách khác để làm cho nó thuận tay, thêm -1 trong phép biến đổi ma trận là một cách khác để thực hiện. Nhưng không có vấn đề gì trong số đó nếu bạn tin rằng hệ thống thuận tay phải theo mặc định, bạn chỉ có thể thay đổi điều gì đó nếu bạn biết mình đang thay đổi từ gì. Tuy nhiên
hultqvist

1
Tôi thấy câu trả lời rất thú vị và nó xuất hiện trong các cuộc tìm kiếm nên nó rất đáng giá đối với tôi.
Tìm hiểu OpenGL ES vào

13

CHỈ NDC

Bạn chỉ nên lưu ý rằng OpenGL chỉ biết NDC! và đó là một hệ tọa độ thuận tay trái.

Bất kể bạn sử dụng hệ tọa độ nào - hệ tọa độ trục thuận tay trái hay tay phải - tất cả đều cần được sao chép sang NDC. Nếu bạn thích, bạn hoàn toàn có thể xử lý không gian thế giới dưới dạng hệ tọa độ thuận tay trái.

Tại sao chúng ta thường sử dụng hệ tọa độ thuận tay phải trong không gian thế giới?

Tôi nghĩ nó là thông thường. Nó chỉ làm. Có lẽ nó chỉ muốn phân biệt với DirectX.


3
Tôi nghĩ điều này không lặp lại đủ. Tất cả các biểu đồ hiển thị "biến đổi mô hình", "biến đổi chế độ xem", "biến đổi phối cảnh" không cho thấy chúng không phải là một phần nội tại của OpenGL. Bạn thậm chí có thể thực hiện tất cả các chuyển đổi của mình theo cách thủ công, có hoặc không có trình đổ bóng, có hoặc không có ma trận.
Tom,

3
Tuy nhiên, nó có thể đẹp hơn nếu lặp lại nó để bao gồm các từ "tọa độ thiết bị chuẩn hóa".
Tommy

6
OpenGL có trước DirectX vài năm, vì vậy OpenGL chắc chắn không cố gắng phân biệt mình với DirectX. Nhà phát triển chính của DirectX, Alex St. John, đã nói rằng quyết định của Microsoft về việc sử dụng hệ thống điều phối thuận tay trái là "một phần vì sở thích cá nhân" và "một sự lựa chọn tùy ý".
Chris Nolet

Đây không phải là hoàn toàn chính xác. OpenGL cũng biết hệ thống tọa độ cắt, vì việc cắt xảy ra trong đó. Hệ tọa độ clip có độ thuận tay giống như hệ tọa độ NDC tho.
plasmacel

7

Cuốn sách "Hướng dẫn lập trình WebGl" của Kouichi Matsuda dành gần mười trang cho "WebGl / OpenGl: Tay trái hay tay phải?"

Theo sách:

  • Trong thực tế, hầu hết mọi người sử dụng hệ thống thuận tay phải

  • OpenGl thực sự là một hệ thống thuận tay trái trong nội bộ

  • Về nội bộ, sâu xa hơn là không. Ở dưới cùng, OpenGl không quan tâm đến giá trị z. Thứ tự mà bạn vẽ các thứ xác định những gì được vẽ trên đầu (vẽ một hình tam giác trước, sau đó là một hình tứ giác, hình tứ giác đè lên hình tam giác).

Tôi không hoàn toàn đồng ý với "nó không phải là" nhưng đó có lẽ là một câu hỏi triết học dù sao.


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). Điều này đúng, trong trường hợp không có thử nghiệm sâu. Khi có kiểm tra độ sâu, giá trị z của một đoạn được so sánh với giá trị trong bộ đệm độ sâu và đoạn bị loại bỏ nếu nó không đạt được kiểm tra độ sâu, vì vậy quad có thể ghi đè lên tam giác tùy thuộc vào độ sâu của chúng và chức năng độ sâu được sử dụng.
chrisvarnz 14/02/18

3

Opengl chắc chắn là người thuận tay trái. Bạn thấy rất nhiều hướng dẫn nói điều ngược lại vì chúng phủ định giá trị z trong ma trận chiếu. Khi các đỉnh cuối cùng được tính toán bên trong bộ đổ bóng đỉnh, nó sẽ chuyển đổi các đỉnh mà bạn truyền từ phía máy khách (coord bên phải) sang phía bên trái và các đỉnh sau đó sẽ được chuyển đến bộ đổ bóng hình học và bộ đổ bóng phân đoạn. Nếu bạn sử dụng hệ tọa độ bên phải ở phía máy khách, Opengl không quan tâm. Nó chỉ biết hệ tọa độ chuẩn hóa, tức là thuận tay trái.

Chỉnh sửa: Nếu bạn không tin tưởng tôi, chỉ cần thử nghiệm trong bộ đổ bóng đỉnh của bạn bằng cách thêm ma trận dịch và bạn có thể dễ dàng xem Opengl có thuận tay trái hay không.


0

Bằng cách sử dụng các chức năng chiếu và biến đổi tích hợp của OpenGL, việc quan sát các chuyển động trên màn hình tuân theo các quy tắc của hệ tọa độ thuận tay phải . Ví dụ: nếu một đối tượng ở phía trước chế độ xem của bạn được dịch theo hướng z dương, thì đối tượng sẽ di chuyển về phía bạn.

Vùng đệm độ sâu hoàn toàn ngược lại và đây là lúc NDC (Tọa độ thiết bị chuẩn hóa) phát huy tác dụng. Nếu truyền GL_LESS vào glDepthFunc có nghĩa là các pixel sẽ vẽ khi chúng ở gần bạn hơn những gì đã có trong bộ đệm độ sâu, thì pixel được coi là sống trong một hệ tọa độ bên trái .

Còn một hệ tọa độ nữa, và đó là khung nhìn! Hệ tọa độ của khung nhìn sao cho + x hướng sang phải và + y hướng xuống dưới. Tôi nghĩ rằng đến thời điểm này, sự thuận lợi là rất quan trọng vì chúng ta chỉ giải quyết x, y tại thời điểm này.

Cuối cùng, gluLookAt dưới mui xe phải phủ định vector nhìn. Vì toán học giả định một vectơ hướng theo hướng dương về phía đối tượng mà nó đang nhìn và máy ảnh nhìn xuống -z, vectơ nhìn phải được phủ định để nó thẳng hàng với máy ảnh.

Một cái gì đó để nhai. Không có ý nghĩa gì khi gọi hướng z của một hệ tọa độ thuận tay phải là một vectơ thuận :). Tôi nghĩ rằng Microsoft đã nhận ra điều này khi họ thiết kế Direct3D.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.