分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 运营维护

webgl之3d动画

发布时间:2023-09-06 01:49责任编辑:赖小花关键词:动画

  之前的几篇文章都是静态的,而这里主要介绍如何使物体动起来,并且学会使用性能监视器来监测性能。

  而如果要让物体动起来,实际上我们是有两种方法的,第一种是让物体真的动起来,另外一种是让摄像机动起来这样物体相对来说也就动起来了。另外,实际上在让物体动起来的过程中,我们是不断通过调用 renderer.render(scene, camera)这个函数实现的,那么怎么才能不断调用这个函数呢?这就需要用到 requestAnimationFrame函数了,这个函数接受一个函数作为参数,并且会在每秒内调用60次,那么最终屏幕就会在一秒内渲染60次,这样就可以形成动画了。

一、物体做绝对运动

  首先,我们先让物体动起来,如下所示,就是一个让物体运动起来的动画:

<!DOCTYPE html><html lang="en"><head> ???<meta charset="UTF-8"> ???<title>three.js</title> ???<style> ???????* { ???????????margin: 0; ???????????padding: 0; ???????} ???</style> ???<script src="./three.js"></script></head><body> ???<script> ???????var scene = new THREE.Scene(); ???????var axes = new THREE.AxesHelper(1000); ???????scene.add(axes); ???????var camera = new THREE.PerspectiveCamera(50, window.innerWidth/window.innerHeight, 1, 1000); ???????camera.position.x = 300; ???????camera.position.y = 300; ???????camera.position.z = 300; ???????camera.up.x = 0; ???????camera.up.y = 0; ???????camera.up.z = 1; // camera.up.z = 1, 所以渲染出来的结果是z轴朝上。 ???????camera.lookAt(scene.position); ???????var renderer = new THREE.WebGLRenderer(); ???????renderer.setClearColor(0x111111); ???????renderer.setSize(window.innerWidth, window.innerHeight); ???????var cubeGeometry = new THREE.CubeGeometry(10, 10, 10); ????????var meshCube = new THREE.MeshBasicMaterial({color: 0xff0000}); ???????var cube = new THREE.Mesh(cubeGeometry, meshCube); ???????cube.position.x = 0; ???????cube.position.y = 0; ???????cube.position.z = 0; ???????scene.add(cube); ???????document.body.append(renderer.domElement); ???????var isDestination = false; ???????function animation() { ???????????var interval = 5; ???????????if (!isDestination) { ???????????????cube.position.x = cube.position.x + interval; ???????????} else { ???????????????cube.position.x = cube.position.x - interval; ???????????} ???????????if (cube.position.x == 330) { ???????????????isDestination = true; ???????????} ???????????if (cube.position.x == 0) { ???????????????isDestination = false; ???????????} ???????????renderer.render(scene, camera); ???????????requestAnimationFrame(animation); ???????} ???????animation(); ???</script></body></html>

  即首先创建场景,然后创建坐标轴并加入到场景中,接着创建相机,注意相机所接受的参数比较多,且相机需要指定position位置以及up位置,且使用lookAt函数,接下来创建一个渲染器,指定背景颜色和宽、高,然后创建一个物体,最后需要将渲染器加入到document.body中,接着是一个动画,然后运行即可。但是,我们可以发现虽然上面代码完成了,但是封装的不好,我们可以尝试着将其用函数封装,如下:

<!DOCTYPE html><html lang="en"><head> ???<meta charset="UTF-8"> ???<title>three.js</title> ???<style> ???????* { ???????????margin: 0; ???????????padding: 0; ???????} ???</style> ???<script src="./three.js"></script></head><body> ???<script> ???????var scene; ???????function initScene() { ???????????scene = new THREE.Scene(); ???????????????????} ???????var axes; ???????function initAxes() { ???????????axes = new THREE.AxesHelper(1000); ???????????scene.add(axes); ???????} ???????var camera; ???????function initCamera() { ???????????camera = new THREE.PerspectiveCamera(50, window.innerWidth/window.innerHeight, 1, 1000); ???????????????????????camera.position.x = 300; ???????????camera.position.y = 300; ???????????camera.position.z = 300; ???????????????????????camera.up.x = 0; ???????????camera.up.y = 1; ???????????camera.up.z = 0; ???????????camera.lookAt(scene.position); ???????} ???????var renderer; ???????function initRenderer() { ???????????renderer = new THREE.WebGLRenderer(); ???????????renderer.setSize(window.innerWidth, window.innerHeight); ???????????renderer.setClearColor(0x111111); ???????????document.body.append(renderer.domElement); ???????} ???????var cube; ???????function initObject() { ???????????var cubeGeometry = new THREE.CubeGeometry(10, 10, 10); ????????????var meshCube = new THREE.MeshBasicMaterial({color: 0xff0000}); ???????????cube = new THREE.Mesh(cubeGeometry, meshCube); ???????????cube.position.x = 0; ???????????cube.position.y = 0; ???????????cube.position.z = 0; ???????????scene.add(cube); ???????} ???????var isDestination = false; ???????function animation() { ???????????var interval = 5; ???????????var destination = 200; ???????????var direction = "y"; ???????????if (!isDestination) { ???????????????cube.position[direction] += interval; ???????????} else { ???????????????cube.position[direction] -= interval; ???????????} ???????????if (cube.position[direction] == destination) { ???????????????isDestination = true; ???????????} ???????????if (cube.position[direction] == 0) { ???????????????isDestination = false; ???????????} ???????????renderer.render(scene, camera); ???????????requestAnimationFrame(animation); ???????} ???????function threeStart() { ???????????initScene(); ???????????initAxes(); ???????????initCamera(); ???????????initRenderer(); ???????????initObject(); ???????????animation(); ???????} ???????threeStart(); ???</script></body></html>

  如上所示,通过函数封装,程序的逻辑性更好了一些,并且仅仅暴露了比如scene、camera、axes、renderer等必要的变量,而其他的变量不会对全局造成污染,而最后的animation函数,我们定义了direction为"x",这样就可以通过这里的修改控制cube运动的坐标轴了,这一点利用的就是JavaScript调用属性的特点。最后我们统一将初始化调用函数写在了threeStart中,这样,就可以通过threeStart函数调用开启这个项目了,最终得到的效果如下所示:

二、相机做绝对运动

如下所示:

<!DOCTYPE html><html lang="en"><head> ???<meta charset="UTF-8"> ???<title>three.js</title> ???<style> ???????* { ???????????margin: 0; ???????????padding: 0; ???????} ???</style> ???<script src="./three.js"></script></head><body> ???<script> ???????var scene; ???????function initScene() { ???????????scene = new THREE.Scene(); ???????????????????} ???????var axes; ???????function initAxes() { ???????????axes = new THREE.AxesHelper(1000); ???????????scene.add(axes); ???????} ???????var camera; ???????function initCamera() { ???????????camera = new THREE.PerspectiveCamera(50, window.innerWidth/window.innerHeight, 1, 1000); ???????????????????????camera.position.x = 300; ???????????camera.position.y = 300; ???????????camera.position.z = 300; ???????????????????????camera.up.x = 0; ???????????camera.up.y = 1; ???????????camera.up.z = 0; ???????????camera.lookAt(scene.position); ???????} ???????var renderer; ???????function initRenderer() { ???????????renderer = new THREE.WebGLRenderer(); ???????????renderer.setSize(window.innerWidth, window.innerHeight); ???????????renderer.setClearColor(0x111111); ???????????document.body.append(renderer.domElement); ???????} ???????var cube; ???????function initObject() { ???????????var cubeGeometry = new THREE.CubeGeometry(10, 10, 10); ????????????var meshCube = new THREE.MeshBasicMaterial({color: 0xff0000}); ???????????cube = new THREE.Mesh(cubeGeometry, meshCube); ???????????cube.position.x = 0; ???????????cube.position.y = 0; ???????????cube.position.z = 0; ???????????scene.add(cube); ???????} ???????var isDestination = false; ???????function animation() { ???????????var interval = 1; ???????????if (!isDestination) { ???????????????camera.position.x -= interval; ???????????????camera.position.y -= interval; ???????????????camera.position.z -= interval; ???????????} else { ???????????????camera.position.x += interval; ???????????????camera.position.y += interval; ???????????????camera.position.z += interval; ??????????????} ???????????if (camera.position.x == 50) { ???????????????isDestination = true; ???????????????????????????} ???????????if (camera.position.x == 300) { ???????????????isDestination = false; ???????????} ???????????renderer.render(scene, camera); ???????????requestAnimationFrame(animation); ???????} ???????function threeStart() { ???????????initScene(); ???????????initAxes(); ???????????initCamera(); ???????????initRenderer(); ???????????initObject(); ???????????animation(); ???????} ???????threeStart(); ???</script></body></html>

这里的思路也非常简单,就是给camera做了一个动画,效果如下所示:

ok,到这里,我们就了解了使得场景运动起来的两种方法,但是,我们应该如何监测他们的性能呢,下面来说一说。

三、性能评估

  

webgl之3d动画

原文地址:https://www.cnblogs.com/zhuzhenwei918/p/8855164.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved