文章目录
一、物体运动的两种方法
1.1 改变相机的位置
让相机在坐标系里面移动,物体不动。
1.2 改变物体的位置
物体在坐标系里面移动,摄像机不动。
二、渲染循环—运动的关键
物体运动的关键就是要渲染物体运动的每一个过程,让它显示给观众。渲染的时候,调用的是渲染器的render()函数
renderer.render(scene,camera);
- 如果改变了物体的颜色或者位置之类的属性,那么就需要不断的绘制新的场景,就要重复调用render()函数,才能将新的场景绘制到浏览器中去。、
- 为了实现循环,这里使用到了
requestAnimationFrame()
这个函数 - 调用
requestAnimationFrame()
函数,传递一个callback参数,则在下一帧动画时,调用callback这个函数。
function animate(){
render();
requestAnimationFrame(animate);
}
三、评估性能—Stats
关于性能
:测试一个程序,性能上是否有瓶颈,在3d中经常使用帧数的概念。帧数
:图形处理器每秒钟能够刷新几次,通常用fps来表示。- 帧数越高,画面的感觉会越好。
3.1 性能监视器Stats
- 关于它的介绍,可以在https://github.com/mrdoob/stats.js了解。
- 也可以在下载的three.js压缩包中了解:
- three.js-master
- examples
- js
- libs
- stats.js
FPS
:表示上一秒的帧数,值越大越好,一般为60左右。点击下图会变成绿色的。
MS
:表示渲染一帧需要的毫秒数,这个数字越小越好。再次点击可回到FPS视图中。
3.2 性能监视器Stats的使用
在Three.js中,性能监视器被封装在一个类中,这个类叫做Stats。
var stats = new Stats();
stats.setMode(1) //0:fps ,1:ms
//将Stats的界面放在左上角
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
document.body.appendChild(stats.domElement);
setInterval(function(){
stats.begin();
//每一帧代码
stats.end();
},1000/60);
代码解析:
setMode函数
:参数为0的时候,表示显示的是FPS界面,参数为1时,表示显示的是MS界面。Stats的domElement
:表示绘制的目的地(DOM),波形图就绘制在上面。Stats的begin函数
:在要测试的代码前面调用begin函数,在代码执行完毕后调用end函数,这样就能统计出这段代码执行的平均帧数了。- fps = 帧数/时间
使用步骤:
- new一个Stats对象
stats = new Stats()
- 将这个对象加入到HTML页面中
- 调用
stats.update()
函数来统计时间和帧数。
四、一个栗子
运用运动、渲染循环、性能检测
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>让物体动起来</title>
<script src="three.js"></script>
<script src="stats.js"></script>
</head>
<body>
<div id='app'></div>
<script>
//创建场景
var scene = new THREE.Scene();
//创建相机
var camera = new THREE.PerspectiveCamera(105,window.innerWidth/window.innerHeight,1,1000);
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 40;
//创建渲染器
render = new THREE.WebGLRenderer({
antialias:true
});
//设置画布大小
render.setSize(window.innerWidth,window.innerHeight);
var app = document.getElementById("app");
app.appendChild(render.domElement);
//创造一个立方体,点模型
var geometry = new THREE.CylinderGeometry(10,20,15,5);//参数:顶面半径,地面半径,高度,分成几边体
//创造一个立方体,网格模型
var material3 = new THREE.MeshBasicMaterial({
color:0x00ff00
});
var meshs = new THREE.Mesh(geometry,material3);
//创建物体的边框线
var geoedg = new THREE.EdgesGeometry(geometry,10);
var edgcol = new THREE.LineBasicMaterial({
color:0xffd700});
var geoline = new THREE.LineSegments(geoedg,edgcol);
meshs.add(geoline);
scene.add(meshs);
//渲染
render.render(scene,camera);
//性能监视器
var stats = new Stats();
stats.setMode(0);
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '30px';
stats.domElement.style.top = '10px';
app.appendChild(stats.domElement);
//产生动画
function animate(){
//相机移动
camera.position.y -=0.05;
if(camera.position.y < -10){
camera.position.z +=0.05;
}
render.render(scene,camera);
//物体移动
//meshs.position.y +=0.05;
//if(meshs.position.y>10){
//meshs.position.z -=0.05;
//}
//render.render(scene,camera);
//window.requestAnimationFrame(animate);
stats.update();
}
setInterval(animate,10);
</script>
</body>
</html>