码迷,mamicode.com
首页 > Web开发 > 详细

webgl之3d动画

时间:2018-04-16 13:07:49      阅读:238      评论:0      收藏:0      [点我收藏+]

标签:camera   asi   pre   alt   margin   har   anim   技术分享   char   

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

  而如果要让物体动起来,实际上我们是有两种方法的,第一种是让物体真的动起来,另外一种是让摄像机动起来这样物体相对来说也就动起来了。另外,实际上在让物体动起来的过程中,我们是不断通过调用 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动画

标签:camera   asi   pre   alt   margin   har   anim   技术分享   char   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!