昔洛 的个人博客

Bug不空,誓不成佛

目录
(三)(二)WebGL Threejs 学习 ----- 让场景动起来
/        

(三)(二)WebGL Threejs 学习 ----- 让场景动起来

学习内容

  • 让场景动起来
    • 相对运动
    • 渲染循环
  • 物体移动
    • 改变相机的位置,让物体移动
    • 改变物体自身的位置,让物体移动
  • 动画运动后,评估程序的性能
  • 性能测试步骤
  • 使用动画引擎 Tween.js 创建动画

让场景动起来

  • 相对运动:通过九年义务教育,我们学习物理知识都知道相对运动这个概念,世间万物都在不停地运动,选择不同的物体作为参照物,那么动画运动的结果也是不同的。而在 three.js 中,场景中的物体发生运动,也是基于相对运动这个概念,比如我们可以让物体在坐标系里面移动,摄像机不动。或者也可以让摄像机在坐标系里面移动,物体不动。这样场景就能够运动起来。
  • 循环渲染:物体运动还有一个关键点,就是要渲染物体运动的每一个过程,让它显示给观众。渲染的时候,我们调用的是渲染器的 render() 函数,代码如下:
    renderer.render(scene, camera);
    
    • 如果我们改变了物体的位置或者颜色之类的属性,就必须重新调用 render() 函数,才能够将新的场景绘制到浏览器中去。不然浏览器不会自动刷新场景的。
    • 如果不断的改变物体的颜色,那么就需要不断的绘制新的场景,所以最好的方式,就是让画面执行一个循环,不断的调用 render 来重绘,这个循环就是渲染循环,在游戏中,叫做游戏循环。
    • 为了实现循环,这里使用一个特殊的函数 requestAnimationFrame,调用该函数时,需要传递一个回调函数,在下一动画帧时,就会调用这个回调函数,于是有下例子:
    function animate() {
    	render();
    	requestAnimationFrame(animate);
    }
    // 这样就会不断执行 animate 这个函数,也就是不断执行 render 函数。
    

改变相机的位置,让物体移动

  • 改变 animation 的代码代码,它将不断的通过下面的代码改变相机的位置:camera.position.x = camera.position.x + 1;
  • 将相机不断的沿着 x 轴移动 1 个单位,也就是相机向右移动。相机向右,相对于相机而言,物体就像左移动。
  • 设置完相机的位置后,调用 requestAnimationFrame(animation) 函数,这个函数又回在下一个动画帧触发 animation 函数,这样就实现不断改变相机的位置,从而实现物体看上去在移动。
  • 另外,必须要重视 render 函数,这个函数是重新绘制渲染结果,如果不调用这个函数,那么及时相机发生了变化,但是没有重新绘制,仍然现实的是上一帧的动画。

改变物体自身的位置,让物体移动

  • 关注 animation 函数处的代码,mesh.position.x -= 1;
  • mesh 就是指的物体,它有一个位置属性 position,这个 position 是一个 THREE.Vector3 类型变量,所以要把它移动,仅需要将 x 的值不断的减少即可。

物体运动后,评估程序的性能

  • 性能:测试一个程序,性能上是否有瓶颈,在 3D 世界里,经常使用帧数的概念。
  • 帧数:图形处理器每秒能够刷新几次,通常用 fps(Frames Per Second)来表示。如下是每秒 59 次刷新的应用:20130515140758436.png
  • 当物体在快速运动时,当人眼所看到的影像消失后,人眼仍能继续保留其影像1/24秒左右的图像,这种现象被称为视觉暂留现象。是人眼具有的一种性质。人眼观看物体时,成像于视网膜上,并由视神经输入人脑,感觉到物体的像。一帧一帧的图像进入人脑,人脑就会将这些图像给连接起来,形成动画。

性能监视器 Stats

    在 Three.js 中,性能由一个性能监视器来管理,他的介绍在https://github.com/mrdoob/stats.js 可以看到,性能监视器的截图如下所示:20130515140815493.png
    其中 FPS 表示:上一秒的帧数,这个值越大越好,一般都为 60 左右。点击上面的图,就会变成如下所示的另一个视图20130515140824632.png
MS 表示渲染一帧需要的毫秒数,这个数字是越小越好。再次点击又可以回到 FPS 视图中。

性能监视器的 Stats 的使用

在 Three.js 中,性能监视器被封装在一个类中,这个类叫做 Stats,使用时需引入这个 js 文件,示例代码如下:

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();
	// work code...
	stats.end();
), 1000 / 60);

Stats做了哪些事情?

  • setMode 函数:参数为 0 的时候,表示显示的是 FPS 界面,参数为 1 的时候,表示显示的是 MS 界面。
  • stats 的 domElement:stats 的 domElement 表示绘制的目的地(DOM),波形图就绘制在这上面。
  • stats 的 begin 函数:begin,在要测试的代码前面调用 begin 函数,在你代码执行完后调用 end() 函数,这样就能够统计出这段代码执行的平均帧数了。

性能测试步骤

  • new 一个 stats 对象: stats = new Stats();
  • 将这个对象加入到 html 网页中去,代码如下:
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.right = '0px';
  • 调用 stats.update() 函数来统计时间和帧数:stats.update();

使用动画引擎 Tween.js 来创建动画

上面描述的是通过移动相机或者物体产生的动画效果。使用的方法是在渲染循环里去移动相机或者物体的位置。如果动画稍微复杂些,这种实现方式就显得比较麻烦了。
为了使程序编写更容易些,这里可以使用动画引擎来实现动画效果。和 three.js 紧密结合的动画引擎是 Tween.js 可以在 https://github.com/sole 下载

  • 引入引擎 js 文件:<script src="./js/tween.min.js"></script>
  • 构建一个 Tween 对象,对 Tween 进行初始化:
    function initTween() {
    	new TWEEN.Tween(mesh.position)
    		.to({x: -400}, 3000).repeat(Infinity).start();
    }
    
    • TWEEN.Tween 的构造函数接受的是要改变属性的对象,这里传入的是 mesh 的位置。Tween 的任何一个函数返回的都是自身,所以可以用串联的方式直接调用各个函数。
    • to 函数,接受两个参数,第一个参数是一个集合,里面存放的键值对,键 x 表示 mesh.position 的 x 属性,值 -400 表示,动画结束的时候需要移动到的位置。第二个参数,是完成动画需要的时间,这里是 3000ms。
    • repeat( Infinity )表示重复无穷次,也可以接受一个整形数值,表示限定重复次数。
    • Start 表示开始动画,默认情况下是匀速的将 mesh.position.x 移动到 -400 的位置。
  • 需要在渲染函数中不断的更新 Tween,这样才能够让 mesh.position.x 移动位置:
function animation() {
	renderer.render(scene,camera);
	requestAnimationFrame(animation);
	stats.update();
	TWEEN.update();	// 让动画动起来到达目标,如果不调用则场景就不会动。
}
(゚д゚)σ弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌⊃
评论
歌名 - 歌手
0:00