本文学习内容来自《Three.js开发指南:WebGL的JavaScript 3D库》

创建场景

一个场景想要显示任何东西,需要三种类型的组件:

组件

说明

摄像机

决定屏幕上哪些东西需要渲染

光源

决定材质如何显示以及用于产生阴影

对象

摄像机透视图里主要的渲染对象,如方块、球体等

场景的一些方法

方法(属性)

描述

THREE.scene.add

添加对象

THREE.scene.remove

删除对象

THREE.scene.children

对象列表

THREE.scene.getObjectByName

获取对象

traverse(function)

遍历对象,在每个对象上执行方法

fog

添加雾化效果

overrideMaterial

强制场景中所有物体使用相同的材质

示例代码演示了上述属性、方法如何使用的。
另外,示例代码使用了stats计算FPS、GUI创建控件。

关键代码:
对象创建、删除等

var controls = new function () {
this.rotationSpeed = 0.02;
this.numberOfObjects = scene.children.length;

this.removeCube = function () {
var allChildren = scene.children;
var lastObject = allChildren[allChildren.length - 1];
if (lastObject instanceof THREE.Mesh) {
scene.remove(lastObject);
this.numberOfObjects = scene.children.length;
}
};

this.addCube = function () {

var cubeSize = Math.ceil((Math.random() * 3));
var cubeGeometry = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize);
var cubeMaterial = new THREE.MeshLambertMaterial({color: Math.random() * 0xffffff});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.castShadow = true;
cube.name = "cube-" + scene.children.length;


// position the cube randomly in the scene

cube.position.x = -30 + Math.round((Math.random() * planeGeometry.parameters.width));
cube.position.y = Math.round((Math.random() * 5));
cube.position.z = -20 + Math.round((Math.random() * planeGeometry.parameters.height));

// add the cube to the scene
scene.add(cube);
this.numberOfObjects = scene.children.length;
};

this.outputObjects = function () {
console.log(scene.children);
}
};

使用gui

var gui = new dat.GUI();
gui.add(controls, 'rotationSpeed', 0, 0.5);
gui.add(controls, 'addCube');
gui.add(controls, 'removeCube');
gui.add(controls, 'outputObjects');
gui.add(controls, 'numberOfObjects').listen();

Three.JS提升学习2:构建Three.js场景的基本组件_对象

一些标准的几何体

圆柱

new THREE.CylinderGeometry(1, 4, 4)

Three.JS提升学习2:构建Three.js场景的基本组件_对象_02
正方体

new THREE.BoxGeometry(2, 2, 2)

Three.JS提升学习2:构建Three.js场景的基本组件_自定义_03

球体

new THREE.SphereGeometry(2)

Three.JS提升学习2:构建Three.js场景的基本组件_对象_04
多面体

new THREE.IcosahedronGeometry(4)

Three.JS提升学习2:构建Three.js场景的基本组件_class_05

自定义凸面体

var points = [
new THREE.Vector3(2, 2, 2),
new THREE.Vector3(2, 2, -2),
new THREE.Vector3(-2, 2, -2),
new THREE.Vector3(-2, 2, 2),
new THREE.Vector3(2, -2, 2),
new THREE.Vector3(2, -2, -2),
new THREE.Vector3(-2, -2, -2),
new THREE.Vector3(-2, -2, 2)
];
geoms.push(new THREE.ConvexGeometry(points));

Three.JS提升学习2:构建Three.js场景的基本组件_对象_06

通常自定义的几何体可以通过定义点和面来创建。面的创建方式:

var faces = [
new THREE.Face3(0,2,1),
new THREE.Face3(2,3,1),
...
];

Lathe

var pts = [];//points array - the path profile points will be stored here
var detail = .1;//half-circle detail - how many angle increments will be used to generate points
var radius = 3;//radius for half_sphere
for (var angle = 0.0; angle < Math.PI; angle += detail)//loop from 0.0 radians to PI (0 - 180 degrees)
pts.push(new THREE.Vector3(Math.cos(angle) * radius, 0, Math.sin(angle) * radius));//angle/radius to x,z
geoms.push(new THREE.LatheGeometry(pts, 12));

Three.JS提升学习2:构建Three.js场景的基本组件_class_07
Octahedron

new THREE.OctahedronGeometry(3)

Three.JS提升学习2:构建Three.js场景的基本组件_class_08
Parametric

new THREE.ParametricGeometry(THREE.ParametricGeometries.mobius3d, 20, 10)

Three.JS提升学习2:构建Three.js场景的基本组件_对象_09

new THREE.TetrahedronGeometry(3)

Three.JS提升学习2:构建Three.js场景的基本组件_对象_10
圆环

new THREE.TorusGeometry(3, 1, 10, 10)

Three.JS提升学习2:构建Three.js场景的基本组件_自定义_11
环面纽结

new THREE.TorusKnotGeometry(3, 0.5, 50, 20)

Three.JS提升学习2:构建Three.js场景的基本组件_自定义_12

上述示例的渲染方法:

var j = 0;
for (var i = 0; i < geoms.length; i++) {
var cubeMaterial = new THREE.MeshLambertMaterial({wireframe: true, color: Math.random() * 0xffffff});

var materials = [

new THREE.MeshLambertMaterial({color: Math.random() * 0xffffff, shading: THREE.FlatShading}),
new THREE.MeshBasicMaterial({color: 0x000000, wireframe: true})

];

var mesh = THREE.SceneUtils.createMultiMaterialObject(geoms[i], materials);
mesh.traverse(function (e) {
e.castShadow = true
});

//var mesh = new THREE.Mesh(geoms[i],materials[i]);
//mesh.castShadow=true;
mesh.position.x = -24 + ((i % 4) * 12);
mesh.position.y = 4;
mesh.position.z = -8 + (j * 12);

if ((i + 1) % 4 == 0) j++;
scene.add(mesh);
}