文章出處

Camera定義

 

游戲中,Camera用來向用戶展示場景,Camera就像一個攝像機,攝像機里面的景象就是Camera的展示范圍,如下圖所示:



在3D空間中Camera被定義為一個位置,有一個單位“方向”向量和一個“向上”的單位向量組成,方向和向上向量告訴OpenGL 當前Camera如何定向。

 

視景體

      Camera的另一個重要特性是視覺平截體(View Frustrum),在上面的圖片中可以看到一個被砍去頂尖的角錐體,這就是一個視覺平截體,所以視覺平截體內部的東西都可以在屏幕上看到,視覺平截體被六個剖面確定,near、far、left、right、top、bottom。near剖面還有一個特殊的性質:你可以認為它是相機照出的照片中的平面。這個由3D轉換為2D的過程,稱為投影,通常有兩種投影:orthographic projection(正交投影) 和 perspective projection(透視投影、中心投影),正交投影在2D的圖形中經常使用,無論物體離camera遠近,物體在屏幕上的大小始終一樣。透視投影是現實世界中的成像原理:物體離眼睛越遠,物體的就越小。不同的投射類型就是改變視景體的形狀,透視投影的視覺平截體形狀就是上圖的角錐體形狀,正交投影的視覺平截體是一個長方體,投影的過程簡單來說:對于物體上的每一個點,計算這個點到camera之間的連線是否與near剖面相交。下圖是正交投影與透視投影的圖片示例:



 由此可以看出為什么在透視投影下,屏幕上越遠的物體會越小,而正交投影下,物體保持大小不變。OpenGL一般使用3D空間展示,無論你是繪圖還是輸出字符串,當你使用正交投影時,可以假設z軸不存在,下圖就是一個2D精靈在3D空間中的樣子:


 

因此,在這里可以忽略2D和3D的不同之處,下圖是一個在未設置任何矩陣(matrix)下使用SpriteBatch繪圖的正交視景體


我們所做的就是讓我們的精靈在x/y平面上移動,忽略z軸,保持我們一直工作在2D空間的假象

 

透視投影使用兩個屬性來定義它的投影規則:廣角和縱橫比(長寬比),廣角是一個角度值,用來定義視場有多大”開口“,如下圖




縱橫比是視口的寬度和高度比。視口是一個長方形,即camera用來進行渲染圖像的地方,一個480*320像素的窗口,它的縱橫比是480/320。

 

Camera相關類

Camera:基礎類

OrthographicCamera:正交Camera 繼承自Camera

PerspectiveCamera:投影Camera繼承在Camera

 

首先看Camera類

 

Java代碼  收藏代碼
  1. public abstract class Camera {                
  2.     public final Vector3 position = new Vector3();  
  3.     public final Vector3 direction = new Vector3(0, 0, -1);   
  4.     public final Vector3 up = new Vector3(0, 1, 0);  

三個公共成員分別是Camera的位置、方向、up向量 ,采用的是默認屬性,因此camera默認位于原點,z軸默認朝上。

Java代碼  收藏代碼
  1. public final Matrix4 projection = new Matrix4();  
  2. public final Matrix4 view = new Matrix4();  
  3. public final Matrix4 combined = new Matrix4();  
  4. public final Matrix4 invProjectionView = new Matrix4();  

這是一系列的在OpenGL ES 2.0中用到的矩陣,前兩個是投影和模型視圖矩陣,第三個是前兩個的結合,第四個是第三個的翻轉,經常用來做提取登時,這些都不會經常使用到

 

Java代碼  收藏代碼
  1. public float near = 1;    
  2. public float far = 100;   
  3. public float viewportWidth = 0;  
  4. public float viewportHeight = 0;  

這是near和far剖面距離camera的距離,以及視口的寬度和高度,near和far必須遵循0<=near<far的公式。默認情況情況下near剖面距離camera是1個單位,對于正交投影,near經常設置為0,width和height用來計算透視投影的縱橫比或者正交投影的視景體長方體

 

Java代碼  收藏代碼
  1. public final Frustum frustum = new Frustum();  

最后的成員是Frustum,有6個平面組成,Frustum可以用來進行裁剪:檢測一個物體是否在Frustum內,如果不在則不繪制它。Frustum有一些的方法用來檢測一個 盒子、球體或者一個點是否在Frustum中。

 

Java代碼  收藏代碼
  1. public abstract void update();  
  2. public void apply(GL10 gl);  

 這是兩個常用方法,update方法用來重新計算camera的舉證,當camera的屬性發生改變時進行調用。apply方法用來設置camera的GL_PROJECTION或者GL_MODELVIEW矩陣,不過這個方法在OpenGL ES 2.0上不可用。

Java代碼  收藏代碼
  1. public void unproject(Vector3 vec);   
  2. public void project(Vector3 vec);  
  3. public Ray getPickRay(float x, float y);  

      最后是幾個你可能用到額高級方法。unproject方法用來從屏幕坐標中取得一個點,并產生這個點的三位坐標。與原有類的OrthographicCamera.screenToWorld()左右相同,也等同于gluUnproject方法。x、y坐標是可觸坐標,參數中的z坐標是個0和1之間的值,0表示點位于near平面,1表示點位于far平面;

    project方法正好相反,從3D世界中取得一個點,并轉換成屏幕上的2d點;

    getPickRay方法會返回一個直線,可以想象成3D世界中,從camera位置到x、y的一條直線,用來檢測這個直線是否與其他圖形或者物體接觸到。

 

Java代碼  收藏代碼
  1. public class OrthographicCamera extends Camera {  
  2.     public float zoom = 1;  
  3.    
  4.     public OrthographicCamera(float viewportWidth, float viewportHeight);  

 

OrthographicCamera有一個額外成員zoom用來定義縮放因子。構造參數定義了camera的視口width和高度,如果想要最佳的利用機器像素,只需要在這里定義GRaphics.getWidth()/getHeight(),也可以使用不同的單位,比如厘米。

 

 

Java代碼  收藏代碼
  1. public class PerspectiveCamera extends Camera {       
  2.     public float fieldOfView = 67;  
  3.    
  4.     public PerspectiveCamera(float fieldOfView, float viewportWidth, float viewportHeight);  

 

 PerspectiveCamera 也有一個額外的成員,廣角。

 

文章翻譯完,對Camera的理解又進了一層。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()