一、环境准备
1.开发工具选用WebStorm,因为WebStorm自带了一个本地服务器,而Three.js的很多特性需要在服务器端才能展现。
2.three.js库的下载与导入
3.打开调用three.js的html的网页文件时,需要借助WebStorm提供的本地服务器,如图所示,通过点击右上角浏览器图标而打开网页文件。
二、文件结构
三、例子展示
四、源码展示
html文件:
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="three.js"></script>
</head>
<body>
<!-- 用于接收three.js画面的输出 -->
<div id="WebGL-output"> </div>
<script>
// 当页面加载完毕后,调用此函数,初始化画面
function init() {
// 创建【场景】,场景用于存放各种物体、光源等
var scene = new THREE.Scene();
// 创建【相机】,相机相当于视角,可以定义视角(相机)的在【场景】中的朝向,远近面等
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
// 创建【渲染器】,渲染器用于加载画面,计算指定【相机】角度下浏览器中【场景】的样子
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMapEnabled = true;
// 展示坐标轴
var axes = new THREE.AxisHelper(50);
scene.add(axes);
// 创建地面
var planeGeometry = new THREE.PlaneGeometry(60, 20, 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 = 15;
plane.position.y = 0;
plane.position.z = 0;
// 将地面添加到场景中
scene.add(plane);
// 创建立方体
var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.castShadow = true;
// 设置立方体的位置坐标
cube.position.x = -4;
cube.position.y = 3;
cube.position.z = 0;
// 将立方体添加到场景中
scene.add(cube);
var sphereGeometry = new THREE.SphereGeometry(4, 20, 20);
var sphereMaterial = new THREE.MeshLambertMaterial({color: 0x7777ff});
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.x = 20;
sphere.position.y = 0;
sphere.position.z = 2;
sphere.castShadow = true;
scene.add(sphere);
// 设置相机的位置和视角朝向
camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 30;
camera.lookAt(scene.position);
// 增加环境光源
var ambientLight = new THREE.AmbientLight(0x0c0c0c);
scene.add(ambientLight);
// 增加点光源
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-40, 60, -10);
spotLight.castShadow = true;
scene.add(spotLight);
// 将画面输出到id为WebGL-output的div标签中
document.getElementById("WebGL-output").appendChild(renderer.domElement);
// 渲染【场景】
var step = 0;
renderScene();
function renderScene() {
// 立方体旋转
cube.rotation.x += 0;
cube.rotation.y += 0.1;
cube.rotation.z += 0.1;
// 球体跳跃
step += 0.04;
sphere.position.x = 20 + ( 10 * (Math.cos(step)));
sphere.position.y = 4 + ( 10 * Math.abs(Math.sin(step)));
// 递归渲染
requestAnimationFrame(renderScene);
renderer.render(scene, camera);
}
}
window.onload = init;
</script>
</body>
</html>
五、附加
1.球体运动的算法介绍:
2.对比 Three.js中的 requestAnimationFrame() 与原生js中的setInterval():
(1)requestAnimationFrame()函数:可以指定一个函数,按照浏览器定义的时间间隔调用,可以在这个指定的函数里执行所有必要的绘画操作,而浏览器会尽可能保证绘画过程平滑、高效。
(2)setInterval()函数:可指定函数多长时间内调用一次,这个函数的问题是它并不考虑浏览器中发生的事情,如果你正在浏览其他页面,这个函数仍然会每隔几毫秒就会被调用一次,除此之外,setInterval()方法并没有跟显示器的重画同步,这可能会导致较高的CPU使用率,降低系统效率。