github地址html
如今咱們對three.js的基本元素與如何用three.js搭建場景有了必定的瞭解後,本篇咱們開始搭建村落中山坡,房屋等對象。git
ps:若是沒看過第一篇的請移步這裏github
從圖中能夠看出山坡mesh的geometry在three.js中並未直接提供,demo的思路是由基本幾何體BoxGeometry變形而來。
這裏說明一下,three.js構建的圖形都有點(vertex),線(edge),面(face)三個屬性:app
如圖所示移動box中對應點,可將box變造成最終所需的geometry:
函數
var geom = new THREE.BoxGeometry(basicWidth, groundDeep, basicHeight, 4, 1, 1) // 改變矩形形狀 geom.vertices[0].y += hillHeight geom.vertices[1].y += hillHeight geom.vertices[10].y += hillHeight geom.vertices[13].y += hillHeight geom.vertices[4].x += groundDeep geom.vertices[5].x += groundDeep var mat = new THREE.MeshStandardMaterial({ color: color.ground, shading: THREE.FlatShading, roughness: 1, metalness: 0 }) this.mesh = new THREE.Mesh(geom, mat) this.add(this.mesh)
使用相同的邏輯咱們能夠建立草皮元素性能
房屋能夠拆分紅屋頂,窗戶,門,牆,煙囪等部件
其中屋頂,和牆也是對基本幾何體的變形,能夠參考上一節的方法,這裏就再也不贅述。
下面咱們說一說Group與ThreeBSPthis
THREE.Group.apply(this, arguments)
查看源碼能夠發現一個常常被使用到的對象THREE.Group。
Group是一個組,其中能夠容納多個Mesh對象,而且若是咱們對該group進行旋轉,平移,縮放操做時,Group會至關於一個總體進行旋轉,平移,縮放。
與之類似,Geometry對象提供了一個Merge方法,能夠合併geometry。
它們之間的差別在於:spa
Group添加的是Mesh,而Merge做用的對象是Geometry;code
即使添加到Group中,Group內的各個Mesh還能夠被單獨操做,使用Merge至關與合成了一個大的geometry對象,你沒法在單獨操做其中的geometry,對於建立後不須要再單獨操做的對象使用Merge能夠提高性能orm
ThreeBSP是一個用來建立geometry的Three.js的擴展庫
用圖來表示一下:
union方式用來獲得geometry的合體(相似並集)
intersect方式用來獲得交集
substract用來從Mesh中挖去另外一個Mesh
用將大Box中挖去小box的思路,咱們就能夠穿件一個窗戶的外框
// 鏤空 function substractMesh(basic, substract, mat) { var material = new THREE.MeshBasicMaterial() var mesh1 = new THREE.Mesh(basic, material) var mesh2 = new THREE.Mesh(substract, material) var basicBSP = new ThreeBSP(mesh1) var substractBSP = new ThreeBSP(mesh2) var res = basicBSP.subtract(substractBSP) res = res.toMesh() res.geometry.computeFaceNormals() res.geometry.computeVertexNormals() res.material = mat return res }
如上,能夠抽象出一個鏤空函數來幫咱們處理mesh
substractMesh函數將接收三個參數(被挖的Mesh,從中挖去的Mesh,最終Mesh的材質)
返回一個鏤空後的Mesh
這篇並無像前篇同樣全程代碼,由於靜態元素的構建過程真的大同小異全寫出來難免枯燥,二來這也僅僅是我的的思路,並且條條大路通羅馬,不該該束縛本身的想象力。以上就是構建村莊中靜態部件的思路,在下一章節咱們會介紹複雜部件如雲,森林是如何構建的