正交投影變換與透視投影
相機投影模型
三維計算機圖形學的基本問題之一就是三維觀察問題:即如何把三維場景投影到要顯示的二維影象。大多數經典的解決投影變換方法有兩種:正交投影變換和透視投影變化。
正交投影變換用一個長方體來取景,並把場景投影到這個長方體的前面。這個投影不會有透視收縮效果(遠些的物體在影象平面上要小一些),因為它保證平行線在變換後仍然保持平行,也就使得物體之間的相對距離在變換後保持不變。簡單的說, 正交投影變換忽略物體遠近時的大小縮放變化,將物體以原比例投影到截面(如顯示螢幕)上,實現這樣效果的照相機叫做正交投影照相機,也稱正交照相機。
透視投影變換跟正交投影一樣,也是把一個空間體(指的是以投影中心為頂點的透視四稜錐)投影到一個二維影象平面上。然而,它卻有透視收縮效果:遠些的物體在影象平面上的投影比近處相同大小的物體的投影要小一些。跟正交投影不同的是,透視投影並不保持距離和角度的相對大小不變,所以平行線的投影並不一定是平行的了。換言之,透視投影變換能夠實現一個物體在玩家近距離比較大,遠距離比較小,那麼實現這樣的效果的照相機就叫做遠景照相機。遠景照相機常用來開發3D遊戲,它的工作原理是通過,根據照相機和物體之間的距離縮放投影的比例(也就是截面的大小)。透視投影跟人的眼睛或相機鏡頭產生三維世界的影象的原理還是很接近的。下面我們講解下視椎,如下圖:
圖中,眼睛所在的位置就是camera所在的位置,viewport就是圖中,所有截面的標記區域,顯示螢幕也是一個viewport的截面。視錐是一個類似於金字塔形狀,它有兩個切割面。物體或物體的某些部分外如果被遮擋,就不會被渲染,這就是透視照相機的工作原理。
ThreeJs中的相機類
在ThreeJS中一共有三個關於相機的JS檔案,Camera.js、OrthographicCamera.js、PerspectiveCamera.js,分別是抽象相機基類、正交投影相機、透視相機(遠景相機)。抽象相機基類Camera是一個使用投影矩陣的相機類,並以此為基礎定義兩個相機模型。OrthographicCamera實現了正交投影,PerspectiveCamera實現了透視投影,這兩個投影模型都很經典並且應用廣泛。
抽象相機基類
攝像機的抽象基類。當你建立一個新的自定義相機時應該始終繼承這個基類。
Camera是預設定義是在3D空間中的,其初始位置也是根據3D空間的位置定義的。他的座標系由指向特定方位的單位向量組成,即3D座標系單位向量。想象一個3D的座標系,也就是我們高中時候常常使用的立體幾何中的座標系,Camera也是這樣的,3D的照相機都是在立體的三維座標系中建立的。通過 Direction Vector(方向向量)能夠讓我們告訴WebGL,如何設定Camera的方位,而 position vector(位置向量)則定義了Camera 在3D世界中的位置。
在3D照相機中另個一重要的屬性就是 View Frustum(視錐)。在上面的圖片中,可以看到一個椎體在視點(圖中眼睛的位置)被截去了頂端,這個就是視椎。所有在這個 Frustum(截頭錐體)裡面的東西都會被顯示在螢幕上。這個截頭錐體切分出來的被6個切面(clipping planes),分別在ThreeJs中分別命名為:near, far, left, right, top and bottom。在上面的圖片中的所看到截頭錐體只是整個椎體的一側。對於近切面它有一個特殊的作用:你可以把它想象成一個取景器取到的圖畫的表面,這樣我們就可以把3D空間轉換為2D平面,展示在玩家面前,這個過程在ThreeJs中稱為 Projection (投影)。實現這些特定的效果,我們就需要改變照相機的和屬性,其實就是改變視錐的屬性。
正交/投影相機
正交投影相機的基礎是正交投影矩陣。
第三人稱攝像機perspectiveCamera
第三人稱相機是繼承了抽象相機基類而建立的一種特殊相機,第三視角相機的目標是當物體移動時跟隨它並保持一定的距離。如果物體移動到攝像機邊界後,將造成攝像機劇烈移動。讓攝像機跟隨一個物體,如玩家控制角色,你需要定義一下如下引數:
1、跟隨位置,攝像機跟隨的目標物體的位置
2、跟隨的方向,攝像機沿哪個方向移動來跟隨物體
3、跟隨速度
4、跟隨距離,攝像機與物體的距離