投影方式- Unity3D遊戲開發培訓

來源:互聯網
上載者:User

標籤:螢幕   end   構造   dem   ogr   round   角度   部分   釋放   

投影方式- Unity3D遊戲開發培訓

 

鄧家海

2018-02-12 20:33:13

 

摘  要 

透視投影是3D渲染的基本概念,也是3D程式設計的基礎。掌握透視投影的原理對於深入理解其他3D渲染管線具有重要作用。本文詳細介紹了透視投影的原理和演算法實現,包括透視投影的標準模型、一般模型和螢幕座標變換等,並通過VC實現了一個示範程式。

在Unity3D裡面,投影方式決定了我們人眼看到的情境,投影方式一般分為透視投影和正交投影兩種,透視投影相當於我們人的眼睛看到的東西。越遠越小,越近越大。還會出現一個倒影。在物理學上面的小孔成像就是透視投影。正交投影是平行光源的投射,物體不會隨著距離的改變而改變。在電腦三維映像裡面,投影是可以看作是一種將三維座標變成二維座標的方法。

相機設定

透視投影:與人的視覺系統相似,多用在三維平面中對三維世界的呈現。模型是由視點E和視平面P兩部分構成(要求E不在平面P上),視點就是觀察者的位置,也就是三維世界的角度,視平面就是渲染3D 物件的二維平面圖,對於任意一點X,構造一條從E到X的射線R,R與平面P的交點X,p即是X點的透視投影結果。:

 

 

 

圖 1-1

 

 

圖 1-2

 

正交投影:用於二維世界的呈現。

 

 

 

 

 圖 1-3

 

無論遠近,大小是一樣的

 

 

3D預設是透視投影(Perspective),2D預設是正交投影(Orthographic)。

 

透視投影的實現

6.1 載入3D模型

使用Matt Fairfax實現的Model_3DS類支援3DS模型檔案的載入,該類的實現非常簡單,而且很容易使用,具體可參考[7]。由於本文的DEMO只需要其中的模型載入功能,所以對原始碼進行了刪減,去掉了紋理載入(暫不需要)和渲染(我們自己實現)代碼,在解構函式中添加了資源釋放代碼。

6.2 視圖變換

為表示透視投影的一般模型,實現了KCamera類,除儲存視點的位置和姿態,還儲存視圖變換矩陣m_kmView,隨著視點位置和姿態的變化,視圖矩陣也不斷更新,更新演算法詳見第4節。對於全局座標系中的任何一點v(x, y, z),通過v = m_kmView*v將其變換到透視投影的標準模型座標系,詳見KCamera::Transform函數。

6.3 透視變換

KFrustum類用來對透視投影的標準模型進行建模,其成員包括視平面的尺寸大小,以及近截面和遠截面的z軸座標。KFrustum通過Project函數將視圖變換的結果變換為透視座標。演算法的原理見第3節,代碼實現如下:

 

 1 void KFrustum::Project(KVector3& v) 2  3 { 4  5     // xp = x*n/z, yp = y*n/z, zp = n. 6  7     float fFactor = GetNear()/v.z; 8  9     v.x *= fFactor;10 11     v.y *= fFactor;12 13     v.z = GetNear();14 15 }

 

 

6.4 螢幕變換

螢幕變換的演算法通過宏實現,代碼如下:

 

 1 #define ToScreen(v, Ws, Hs) / 2  3 {/ 4  5     float x = (v.x/GetWidth()+0.5f)*(Ws-1);/ 6  7     float y = (v.y/GetHeight()+0.5f)*(Hs-1);/ 8  9     v.x = KMath::Round(x);/10 11     v.y = KMath::Round(y);/12 13 }

 

 

6.5 渲染

Demo中的渲染使用軟體實現,沒有使用任何第三方圖形庫,主代碼在KCamera::Render函數中,它接收兩次參數:Model_3DS和KSurface,對Model_3DS中的頂點進行透視投影,然後將結果繪製到Ksurface中。函數代碼如下:

 

 1 bool KCamera::Render(Model_3DS& m3DS, KSurface& kSurface) 2  3 { 4  5     kSurface.Fill(RGB(0,0,0)); // 背景為黑色 6  7     COLORREF crPen = RGB(255,0,0); // 用紅色繪製模型 8  9    10 11     KMatrix4 m = m_kmView;12 13     int Ws = kSurface.GetWidth();14 15     int Hs = kSurface.GetHeight();16 17  18 19     for(int i=0; i<m3DS.numObjects; i++)20 21     {22 23         Model_3DS::Object& obj = m3DS.Objects[i];24 25  26 27         for(int n=0; n<obj.numFaces; n+=3)28 29         {30 31             int index = obj.Faces[n]*3;32 33             KVector4 v0(obj.Vertexes[index], obj.Vertexes[index+1], obj.Vertexes[index+2]);34 35             index = obj.Faces[n+1]*3;36 37             KVector4 v1(obj.Vertexes[index], obj.Vertexes[index+1], obj.Vertexes[index+2]);38 39             index = obj.Faces[n+2]*3;40 41             KVector4 v2(obj.Vertexes[index], obj.Vertexes[index+1], obj.Vertexes[index+2]);42 43  44 45             Transform(v0, Ws, Hs);46 47             Transform(v1, Ws, Hs);48 49             Transform(v2, Ws, Hs);50 51  52 53             // 繪製網線54 55             kSurface.MoveTo(v0.x, v0.y);56 57             kSurface.LineTo(v1.x, v1.y, crPen);58 59             kSurface.LineTo(v2.x, v2.y, crPen);60 61             kSurface.LineTo(v0.x, v0.y, crPen);62 63         }64 65     }66 67  68 69     return true;70 71 }

 

投影方式- Unity3D遊戲開發培訓

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.