stats.js 和 dat.gui.js可以从 https://github.com/mrdoob/three.js/tree/master/examples/js/libs里获取
1.使用stats监测FPS
很多情况下,我们希望知道实时的FPS信息,从而更好地监测动画效果。这时候,就要用到stats.js了!
要显示这个信息,我们首先需要在<head>
标签里引入这个库:
<script src="stats.min.js"></script>
接下来写个函数初始化这个统计对象:
function initStats(){
//实例化
var stats = new Stats();
//setMode参数如果是0,监测的是FPS信息,如果是1,监测的是渲染时间
stats.setMode(0);
//把统计面板放到左上角
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
stats.domElement.style.left = '0px';
//添加到body里
document.body.appendChild(stats.domElement);
//返回这个实例
return stats;
}
我们可以在渲染之前调用它:
...
var stats = initStats();
// 调用渲染函数
render();
剩下的就是告诉stats对象每次渲染的开始时间,为此我们需要在render函数里调用 stats.update方法,如下:
function render() {
stats.update()
...
requestAnimationFrame(render);
renderer.render(scene, camera);
}
添加上以上代码后,就可以在左上角看到FPS的信息了,如下图:
2.使用dat.gui简化实验
在它的帮助下,你能很容易的就可以创建出一个简单的界面组件,用以修改代码中的变量,下面我就开始添加一个用户界面,使得我们可以:
- 控制球的弹跳速度
- 控制方块的旋转
和stats一样,我们首先需要在<head>
标签里引入这个库:
<script src="dat.gui.min.js"></script>
接下来定义一个对象,用来保存我们想要通过dat.gui修改的那些变量:
var ctrls = {
rotationSpeed:0.02,//旋转速度
bouncingSpeed:0.03,//弹跳速度
bouncingHeight:10//弹跳高度
}
在ctrls对象里我们定义了三个属性,并设置默认值。接下来我们要把这个对象传给dat.GUI对象并定义这三个属性的取值范围,如下:
//初始化对象,并添加变量的取值范围
var gui = new dat.GUI();
gui.add(ctrls,'rotationSpeed',0,0.5);
gui.add(ctrls,'bouncingSpeed',0,0.5);
gui.add(ctrls,'bouncingHeight',10,20);
属性rotationSpeed和bouncingSpeed的取值范围是0到0.5,bouncingHeight取值范围是10到20。现在要做的是保证render函数循环里直接引用这三个属性,这样当我们在dat.GUI用户界面修改时,可以影响物体的旋转速度,弹跳速度和弹跳高度。如下:
function render() {
...
box.rotation.x += ctrls.rotationSpeed;
box.rotation.y += ctrls.rotationSpeed;
box.rotation.z += ctrls.rotationSpeed;
step += ctrls.bouncingSpeed;
sphere.position.x = 20 + 10 * Math.cos(step)
sphere.position.y = 2 + ctrls.bouncingHeight * Math.abs(Math.sin(step))
...
}
现在运行这个示例,你会看到一个简单的用户界面,通过它你可以控制物体的旋转速度,弹跳速度和弹跳高度:
完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>three.js入门(3) stats.js和dat.gui.js的使用</title>
<script src="stats.min.js"></script>
<script src="dat.gui.min.js"></script>
<script src="three.js"></script>
</head>
<body>
<script>
// 渲染器
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
renderer.setClearColor(0x000000);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap
// 场景
var scene = new THREE.Scene();
// 照相机
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(-30, 40, 30);
camera.lookAt(new THREE.Vector3(0, 0, 0));
// 辅助轴
var axes = new THREE.AxisHelper(20);
scene.add(axes);
// 平面
var planeGeometry = new THREE.PlaneGeometry(60, 20);
var planeMaterial = new THREE.MeshLambertMaterial({
color: 0xffffff
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.position.set(15, 0, 0);
plane.rotation.x = -0.5 * Math.PI;
plane.receiveShadow = true;
scene.add(plane);
// 立方体
var boxGeometry = new THREE.BoxGeometry(4, 4, 4);
var boxMaterial = new THREE.MeshLambertMaterial({
color: 0xff0000
});
var box = new THREE.Mesh(boxGeometry, boxMaterial);
box.position.set(-4, 3, 0);
box.castShadow = true;
scene.add(box);
// 球
var sphereGeometry = new THREE.SphereGeometry(4, 32, 32);
var sphereMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff,
wireframe: true
});
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.set(20, 4, 2);
sphere.castShadow = true;
scene.add(sphere);
// 灯光
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-10, 20, -10);
spotLight.castShadow = true;
scene.add(spotLight);
// 灯光辅助
var spotLightHelper = new THREE.SpotLightHelper(spotLight);
scene.add(spotLightHelper);
//统计对象,用户显示FPS
var stats = initStats();
// 用来保存我们想要通过dat.gui修改的那些变量
var ctrls = {
rotationSpeed:0.02,
bouncingSpeed:0.03,
bouncingHeight:10
}
//初始化对象,并添加变量的取值范围
var gui = new dat.GUI();
gui.add(ctrls,'rotationSpeed',0,0.5);
gui.add(ctrls,'bouncingSpeed',0,0.5);
gui.add(ctrls,'bouncingHeight',10,20);
// 调用渲染函数
render();
var step = 0;
function render() {
stats.update()
box.rotation.x += ctrls.rotationSpeed;
box.rotation.y += ctrls.rotationSpeed;
box.rotation.z += ctrls.rotationSpeed;
step += ctrls.bouncingSpeed;
sphere.position.x = 20 + 10 * Math.cos(step)
sphere.position.y = 2 + ctrls.bouncingHeight * Math.abs(Math.sin(step))
requestAnimationFrame(render);
renderer.render(scene, camera);
}
//初始化统计对象
function initStats(){
var stats = new Stats();
stats.setMode(0);
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
stats.domElement.style.left = '0px';
document.body.appendChild(stats.domElement);
return stats;
}
</script>
</body>
</html>