統一D3D與OpenGL座標系統

2021-06-26 20:45:49 字數 1995 閱讀 8887

directx 3d與opengl座標系統的差異性,給我們帶來很大的麻煩,讓跨平台程式設計的新手很困惑。最近在做乙個跨平台的遊戲,仔細看了下兩者的矩陣,發現並沒有什麼大區別,將d3d左手系的矩陣傳遞給opengl shader完全可以正常工作。

先說一下兩者一些概念上的區別:

(1)座標系統不同

d3d左手座標系,opengl右手座標系

(2)矩陣行序不同

d3d行優先,opengl列優先。這兩個不同,直接導致了座標變換順序與矩陣乘法順序的相反性。如果是先縮放,再旋轉,最後平移,對應的矩陣分別為s、r、t,則d3d的最終矩陣為m = s * r * t,opengl為m = t * r * s

(3)裁減空間z取值範圍不同

d3d是[0, 1],opengl是[-1, 1]

表面上來看,兩者矩陣差別很大,但其實不然。

1.左右手座標系

對於顯示卡裝置來說,

裝置座標系是左手座標系

,即z軸指向螢幕裡面,z值越大表示距離視線越遠。因此,opengl的右手系,在進入裁減空間的時候,會轉換成左手系。這也就是說,在渲染管線內部,座標系是統一的。不管是左手座標系矩陣,還是右手座標系矩陣,只要變換到裁減空間中的點是左手系就可以了。

2.矩陣行序

行矩陣和列矩陣,在邏輯上乙個是另乙個的轉置,但在物理存貯結構上卻是完全一致的。如乙個平移變換(x, y, z):

需要注意的是,矩陣乘法並不關心矩陣是行矩陣還是列矩陣,都是按照第乙個矩陣的行去乘以第二個矩陣的列。對於列矩陣而言,這正是其蹩腳的地方,為了保證乘法意義的有效性,其座標變換順序跟矩陣乘法順序恰好相反。

還要注意一點,在shader中,opengl的矩陣乘法規則跟d3d是不同的。按照矩陣乘法規則(第乙個矩陣行*第二個矩陣列):

d3d矩陣乘法:      ma(0 1 2 3) * mb(0 4 8 12)

opengl矩陣乘法: ma(0 4 8 12) * mb(0 1 2 3)

因此,對於opengl shader而言,變換順序跟矩陣乘法順序依然是反的。如果我們能將傳入opengl shader的矩陣做一次轉置,那麼opengl shader的矩陣乘法意義將跟d3d shader完全一致!

3.修改投影矩陣

由於opengl的裁減空間z取值範圍為[-1, 1]跟d3d的[0, 1]不同,我們不能簡單的使用d3d投影矩陣,必須重新定義d3d投影矩陣。

[cpp]view plain

copy

print

?void matrix::perspectiveprojectionlh2( float fov, float aspectratio, 

float nearplane, float farplane )   

void matrix::perspectiveprojectionlh2( float fov, float aspectratio,

float nearplane, float farplane )

4.總結使用左手系變換來統一兩個平台是比較方便的。總結一下修改opengl渲染管線的步驟:

(1)在c++層統一使用左手座標系變換;

(2)修改投影矩陣,以適應裁減空間z座標範圍[-1, 1];

(3)矩陣在傳入shader的時候,將矩陣的轉置矩陣傳入;

(4)在shader層,統一使用左手座標系變換。

如果,不想修改shader中的變換,只用做到(1)和(2)就夠了。

推導投影矩陣

跨越opengl和d3d的鴻溝

統一D3D與OpenGL座標系統

2014年07月20日 16 23 03 directx 3d與opengl座標系統的差異性,給我們帶來很大的麻煩,讓跨平台程式設計的新手很困惑。最近在做乙個跨平台的遊戲,仔細看了下兩者的矩陣,發現並沒有什麼大區別,將d3d左手系的矩陣傳遞給opengl shader完全可以正常工作。先說一下兩者一...

OpenGL和D3D的區別

1 世界座標系 opengl為右手座標系d3d為左手座標系 2 裁剪空間 opengl中z的範圍 1.0,1.0 d3d為 0.0,1.0 3 shader shader開始是以彙編的形式出現,在推出一段時間後,就出現如下幾種類c的高階語言 注 這些高階語言會被編譯成顯示卡識別的彙編 opengl的...

D3D世界座標變換到螢幕座標

d3d中世界座標變換到螢幕座標,可用於繪製座標軸文字.code d3d世界座標轉螢幕座標 private function vector2point x as single,y as single,z as single as point 是有順序的,先世界 在檢視 在投影 dim vectorop...