創建場景中的三維模型往往需要設置顯示大小、位置、角度,three.js提供了一系列網格模型對象的幾何變換方法,從WebGL的角度看,旋轉、縮放、平移對應的都是模型變換矩陣,關於矩陣變換內容可以觀看本人博客發布的原生WebGL課程。
網格模型對象的旋轉、縮放、平移等方法或屬性可以查找three.js文檔的Object3D對象,該對象是網格模型對象、點模型對象、線條模型對象的基類。
縮放
立方體網格模型x軸方向放大2倍,如果連續執行兩次該語句,相等於比原來方法4倍
mesh.scale.x = 2.0;//x軸方向放大2倍
立方體網格模型整體縮小0.5倍,相當於xyz三個方向分別縮小0.5倍
mesh.scale.set(0.5,0.5,0.5);//縮小為原來0.5倍
網格模型Mesh的屬性scale返回值是一個Vector3對象,查看three.js官方文檔你可以知道Vector3對象具有屬性x、y、z對於上面的代碼而言xyz表示坐標值,xyz數據類型是float,Vector3對象還具有方法set(),set方法有三個表示xyz坐標的參數。
平移
立方體網格模型沿着x軸正方向平移100,可以多次執行該語句,每次執行都是相對上一次的位置進行平移變換
mesh.translateX(100);//沿着x軸正方向平移距離100
網格模型沿着向量(0,1,0)表示的方向平移100
var axis = new THREE.Vector3(0,1,0);//向量axis mesh.translateOnAxis(axis,100);//沿着axis軸表示方向平移100
translateOnAxis(axis, distance)方法相比.translateX、.translateY、.translateZ更通用,可以實現立方體沿着任何方向旋平移,參數axis表示平移方向,使用對象Vector3表示
旋轉
立方體網格模型繞立方體的x軸旋轉π/4,可以多次執行該語句,每次執行都是相對上一次的角度進行旋轉變化
mesh.rotateX(Math.PI/4);//繞x軸旋轉π/4
網格模型繞(0,1,0)向量表示的軸旋轉π/8
var axis = new THREE.Vector3(0,1,0);//向量axis mesh.rotateOnAxis(axis,Math.PI/8);//繞axis軸旋轉π/8
rotateOnAxis(axis, angle)方法相比.rotateX、.rotateY、.rotateZ更通用,可以實現立方體繞任何軸旋轉,參數axis表示旋轉軸,使用對象Vector3表示
位置屬性position
立方體網格模型位置坐標(80,2,10)
mesh.position.y = 80;//設置網格模型幾何中心y坐標
立方體網格模型幾何中心y軸坐標值80
mesh.position.set(80,2,10);//設置網格模型幾何中心三維坐標
position屬性和平移方法translateX()一樣都是設置距離,方法translateX()設置的相對上次位置進行平移,兩次執行該方法,距離會疊加,position屬性設置的距離是相對坐標系原點位置, 兩次執行position屬性立方體的會只會更新重新定位,兩次的距離參數不是疊加關系,而是替換關系。
角度屬性rotation
立方體網格模型位置坐標(80,2,10)
mesh.position.y = 80;//設置網格模型幾何中心y坐標
立方體網格模型幾何中心y軸坐標值80
mesh.position.set(80,2,10);//設置網格模型幾何中心三維坐標
rotation屬性和旋轉方法rotateX()差異類似position屬性和平移方法translateX()的差異,一個是相對坐標系設置角度、位置,一個是相對當前的三維模型的狀態設置角度、位置參數。 旋轉與平移參考的都是坐標系,不過參考的坐標系稍有不同,平移參考的是世界坐標系或者說三維場景對象Scene的坐標系,和相機對象一樣,在整個三維場景中的位置, 三維模型的旋轉參考的是模型坐標系,也就是對三維模型本身建立的坐標系。
基類Object3D
點模型Points
、線模型Line
、精靈模型sprite
、組對象Group
等threejs模型對象的基類都是Object3D
,這些模型對象的角度、位置、縮放屬性和旋轉、平移、縮放方法都可以查看threejs文檔基類Object3D
幾何體變換
幾何體Geometry
和網格模型Mesh
一樣也就有旋轉縮放平移等方法,通過網格模型或幾何體的方法都可以對模型進行變換,但是本質是不一樣的,網格模型Mesh
執行旋轉平移縮放變化,並不會改變自身綁定幾何體的頂點坐標,會改變模型對應的模型矩陣ModelMatrix
,幾何體執行旋轉縮放平移變換會改變幾何體本身包含的頂點位置、法向量等數據。
如果對上面闡述不太理解,建議最好看看本人博客發布的threejs課程中第二章關於幾何體頂點的介紹,threejs進階課程中關於模型矩陣等概念的介紹。
下面的程序是通過一個幾何體創建了多個網格模型,網格模型可以共享幾何體對象和材質對象都,幾何體對象本質上是一組頂點相關數據,每創建一個網格模型, 相當於多次利用顯存中的同一組定點相關數據渲染出多個三維模型的效果,幾何體頂點雖然是同一組數據,但是可以在GPU着色器中對這組數據進行矩陣變換,來呈現出不同的效果。
/** * 創建網格模型1、網格模型2 */ var box=new THREE.BoxGeometry(50,50,50);//創建一個立方體幾何對象 var material=new THREE.MeshLambertMaterial({color:0x0000ff});//材質對象 var mesh1=new THREE.Mesh(box,material);//網格模型對象1 var mesh2=new THREE.Mesh(box,material);//網格模型對象2 mesh1.translateX(-50);//沿着x軸負方向平移距離50 mesh2.translateX(50);//沿着x軸正方向平移距離50 scene.add(mesh1);//網格模型1添加到場景中 scene.add(mesh2);//網格模型2添加到場景中
代碼中的網格模型mesh1、網格模型mesh2都是通過同一個幾何體對象Geometry創建,默認情況下,幾何體對象的頂點位置決定了網格模型在場景中的顯示位置, 兩個網格模型執行方法translateX()進行平移變換錯開顯示。網格模型的平移變換方法translateX()會通過three.js引擎轉化為WebGL中CPU頂點着色器的矩陣變換程序。
更改上面的程序,插入下面一段代碼,放大其中一個網格模型,可以看到另外外一個網格模型的顯示大小並不受影響。
mesh2.scale.y = 2.0;//y軸方向放大2倍
網格模型對象可以進行縮放平移旋轉變換,幾何體對象也擁有相關的幾何變換方法和屬性,幾何體進行幾何變換,本質上更改的是顯存中的頂點相關數據, 網格模型進行幾何變換,不會更改顯存中的頂點數據,頂點數據的變換是在GPU渲染管線的頂點着色器處理單元中借助程序逐頂點執行矩陣乘法運算。
幾何體對象執行方法scale(),尺寸縮小為原來的0.5倍,刷新瀏覽器你會看到兩個網格模型代表的立方體都縮小了,對比上面的程序可以看出更改幾何體的參數,與之相關的網格模型都會變化。 這很好理解,網格模型的幾何變換更改的是要與頂點數據進行乘法運算的模型矩陣,幾何體對象進行變換更累刷新的是顯存上的頂點相關數據,每次渲染出一個網格模型, 都會從網格模型構造函數指定的頂點對象獲取頂點數據。
var box=new THREE.BoxGeometry(50,50,50);//創建一個立方體幾何對象 box.scale(0.5,0.5,0.5);//幾何體縮小為原來0.5倍
幾何體對象可以進行上面程序中的縮放變換,自然也有平移、縮放變換的相關方法,具體使用方法可以參考three.js文檔的Geometry對象,立方體、球體等幾何體的構造函數返回的結果都是Geometry對象, 這些構造函數返回的對象都會繼承Geometry對象的屬性和方法。