前面簡單介紹了webGL和Three.js的背景以及照相機的設定,接下來介紹一些Three.js中的幾何形狀。
1.立方體
雖然這一形狀的名字叫立方體(CubeGeometry),但它其實是長方體,也就是長寬高可以設置為不同的值。其構造函數是:
THREE.CubeGeometry(width,height,depth,widthSegments,heightSegments, depthSegments)
width:x方向上的長度
height:y方向上的長度
depth:z方向上的長度
widthSegments:x方向上的分段數(可選,缺省值1)
heightSegments:y方向上的分段數(同上)
depthSegments:z方向上的分段數(同上)
未分段:
var material = new THREE.MeshBasicMaterial({
color: 0xffff00,
wireframe: true
});
drawCube(scene, material);
function drawCube(scene, material) {
var cube = new THREE.Mesh(new THREE.CubeGeometry(1, 2, 3), material);
scene.add(cube);
}

物體的默認位置是原點,對於立方體而言,是其幾何中心在原點的位置。
分段:
var cube = new THREE.Mesh(new THREE.CubeGeometry(1, 2, 3, 2, 2, 3), material);

為什么會有這么多邪線呢?版本問題。R73版本:

注意這個分段是對六個面進行分段,而不是對立方體的體素分段,因此在立方體的中間是不分段的,只有六個側面被分段。
2.平面
這里的平面(PlaneGeometry)其實是一個長方形,而不是數學意義上無限大小的平面。其構造函數為:
THREE.PlaneGeometry(width, height, widthSegments, heightSegments)
width:x方向上的長度
height:y方向上的長度
widthSegments:x方向上的分段數(可選,缺省值1)
heightSegments:y方向上的分段數(同上)
new THREE.PlaneGeometry(2, 4);創建的平面在x軸和y軸所在平面內,效果如下:

3.球體
球體(SphereGeometry)的構造函數是:
THREE.SphereGeometry(radius,segmentsWidth,segmentsHeight,phiStart, phiLength, thetaStart, thetaLength) // radius:半徑 // segmentsWidth:經度上的分段數 // segmentsHeight:緯度上的分段數 // phiStart:經度開始的弧度 // phiLength:經度跨過的弧度 // thetaStart:緯度開始的弧度 // thetaLength:緯度跨過的弧度
3.1 經緯度分段數
首先,我們來理解下segmentsWidth和segmentsHeight。使用var sphere = new THREE.SphereGeometry(3, 8, 6)可以創建一個半徑為3,經度划分成8份,緯度划分成6份的球體,如下圖所示。

segmentsWidth相當於經度被切成了幾瓣,而segmentsHeight相當於緯度被切成了幾層。
new THREE.SphereGeometry(3, 5, 4)的效果:

new THREE.SphereGeometry(3, 8, 6)的效果:

new THREE.SphereGeometry(3, 18, 12)的效果:

在圖形底層的實現中,並沒有曲線的概念,曲線都是由多個折線近似構成的。對於球體而言,當這兩個值較大的時候,形成的多面體就可以近似看做是球體了。
3.2 經度弧度
new THREE.SphereGeometry(3, 8, 6, Math.PI / 6, Math.PI / 3)表示起始經度為Math.PI / 6,經度跨度為Math.PI / 3。效果如下:

注意,這里segmentsWidth為8意味着對於經度從Math.PI / 6跨過Math.PI / 3的區域內划分為8塊,而不是整個球體的經度划分成8塊后再判斷在此經度范圍內的部分。
3.3 緯度弧度
緯度弧度同理。new THREE.SphereGeometry(3, 8, 6, 0, Math.PI * 2, Math.PI / 6, Math.PI / 3)表示緯度從Math.PI / 6跨過Math.PI / 3。效果如下:

new THREE.SphereGeometry(3, 8, 6, Math.PI / 2, Math.PI, Math.PI / 6, Math.PI / 2)的效果:

4.源碼
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8">
5 <title>3.js測試四</title>
6 </head>
7 <body onload="init()">
8 <canvas id="mainCanvas" width="400px" height="300px" ></canvas>
9 </body>
10 <script type="text/javascript" src="js/three.min.js"></script>
11 <script type="text/javascript">
12 function init() {
13 var renderer = new THREE.WebGLRenderer({
14 canvas: document.getElementById('mainCanvas')
15 });
16 renderer.setClearColor(0x000000);
17 var scene = new THREE.Scene();
18
19 // camera
20 var camera = new THREE.OrthographicCamera(-5, 5, 3.75, -3.75, 0.1, 100);
21 camera.position.set(25, 25, 25);
22 camera.lookAt(new THREE.Vector3(0, 0, 0));
23 scene.add(camera);
24
25 // 材質
26 var material = new THREE.MeshBasicMaterial({
27 color: 0xffff00,
28 wireframe: true
29 });
30
31 drawCube(scene, material); //立方體
32 // drawPlane(scene, material); //平面
33 // drawSphere(scene, material); //球體
34
35 // render
36 renderer.render(scene, camera);
37 }
38
39 function drawCube(scene, material) {
40 var cube = new THREE.Mesh(new THREE.CubeGeometry(1, 2, 3, 2, 2, 3), material);
41 scene.add(cube);
42 }
43
44 function drawPlane(scene, material) {
45 var plane = new THREE.Mesh(new THREE.PlaneGeometry(2, 4), material);
46 scene.add(plane);
47 }
48
49 function drawSphere(scene, material) {
50 var sphere = new THREE.Mesh(new THREE.SphereGeometry(3, 18, 12), material);
51 // var sphere = new THREE.Mesh(new THREE.SphereGeometry(3, 8, 6, Math.PI / 6, Math.PI / 3), material);
52 // var sphere = new THREE.Mesh(new THREE.SphereGeometry(3, 8, 6, 0, Math.PI * 2, Math.PI / 6, Math.PI / 3), material);
53 // var sphere = new THREE.Mesh(new THREE.SphereGeometry(3, 8, 6, Math.PI / 2, Math.PI, Math.PI / 6, Math.PI / 2), material);
54 scene.add(sphere);
55 }
56 </script>
57 </html>
整理自張雯莉《Three.js入門指南》

