統一D3D與OpenGL座標系統

來源:互聯網
上載者:User

標籤:d3d   opengl   跨平台   

遊藍海(http://blog.csdn.net/you_lan_hai)


        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投影矩陣。

void Matrix::perspectiveProjectionLH2( float fov, float aspectRatio,        float nearPlane, float farPlane ){        float h = (1.0f / tanf(fov * 0.5f));        float w = h / aspectRatio;        float a = (farPlane + nearPlane) / (farPlane - nearPlane);        float b = -2.0f * farPlane * nearPlane / (farPlane - nearPlane);                m[0][0] = w; m[0][1] = 0; m[0][2] = 0; m[0][3] = 0;        m[1][0] = 0; m[1][1] = h; m[1][2] = 0; m[1][3] = 0;        m[2][0] = 0; m[2][1] = 0; m[2][2] = a; m[2][3] = 1;        m[3][0] = 0; m[3][1] = 0; m[3][2] = b; m[3][3] = 0;}


4.總結

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

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

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

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

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

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


5.更多閱讀

推導投影矩陣 http://blog.csdn.net/popy007/article/details/4091967

跨越opengl和d3d的鴻溝 http://www.cppblog.com/topjackhjj/articles/157038.html


統一D3D與OpenGL座標系統

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.