Three.JS学习 4:循环渲染与动画
来源:互联网 发布:程序员刚入职任务不会 编辑:程序博客网 时间:2024/05/16 05:32
本文学习内容来源:
http://www.hewebgl.com/article/getarticle/58
渲染
renderer.render(scence,camera);
当改变了物体的属性时,需要重新调用render()函数,浏览器才会自动刷新场景。
为了循环渲染,要使用requestAnimationFrame函数,传递一个callback参数。
function animate(){ render(); requestAnimationFrame(animate);}
移动摄像机让物体动起来
移动一个物体的源代码:
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>Three框架</title> <script src="js/three.min.js"></script> <style type="text/css"> div#canvas-frame { border: none; cursor: pointer; width: 100%; height: 600px; background-color: #EEEEEE; } </style> <script> var renderer,width,height; function initThree() { width = document.getElementById('canvas-frame').clientWidth; height = document.getElementById('canvas-frame').clientHeight; renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(width, height); document.getElementById('canvas-frame').appendChild(renderer.domElement); renderer.setClearColor(0xFFFFFF, 1.0); } var camera; function initCamera() { camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000); camera.position.x = 0; camera.position.y = 0; camera.position.z = 600; camera.up.x = 0; camera.up.y = 1; camera.up.z = 0; camera.lookAt({ x: 0, y: 0, z: 0 }); } var scene; function initScene() { scene = new THREE.Scene(); } var light; function initLight() { light = new THREE.AmbientLight(0xFFFFFF); light.position.set(100, 100, 200); scene.add(light); light = new THREE.PointLight(0x00FF00); light.position.set(0, 0, 300); scene.add(light); } function initObject() { var geometry = new THREE.CylinderGeometry(100, 150, 400); var material = new THREE.MeshLambertMaterial({ color: 0x33FF33 }); var mesh = new THREE.Mesh(geometry, material); mesh.position = new THREE.Vector3(0, 0, 0); scene.add(mesh); } function threeStart() { initThree(); initCamera(); initScene(); initLight(); initObject(); animation(); } function animation() { camera.position.x = camera.position.x + 1; if (camera.position.x > width-400) camera.position.x = 0; renderer.render(scene, camera); requestAnimationFrame(animation); } </script> </head> <body onload="threeStart();"> <div id="canvas-frame"></div> </body></html>
CylinderGeometry函数说明
- radiusTop: 柱体顶部半径
- radiusBottom:柱体底部半径
- height:柱体高度
- radiusSegments:圆周分段,数字越高柱体越圆滑
- heightSegments:高度分段,与上类似
- openEnded:是否显示顶盖和底板
- theraStart, thetaLength:暂不清楚
改变物体坐标,让物体动起来
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>Three框架</title> <script src="js/three.min.js"></script> <style type="text/css"> div#canvas-frame { border: none; cursor: pointer; width: 100%; height: 600px; background-color: #EEEEEE; } </style> <script> var renderer,width,height; function initThree() { width = document.getElementById('canvas-frame').clientWidth; height = document.getElementById('canvas-frame').clientHeight; renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(width, height); document.getElementById('canvas-frame').appendChild(renderer.domElement); renderer.setClearColor(0xFFFFFF, 1.0); } var camera; function initCamera() { camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000); camera.position.x = 0; camera.position.y = 0; camera.position.z = 600; camera.up.x = 0; camera.up.y = 1; camera.up.z = 0; camera.lookAt({ x: 0, y: 0, z: 0 }); } var scene; function initScene() { scene = new THREE.Scene(); } var light; function initLight() { light = new THREE.AmbientLight(0xFF0000); light.position.set(100, 100, 200); scene.add(light); light = new THREE.PointLight(0x00FF00); light.position.set(0, 0, 300); scene.add(light); } var mesh; //mesh就是要移动的物体 function initObject() { var geometry = new THREE.CylinderGeometry(100, 150, 400); var material = new THREE.MeshLambertMaterial({ color: 0xFFFFFF }); mesh = new THREE.Mesh(geometry, material); mesh.position = new THREE.Vector3(0, 0, 0); scene.add(mesh); } function threeStart() { initThree(); initCamera(); initScene(); initLight(); initObject(); animation(); } function animation() { mesh.position.x -= 1; console.log(mesh.position.x); if (mesh.position.x < -(width - 400)) mesh.position.x = 0; renderer.render(scene, camera); requestAnimationFrame(animation); } </script> </head> <body onload="threeStart();"> <div id="canvas-frame"></div> </body></html>
评估程序性能
帧数
定义:图形处理器每秒能刷新多少次
单位:fps(Frames Per Second)
当物体在快速运动时,当人眼所看到影像消失后,人眼仍能继续保留其影像1/24左右的图像,称为视觉暂留现象。一帧一帧的图像进入人脑,人脑将会将这些图像连接起来,形成动画。
帧数越高,画面感觉越流畅。大多数游戏FPS超过30.
添加性能监视器Stats
https://github.com/mrdoob/stats.js
可以看到Three.js的性能监视器。
性能监视器:
FPS监视器
FPS : 上一秒的帧数,越大越好,一般为60左右
点击它,会显示:
MS监视器
MS 表示渲染一帧需要的毫秒数,越小越好。
MB监视器
占用内存多少M字节。启动谷歌浏览器时,使用
--enable-precise-memory-info
CUSTOM监视器
支持用户自定义的panel
使用Stats
var stats = new Stats();stats.showPanel( 1 ); // 0: fps, 1: ms, 2: mb, 3+: customdocument.body.appendChild( stats.dom );function animate() { stats.begin(); // monitored code goes here stats.end(); requestAnimationFrame( animate );}requestAnimationFrame( animate );
完整示例代码:
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>Three框架</title> <script src="js/three.min.js"></script> <script src="js/stats.min.js"></script> <style type="text/css"> div#canvas-frame { border: none; cursor: pointer; width: 100%; height: 600px; background-color: #EEEEEE; } </style> <script> var renderer, width, height; var stats; function initThree() { width = document.getElementById('canvas-frame').clientWidth; height = document.getElementById('canvas-frame').clientHeight; renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(width, height); document.getElementById('canvas-frame').appendChild(renderer.domElement); renderer.setClearColor(0xFFFFFF, 1.0); stats = new Stats(); stats.showPanel(1); // 0: fps, 1: ms, 2: mb, 3+: custom document.body.appendChild(stats.dom); } var camera; function initCamera() { camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000); camera.position.x = 0; camera.position.y = 0; camera.position.z = 600; camera.up.x = 0; camera.up.y = 1; camera.up.z = 0; camera.lookAt({ x: 0, y: 0, z: 0 }); } var scene; function initScene() { scene = new THREE.Scene(); } var light; function initLight() { light = new THREE.AmbientLight(0xFF0000); light.position.set(100, 100, 200); scene.add(light); light = new THREE.PointLight(0x00FF00); light.position.set(0, 0, 300); scene.add(light); } var mesh; function initObject() { var geometry = new THREE.CylinderGeometry(100, 150, 400); var material = new THREE.MeshLambertMaterial({ color: 0xFFFFFF }); mesh = new THREE.Mesh(geometry, material); mesh.position = new THREE.Vector3(0, 0, 0); scene.add(mesh); } function threeStart() { initThree(); initCamera(); initScene(); initLight(); initObject(); animation(); } function animation() { stats.begin(); mesh.position.x -= 1; console.log(mesh.position.x); if (mesh.position.x < -(width - 400)) mesh.position.x = 0; renderer.render(scene, camera); stats.end(); requestAnimationFrame(animation); } </script> </head> <body onload="threeStart();"> <div id="canvas-frame"></div> </body></html>
结果:
上面代码里的stats.begin和stats.end可以再次封装:
function animation() { mesh.position.x -= 1; console.log(mesh.position.x); if (mesh.position.x < -(width - 400)) mesh.position.x = 0; renderer.render(scene, camera); requestAnimationFrame(animation); stats.update(); }
stats.update封装了stats.begin/stats.end
使用Tween.js创建动画
https://github.com/sole 下载库文件
使用方法:
构建Tween对象并初始化
function initTween(){ new TWEEN.Tween(mesh.position).to( { x: -400 }, 3000 ).repeat( Infinity ).start();}
构造函数:要改变的值。
to():接受两个参数,1:集合,存放键值对,x表示mesh.position的x属性, 2:完成动画需要的时间
repeat():重复几次,Infinity是无穷次
start():开始动画
实现动画
function animation(){ renderer.render(scene, camera); requestAnimationFrame(animation); stats.update(); TWEEN.update();}
完整示例:
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>Three框架</title> <script src="js/three.min.js"></script> <script src="js/stats.min.js"></script> <script src="js/Tween.js"></script> <style type="text/css"> div#canvas-frame { border: none; cursor: pointer; width: 100%; height: 600px; background-color: #EEEEEE; } </style> <script> var renderer, width, height; var stats; function initThree() { width = document.getElementById('canvas-frame').clientWidth; height = document.getElementById('canvas-frame').clientHeight; renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(width, height); document.getElementById('canvas-frame').appendChild(renderer.domElement); renderer.setClearColor(0xFFFFFF, 1.0); stats = new Stats(); stats.showPanel(1); // 0: fps, 1: ms, 2: mb, 3+: custom document.body.appendChild(stats.dom); } var camera; function initCamera() { camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000); camera.position.x = 0; camera.position.y = 0; camera.position.z = 600; camera.up.x = 0; camera.up.y = 1; camera.up.z = 0; camera.lookAt({ x: 0, y: 0, z: 0 }); } var scene; function initScene() { scene = new THREE.Scene(); } var light; function initLight() { light = new THREE.AmbientLight(0xFF0000); light.position.set(100, 100, 200); scene.add(light); light = new THREE.PointLight(0x00FF00); light.position.set(0, 0, 300); scene.add(light); } var mesh; function initObject() { var geometry = new THREE.CylinderGeometry(100, 150, 400); var material = new THREE.MeshLambertMaterial({ color: 0xFFFFFF }); mesh = new THREE.Mesh(geometry, material); mesh.position = new THREE.Vector3(0, 0, 0); scene.add(mesh); } function initTween() { new TWEEN.Tween(mesh.position).to({ x: -400 }, 3000).repeat(Infinity).start(); } function threeStart() { initThree(); initCamera(); initScene(); initLight(); initObject(); initTween(); animation(); } function animation() { renderer.render(scene, camera); requestAnimationFrame(animation); stats.update(); TWEEN.update(); } </script> </head> <body onload="threeStart();"> <div id="canvas-frame"></div> </body></html>
- Three.JS学习 4:循环渲染与动画
- Three.js之渲染器
- Three.js之渲染器
- three.js学习笔记 用Tween.js做动画
- three.js 动画效果01
- Three.js之渲染器(转)
- Three.JS提升学习1:创建场景并渲染三维对象
- three.js学习 函数使用方法散记4
- three.js学习
- three.js学习
- Three.js学习
- three.js 与 webGL
- Vue.js学习 Item7 -- 条件渲染与列表渲染
- Vue.js 学习6 条件渲染与列表渲染
- vue.js基础-声明式渲染和条件与循环
- vue.js基础-声明式渲染和条件与循环
- tween.js 用户指南 - 与 Three.js 配合使用的补间动画库
- vue.js 嵌套循环渲染
- b 【NOIP2017GDKOI模拟1.12】
- Android窗口机制(二)Window,PhoneWindow,DecorView,setContentView源码理解
- 选夫婿2
- 写io的几种模式
- 1004. Counting Leaves 解析
- Three.JS学习 4:循环渲染与动画
- 商人的诀窍
- es安装
- 从1....n中随机输出m个不重复的数
- 素数筛法
- opencv行人检测代码
- 实验室-PHP重构$_GET参数部分
- 老--质价比
- JUnit-4.11使用报java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing错误