1.簡單幾何體
three.js提供的稍微簡單點的幾何體包括有:PlaneGeometry(平面)、CircleGeometry(圓形)、ShapeGeometry(塑性)、CubeGeometry(立方體)、CylinderGeometry(圓柱)、TorusGeometry(圓環)、TorusKnotGeometry(畫面扭結)、PolyhedronGeometry(多面體)、IcosahedronGeometry(二十面體)、OctahedronGeometry(八面體)、TetraHedronGeometry(四面體)。
稍微復雜點的幾何體包括有:ConvexGeometry(凸面體)、LatheGeometry(掃描體)、ExtrudeGeometry(拉伸幾何體)、TubeGeometry(管狀體)ParameterGeometry(參數幾何體)、TextGeometry(文本幾何體)。
2.二維幾何體PlaneGoemetry
PlaneGeoemtry是矩形態的平面幾何體,初始化也很簡單,需要4個參數:
new THREE.PlaneGeometry(10, 14, 4, 4)
4個參數分別是width、height、widthSegment、heightSegment。其中widthSegment指定矩形的寬度應該划成幾段,這里是在width和height方向都划分成4段。如下所示:
3.同時顯示幾何體的面和網狀結構
可通過THREE.SceneUtils.createMultiMaterialObject來為幾何體添加多個材質,從而由顯示面的顏色也顯示網狀結構。實現代碼可參考下面:
var meshMaterial = new THREE.MeshNormalMaterial(); meshMaterial.side = THREE.DoubleSide; var wireFrameMat = new THREE.MeshBasicMaterial(); wireFrameMat.wireframe = true; var plane = THREE.SceneUtils.createMultiMaterialObject(new THREE.PlaneGeometry(10, 14, 4, 4), [meshMaterial, wireFrameMat]);
createMultiMaterialObject函數第一個參數是一個幾何體對象,第二個參數是材質的數組,可傳遞多個。其實最終生成的是多個物體,只不過都重疊在一起。
4.CircleGeometry
很容易理解CircleGeoemtry用來畫平面元的。屬性包括:
屬性/是否必填/描述
radius/是/定義啊圓的半徑
segments(分段)/否/定義創建圓所有面的數量,最少三個。如果沒有指定默認為8
thetaStart(起始角)/否/定義從哪兒開始畫圓。取值從0到2*PI
thetaLength(角度)/否/定義圓要花多大。如果沒有指定,默認為2*PI整圓。如果指定為0.5PI則為四分之一個圓
5.ShapeGeometry
PlaneGeometry和CircleGeometry只有有限的方法來定制他們的外觀。如果想創建一個自定義的二維圖形,可以使用ShapeGeometry。ShapeGeometry沒有比的選項可以定制圖形。一般都是先創建一個Shape圖形。用Shape圖形繪圖。Shape對象提供的函數繪制函數包括:
moveTo(x, y)/將繪圖點移動到x、y坐標處
lineTo(x, y)/從當前位置繪制一條線到指定的x、y坐標處
quadriCurveTo(aCPx, aCPy, x, z)(二次曲面)/定義曲面,可以使用quadraticCurveTo函數或者bezierCurveTo函數繪制曲面。
bezierCurveTO(aCPx1, aCPy1, aCPx2, aCPy2, x, y)/畫一條曲線。該曲線的繪制是基於兩個定義曲線的坐標以及重點坐標(x,y)。起始點是當前位置。
splineThru(pts)/該函數沿着提供的坐標集合繪制一條光華曲線。這個參數應該是THREE.Vector2的對象數組
arc(ay, ay, aRadius, aSTartAngle, aEndAngle, aClockwise)/畫圓或者一段圓弧。圓弧起始於當前位置。ax和ay用來指定圓心與當前位置之間的偏移量。aRadius設置圓大小,而aSTartAgnle和aEndAngle定義圓弧要畫多長。布爾aCockwise決定這段圓弧是順時針還是逆時針
absArc(ay, ay, aRadius, aSTartAngle, aEndAngle, aClockwise)/參考arc,其位置是絕對的,而不是相對於當前位置
ellipse(aX, aY, xRadius, aStartAngle, aEndAngle, aClockwise))/參考arc。作為補充,通過ellipse函數可以分別制定x軸半徑和y軸半徑
absEllipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise)/參考ellipse描述。起位置時絕對,而不是相對於當前位置的相對值
Shape對象屬性holes,通過往這個屬性中國添加THEE.Shape對象,你可以在圖形中打幾個洞。Shape對象本身也有幾個輔助函數,可永安里創建幾何體。如下所示:
makeGeometry/該函數從shape對象返回一個ShapeGeometry對象
createPointsGeometry(divisions)/改函數將圖形轉換成一個點集。屬性divisions分段數定義返回點的數目
createSpacedPointsGeoemtry(divisions)/該函數將圖形轉換為一個點集,但是這一次,分段數是一次性地應用到整個路徑上
如果用createPointsGeometry或者createSpacedPointsGeometry函數創建一個點集,你可用這些點創建線段
new THREE.Line(shape.createPointsGeometry(10), new THREE.LineBasicMateial({color: 0xff3333, linewidth: 2})
6.SphereGeometry
這個幾何體非常靈活,可以用來創建所有跟球體相關的幾何體。下表中的屬性可用來調整結果網格的外觀:
屬性/是否必填/描述
radius/否/該屬性設置球體的半徑
widthSegments/否/指定豎直方向上的分段數。默認為8,最小為2
hieghtSegments/否/指定水平方向的分段數。默認為6,最小為2
phiStart/否/指定從x軸的什么地方開始繪制。取值范圍從0到2*PI。默認為0
phiLength/否/指定從phiStart開始畫多少。2*PI是整球,0.5*PI是四分之一球
thetaStart/否/指定從y軸的什么地方開始繪制。取值范圍從0到PI。默認為0
thetaLength/指定從theata開始畫多少。PI是征求,0.5PI只會繪制上半球
7.CylinderGeometry
創建CylinderGeometry時,沒有必須提供的參數。直接調用new THREE.CylinderGeometry()即可創建一個圓柱。屬性列表如下:
radiusTop/圓柱頂部尺寸,默認是20
radiusBottom/設置圓柱底部的尺寸,默認是20
height/屬性設置圓柱的高度,默認是100
segmentsX/該屬性設置沿x軸分成多少段,默認是8.這個數字越大,圓柱越光滑
segmentsY/該屬性設置沿y軸分成多少段
openEnded/指定網格的頂部和底部是否封閉。默認為false
8.TorusGeometry
Torus圓環是一種簡單的圖形,看上去像甜甜圈。創建TorusGeometry沒有必須提供的參數。參數列表為:
radius/設置完整環的尺寸,默認為100
tube/設置是管子的半徑。默認為40
radialSegments/這個參數設置的是沿圓環長度方向分成的段數。默認是8
tabularSegments/這個參數設置沿圓環寬度方向分成的段數。默認是6
arc/通過該屬性值,可以孔子是否繪制一個完整的圓環。默認是 2*PI
9.ConvexGeometry
通過ConvexGeometry可以在一組點的外面建立一個凸面。所謂凸面就是包圍這組點的最小圖形。如下面的代碼,創建了一組隨機的點,使用new THREE.ConvexGeometry(points)初始化這個包面圖形。
function generatePoints(){ var points = []; for(var i = 0; i < 20; i++){ var randomX = -15 + 30 * Math.random(); var randomY = -15 + 30 * Math.random(); var randomZ = -15 + 30 * Math.random(); points.push(new THREE.Vector3(randomX, randomY, randomZ)); } spGroup = new THREE.Object3D(); var material = new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: true}); points.forEach(function(point){ var sphereGeometry = new THREE.SphereGeometry(0.2); var mesh = new THREE.Mesh(sphereGeometry, material); mesh.position.copy(point); spGroup.add(mesh); }); scene.add(spGroup); var hullGeometry = new THREE.ConvexGeometry(points); hullMesh = createMesh(hullGeometry); scene.add(hullMesh); }
10.TubeGeometry
TubeGeometry沿着一條三維樣條曲線拉伸出一根管道。你可以通過指定頂點來定義路徑,然后TubeGeometry就可以創建這根管子。如下面的代碼:
function generatePoints(points, segments, radius, radiusSegments, closed){ spGroup = new THREE.Object3D(); var material = new THREE.MeshBasicMaterial({color: 0xff0000, transparent: false}); points.forEach(function(point){ var spGeom = new THREE.SphereGeometry(0.2); var spMesh = new THREE.Mesh(spGeom, material); spMesh.position.copy(point); spGroup.add(spMesh); }); scene.add(spGroup); var tubeGeometry = new THREE.TubeGeometry(new THREE.SplineCurve3(points), segments, radius, radiusSegments, closed); tubeMesh = createMesh(tubeGeometry); scene.add(tubeMesh); }
points是一組Vector3集合,但TubeGeometry不能直接使用,必須要轉換成THREE.SplineCurve3創建樣條。而且這個參數是比傳的。其他屬性如下列表:
屬性/是否必須/描述
path/是/該屬性用一個THREE.SplineCurve3對象指定管道應當遵循的路徑
segments/否/管道所有的分段數。默認64.路徑越長,指定的分段數應該越多
radius/否/管道半徑,默認為1
radiusSegments/否/管道圓周的分段數。默認是8.分段數越多,管道看上去越圓滑
closed/否/如果為true,管道的頭和尾會連起來。默認為false
11.textGeometry
text幾何體的創建代碼可參考如下:
this.asGeom = function(){ scene.remove(text1); scene.remove(text2); var option = { size: controls.size, height: controls.height, weight: controls.weight, font: controls.font, bevelThickness: controls.bevelThickness, bevelSize: controls.bevelSize, bevelSegments: controls.bevelSegments, bevelEnabled: controls.bevelEnabled, curveSegments: controls.curveSegments, steps: controls.steps } text1 = createMesh(new THREE.TextGeometry("Learning", option)); text1.position.z = -100; text1.position.y = 100; scene.add(text1); text2 = createMesh(new THREE.TextGeometry("Three.js", option)); scene.add(text2); }
和其他幾何體創建方式一樣,只是初始化時調用new THREE.TextGeometry對象,第一個參數是傳遞的文字。第二個參數是幾何體的屬性。屬性列表如下:
屬性/是否必須/描述
size/否/指定文字的大小。默認100
height/否/指定拉伸的程度。默認是50
weight/否/指定字體的權重。可選的值是normal、bold。默認normal
font/否/指定要使用的字體名。默認是helvetiker
style/否/字體樣式。可選值包括normal、italic。默認是normal
bevelThickness(斜角厚度)/否/指定斜角的深度。斜角是前后面和拉伸面之間的倒角。默認是10
bevelSegments(斜角分段數)/斜角的分段數。默認是3
bevelSize/否/指定斜角的高度。默認為8
bevelEnabled/否/如果設置為true,就會有斜角。默認為false
curveSegments(曲線分段數)/否/定義拉伸體被分成幾段。默認為1.
steps(拉伸體段數)/否/拉伸體被分成多少段。默認為1
extrudePath/否/指定圖形沿着什么路徑拉伸。如果沒有指定,圖形沿着z軸拉伸
material/否/定義前后面所用材質的索引。用函數THREE.SceneUtils.createMultiMaterialObject創建網格
extrudeMateria(拉伸材質)/否/指定斜角和拉伸體所用材質的索引。用函數THREE.SceneUtils.createMultiMaterialObject創建網格
12添加自定義字體
Three.js提供了幾種可以在場景中使用的字體。這些字體技術是由typeface.js(http://typeface.neocracy.org)提供的字體。typeface.js是一個可以將TrueType和OpenType字體轉換為Javascript庫。轉換出來的Javascript文件可以包含在你的頁面,然后即可在Three.js中使用。
要轉換已有的OpenType或TrueType字體,可以使用網頁http://typeface.neocracy.org/fonts.html。你可以在這個網站上上傳一個字體,然后它就會把該字體轉化成javascript。要包含這個字體。只要在html頁面頂部引用這個javascript文件即可。
13.使用二元操作組合網格
我們可以把標准的幾何體組合在一起創建出一個新的幾何體。實現這個功能,我們可以使用Three.js擴展庫ThreeBSP。下載地址為:https://github.com/skalnik/ThreeBSP。這個擴展庫提供了三個函數:
intersect(相交)/可以在兩個幾何體的交集上創建出新的幾何體。兩個幾何體相互交疊的地方就是新的幾何體
union(聯合)/將兩個幾何體聯合在一起創建出新的幾何體。可以將這個函數與mergeGeometry函數想比較
subtract(相減)/可以在第一個幾何體中減去兩個幾何體交疊的部分,從而創建出新的幾何體
下面代碼是使用ThreeBSP的代碼,使用也比較簡單:
function redrawResult(){ showSpinner(); //異步執行,避免鎖定線程 setTimeout(function(){ scene.remove(result); var sphere1BSP = new ThreeBSP(sphere1); var sphere2BSP = new ThreeBSP(sphere2); var cubeBSP = new ThreeBSP(cube); var resultBSP; switch(controls.actionSphere){ case "subtract": resultBSP = sphere1BSP.subtract(sphere2BSP); break; case "intersect": resultBSP = sphere1BSP.intersect(sphere2BSP); break; case "union": resultBSP = sphere1BSP.union(sphere2BSP); break; case "none": break; } if(!resultBSP) resultBSP = sphere1BSP; switch(controls.actionCube){ case "subtract": resultBSP = cubeBSP.subtract(resultBSP); break; case "intersect": resultBSP = cubeBSP.intersect(resultBSP); break; case "union": resultBSP = cubeBSP.union(resultBSP); break; case "none": break; } if(controls.actionCube === "none" && controls.actionSphere === "none"){ }else{ result = resultBSP.toMesh(); result.geometry.computeFaceNormals(); result.geometry.computeVertexNormals(); scene.add(result); } hideSpinner(spinner); }, 200); }
要使用運算函數,需要把geometry轉換成ThreeBSP對象。代碼resultBSP = sphere1BSP.subtract(sphere2BSP)最終的結果是sphere1BSP幾何體減去和sphere2BSP重疊的部分后剩下的幾何體。
運算完成后直接調用result.BSP.toMesh()函數即可得到網格。但還需要調用computeFaceNormals和computeVertexNromals函數,這是因為執行二元操作之后,幾何體中心店和面的法向量可能會變化。Three.js在着色器中會用到面法向量和頂點法向量。明確地重新計算面和頂點法向量,可保證新生成的對象着色光滑。

