詳解OpenGL中的各種變換(投影變換,模型變換,視圖變換)(一)——模型變換和視圖變換


  本文一些用於均參考《OpenGL編程指南(第8版)》,有興趣的同學可以結合一起看。這篇算是整合補充。

  OpenGL采用的是相機模型,就是把視圖變換操作類比為使用照相機拍攝照片的過程,具體步驟如下(這里和紅寶書有一些改變):

  1. 將准備拍攝的對象移動到場景中指定位置。(模型變換,Model Transform)
  2. 將相機移動到准備拍攝的位置,將它對准某個方向。(視圖變換,View Transform)
  3. 設置相機的焦距,或者調整縮放比例。(投影變換,Projection Transform)
  4. 拍攝照片並變換到需要的圖片大小。(這個是視口變換,我們這里不做討論)

  在這四個步驟中,前三個都是可以用變換矩陣實現的。看完本文之后基本就可以用自己寫的矩陣來代替OpenGL里面的各種變換操作了。至於為什么要按照上述的順序可以參考下面代碼,有興趣的讀者可以調換一下位置試一試,其中投影變換矩陣一定要放在最左邊。

/*Project:投影變換矩陣
    View:視圖變換矩陣
    Model:模型變換矩陣*/
ModelViewProject = Project * View * Model;

 


  下面需要知道一些矩陣和齊次坐標的相關知識,網上有很多資料,如果又不知道的可以提前了解下。

  這里有必要深入講解一下齊次坐標的意義。假設一3維向量x,我們對這個向量進行線性變換Tx,但無論T為任意3*3矩陣,都無法完成向量的平移操作(比如x=(0,0,0)Tx無論如何也不可能變換到(1,0,0))。這里我們就需要用到齊次坐標,使用齊次坐標的目的也就是通過增加額外的數值來完成向量的平移操作。熟悉OpenGL的已經知道了,將三維數據植入思維坐標空間當中就行了。就是將x=(0,0,0)轉變成x=(0,0,0,1)。T也轉變成4*4矩陣。

  我們再討論一下齊次坐標的一個性質, 齊次坐標所表達的其實是方向而不是位置。比如x1=(1,2,3,1)x2=(2,4,6,2)其實在3維坐標系中表示的是同一個位置。此外,最后一個分量w越大,那么齊次坐標將處於更遠的位置。當OpenGL准備顯示集合體的時候,它會使用左后一個分量除以前三個分量,從而將其次坐標重新變換到3維坐標系中,因此w越大的物體也會顯示的越小。w0.0的時候,由於坐標位於無限近的位置,以至於顯示可能會呈現出無限大。這個概念非常重要,因為下面投影矩陣就是利用這個概念!

  我們接下來說明三個變換中具體包含哪些矩陣。對於一個頂點來說,我們對其先進行模型變換,在進行視圖變換和投影變換。我們將這些變換細分一下就可以得到如下代碼:

/*S:縮放 R:旋轉 T:平移*/
ModelViewProject = Project 
          * ViewR * ViewT 
          * ModelS * ModelR * ModelT
gl_position = ModelViewProject * Vertex;

  


   下面我就按照順序逐一介紹一下各個矩陣,先介紹一下模型變換矩陣,這部分我就不細說了,了解的人應該不少。

  (1)ModelT 平移矩陣

  這個矩陣算是最簡單的矩陣,這里舉個例子。假設我們要將v=(x,y,z)沿x軸正方向平移2.5,具體計算如下:

圖1

  (2)ModelR 旋轉矩陣

  這個矩陣就比較多樣了,我以前的博客關於這個矩陣有不少分析,這里也不多說了。下面列出三個歐拉角對應的旋轉矩陣(也是最常用的):

圖2

  (3)ModelS 縮放矩陣

  這個矩陣也比較簡單,只要把縮放因子factor放在矩陣的對角線上就行了。具體表達如下:

圖3

  這三個矩陣就組成了模型變換矩陣,根據具體需求可以隨意組合平移旋轉縮放矩陣,並不一定非要按照上面代碼中的順序。

 


  下面介紹視圖矩陣,我們可以把這一步假想為設置相機或者人眼(View)的位置。設置相機一般只需要兩步,首先把相機移動到固定的位置,然后把當前坐標系轉化成相機坐標系。這里不像模型變換,可以多次旋轉平移,這里只需要1個平移操作和1個旋轉操作一般就可以了,而且還不需要縮放。

  (1)ViewT 平移矩陣

  這個矩陣和ModelT正好是相反的。我們可以這樣理解,如果要在世界坐標系下的(x,y,z)位置設置相機,那么我們把相機再移回世界坐標系原點的位移就是(-x,-y,-z)。所以我們當以相機為坐標原點的時候,所有在原來坐標系下的物體都要加上這個負的平移分量。那么這個平移矩陣如下:

圖4

  (2)ViewR 旋轉矩陣

  我們將原來的坐標系轉變成相機坐標系,不僅需要平移到相機位置,還要旋轉到相機的朝向。如圖5所示,我們要將藍色的坐標系通過旋轉變換成紅色的相機坐標系。由於坐標系的三個基向量都是單位化的,所以最簡單的辦法就是點乘。做法是點乘相機坐標系的三個基向量,具體看圖6的公式。


圖5

圖6

 

  其中V指向相機坐標系的y軸,U指向相機坐標系的x軸,N指向相機坐標系的z軸。

  這兩個矩陣就組成了視圖變換矩陣,View乘以Model得到的矩陣,在OpenGL固定管線中稱為模型視圖矩陣,可以通過glMatrixMode(GL_MODELVIEW)進行設置。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM