three.js之自定义一个正方体(网格)

本节主要通过自定义顶点和平面的方式,创造一个立方体。真正的开始走近three.js。


效果图

three.js之自定义一个正方体(网格)_第1张图片

坐标系

坐标系支持右手定则。图中红色是x轴,绿色是y轴,蓝色是z轴
three.js之自定义一个正方体(网格)_第2张图片

源码

引入的插件js【本人的csdn也有下载资源,如果打不开git可以在csdn下载】:

  • three.js
  • dat.gui.js
  • Stats.js
  • TrackballControls.js
  • SceneUtils.js
  • util.js
DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>title>
		<link type="text/css" rel="stylesheet" href="../css/index.css" />
		<script src="../libs/three.js">script>
		<script src="../libs/Stats.js">script>
		<script src="../libs/dat.gui.js">script>
		<script src="../libs/TrackballControls.js">script>
		<script src="../js/util/three_util.js">script>
		<script src="../js/util/SceneUtils.js">script>
	head>
	<body>
		<div id="webgl-output">div>
		<script src="../js/3.js">script>
	body>
html>

3.js

var stats = initStats();
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100);
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000));
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;

var planeGeometry = new THREE.PlaneGeometry(60, 40, 1, 1);
var planeMaterial = new THREE.MeshLambertMaterial({
	color: 0xffffff
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.receiveShadow = true;
plane.rotation.x = -0.5 * Math.PI;
plane.position.x = 0;
plane.position.y = 0;
plane.position.z = 0;
scene.add(plane);

camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 30;
camera.lookAt(scene.position);

// 设置8个顶点
var vertices = [
	new THREE.Vector3(1,1,1),
	new THREE.Vector3(1,5,1),
	new THREE.Vector3(1,1,5),
	new THREE.Vector3(1,5,5),
	new THREE.Vector3(5,1,1),
	new THREE.Vector3(5,5,1),
	new THREE.Vector3(5,1,5),
	new THREE.Vector3(5,5,5)
]

// 构建立方体所需要的十二个三角形平面
var faces = [
	new THREE.Face3(0,2,1),
	new THREE.Face3(2,3,1),
	new THREE.Face3(7,3,2),
	new THREE.Face3(7,2,6),
	new THREE.Face3(5,7,6),
	new THREE.Face3(4,5,6),
	new THREE.Face3(1,5,0),
	new THREE.Face3(0,5,4),
	new THREE.Face3(5,1,3),
	new THREE.Face3(5,3,7),
	new THREE.Face3(2,0,4),
	new THREE.Face3(2,4,6)
]

var geom = new THREE.Geometry()
geom.vertices = vertices
geom.faces = faces
geom.computeFaceNormals()
// 设置两种材质,这样方便同时看颜色和骨架
var materials = [
	new THREE.MeshBasicMaterial({color: 0x000000, wireframe: true}),
	new THREE.MeshLambertMaterial({opacity: 0.6, color: 0x44ff44, transparent: true})
];
// materials这样做的原因是,除了显示绿色透明的立方体外,我还想显示一个线框。因为使用线框可以很容易地找出顶点和面的位置。
// SceneUtils是SceneUtils里的方法
var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, materials);
mesh.castShadow = true;
mesh.children.forEach(function (e) {
  e.castShadow = true
});

scene.add(mesh);

var ambientLight = new THREE.AmbientLight(0x3c3c3c);
scene.add(ambientLight);

var spotLight = new THREE.SpotLight(0xffffff, 1.2, 150, 120);
spotLight.position.set(-40, 60, -10);
spotLight.castShadow = true;
scene.add(spotLight);

document.getElementById("webgl-output").appendChild(renderer.domElement);
var trackballControls = initTrackballControls(camera, renderer);
var clock = new THREE.Clock();
render();
    
function render() {
	trackballControls.update(clock.getDelta());
	stats.update();
	requestAnimationFrame(render);
	renderer.render(scene, camera);
}

注意点:

  • 通过vertices方法设置顶点,通过faces设置平面。
  • three里平面是由三角形构成的,所以我们要用三角形去拼装成一个个平面,比如我们要构建一个正方体,那么就需要定义8个顶点和12个三角形,
  • 三角形的顶点顺序是有规则的,当三个点是顺时针排列的时候,平面是面向相机的(面向相机的平面带颜色),反之则相反。(当然也可以伸出右手,让手指顺着顶点排列的顺序弯曲,这时候大拇指指向的方向就是平面的正面即有颜色的一侧。类似我们高中物理的电磁感应的右手定则一样。)
  • 示例中引用了SceneUtils.js里的createMultiMaterialObject方法,主要是为了构建一个同时支持两种材质的平面。

网格的方法

three.js之自定义一个正方体(网格)_第3张图片

  • mesh.rotation.x = Math.PI * 0.4 或 mesh.rotation.set(Math.PI * 0.4, 0, 0) 或 mesh.rotation = new THREE.Vector3(Math.PI * 0.4, 0, 0)
  • mesh.position.x = 4 或 mesh.position.set(4, 0, 0) 或 mesh.position = new THREE.Vector3(Math.PI * 0.4, 0, 0)
  • mesh.scaleX = 4 或 mesh.scale = 4 或 mesh.scale.set(4, 0, 0)
  • mesh.translateX = 4或 mesh.translate.set(4, 0, 0)
  • mesh.visible = true 或 false

你可能感兴趣的:(three.js,javascript,前端,git)