当前位置: 移动技术网 > IT编程>网页制作>CSS > Three.js使用第一视角控制器FirstPersonControls控制相机(代码教程)

Three.js使用第一视角控制器FirstPersonControls控制相机(代码教程)

2019年06月02日  | 移动技术网IT编程  | 我要评论

遵义在线读者留言板,激战柏林,32423

简介

顾名思义,通过第一视角控制器你可以像第一视角射击游戏那样控制摄像机。鼠标用于控制视角,键盘用于控制移动角色。本人感觉最类似的效果就是cs游戏死亡后,能够随意漂浮的感觉。

案例实现

这里写图片描述

首先,引入相关库文件,其中,我们额外引入了一个处理颜色的库叫chroma.js库。在这里,就不详细介绍这个库了,如果需要相关内容,请查看其官方文档:https://gka.github.io/chroma.js/#color-rgba

<script src="/lib/libs/chroma.js"></script> 
<script src="/lib/js/controls/firstpersoncontrols.js"></script>

其次,就是在实例化相机以后,通过camera实例化相关对象,然后进行相关配置:

controls = new three.firstpersoncontrols(camera);
controls.lookspeed = 0.2; //鼠标移动查看的速度
controls.movementspeed = 20; //相机移动速度
controls.nofly = true;
controls.constrainvertical = true; //约束垂直
controls.verticalmin = 1.0;
controls.verticalmax = 2.0;
controls.lon = -100; //进入初始视角x轴的角度
controls.lat = 0; //初始视角进入后y轴的角度

最后,需要在每次渲染里面更新控制器:

var clock = new three.clock();

function animate() {
    render();

    //更新性能插件
    stats.update();

    //更新控制器
    controls.update(clock.getdelta());

    requestanimationframe(animate);
}

该控件的相关控制方法:

操控 效果
移动鼠标 向四周看
上、下、左、右方向键 向上、下、左、右移动
w 向前移动
a 向左移动
s 向后移动
d 向右移动
r 向上移动
f 向下移动
q 停止移动

案例代码

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>title</title>
    <style type="text/css">
        html, body {
            margin: 0;
            height: 100%;
        }

        canvas {
            display: block;
        }

    </style>
</head>

<body onload="draw();">

</body>
<script src="/lib/three.js"></script>
<script src="/lib/js/loaders/objloader.js"></script>
<script src="/lib/js/loaders/mtlloader.js"></script>
<script src="/lib/libs/chroma.js"></script> <!--处理颜色的库-->
<script src="/lib/js/controls/firstpersoncontrols.js"></script>
<script src="/lib/js/libs/stats.min.js"></script>
<script src="/lib/js/libs/dat.gui.min.js"></script>
<script src="/lib/js/detector.js"></script>

<script>
    var renderer;
    function initrender() {
        renderer = new three.webglrenderer({antialias:true});
        renderer.setsize(window.innerwidth, window.innerheight);
        renderer.sortobjects = false;
        //告诉渲染器需要阴影效果
        document.body.appendchild(renderer.domelement);
    }

    var camera;
    function initcamera() {
        camera = new three.perspectivecamera(45, window.innerwidth/window.innerheight, 0.1, 10000);
        camera.position.set(0, 10, 50);
        camera.lookat(new three.vector3(0,0,0));
    }

    var scene;
    function initscene() {
        scene = new three.scene();
    }

    //初始化dat.gui简化试验流程
    var gui;
    function initgui() {
        //声明一个保存需求修改的相关数据的对象
        gui = {
        };
        var datgui = new dat.gui();
        //将设置属性添加到gui当中,gui.add(对象,属性,最小值,最大值)
    }

    var light;
    function initlight() {
        scene.add(new three.ambientlight(0x444444));

        light = new three.pointlight(0xffffff);
        light.position.set(0,50,0);

        //告诉平行光需要开启阴影投射
        light.castshadow = true;

        scene.add(light);
    }

    function initmodel() {

        //辅助工具
        var helper = new three.axeshelper(50);
        scene.add(helper);

        var mtlloader = new three.mtlloader();
        mtlloader.setpath('/lib/assets/models/');
        //加载mtl文件
        mtlloader.load('city.mtl', function (material) {
            var objloader = new three.objloader();
            //设置当前加载的纹理
            objloader.setmaterials(material);
            objloader.setpath('/lib/assets/models/');
            objloader.load('city.obj', function (object) {
                //设置颜色的取值范围
                var scale = chroma.scale(['yellow', '008ae5']);

                console.log(object);

                //重新设置纹理颜色
                setrandomcolors(object, scale);

                //将模型缩放并添加到场景当中
                scene.add(object);
            })
        });
    }

    //添加纹理的方法
    function setrandomcolors(object, scale) {
        //获取children数组
        var children = object.children;

        //如果当前模型有子元素,则遍历子元素
        if (children && children.length > 0) {
            children.foreach(function (e) {
                setrandomcolors(e, scale)
            });
        }
        else {
            if (object instanceof three.mesh) {
                //如果当前的模型是楼层,则设置固定的颜色,并且透明化
                if(array.isarray(object.material)){
                    for(var i = 0; i<object.material.length; i++){
                        var material = object.material[i];
                        var color = scale(math.random()).hex();
                        if (material.name.indexof("building") === 0) {
                            material.color = new three.color(color);
                            material.transparent = true;
                            material.opacity = 0.7;
                            material.depthwrite = false;
                        }
                    }
                }
                // 如果不是场景组,则给当前mesh添加纹理
                else{
                    //随机当前模型的颜色
                    object.material.color = new three.color(scale(math.random()).hex());
                }
            }
        }
    }

    //初始化性能插件
    var stats;
    function initstats() {
        stats = new stats();
        document.body.appendchild(stats.dom);
    }

    var controls;
    function initcontrols() {

        controls = new three.firstpersoncontrols(camera);
        controls.lookspeed = 0.2; //鼠标移动查看的速度
        controls.movementspeed = 20; //相机移动速度
        controls.nofly = true;
        controls.constrainvertical = true; //约束垂直
        controls.verticalmin = 1.0;
        controls.verticalmax = 2.0;
        controls.lon = -100; //进入初始视角x轴的角度
        controls.lat = 0; //初始视角进入后y轴的角度
    }

    function render() {

        renderer.clear();
        renderer.render( scene, camera );
    }

    //窗口变动触发的函数
    function onwindowresize() {

        camera.aspect = window.innerwidth / window.innerheight;
        camera.updateprojectionmatrix();
        render();
        renderer.setsize( window.innerwidth, window.innerheight );

    }

    var clock = new three.clock();

    function animate() {
        //更新控制器
        render();

        //更新性能插件
        stats.update();

        controls.update(clock.getdelta());

        requestanimationframe(animate);
    }

    function draw() {
        //兼容性判断
        if ( ! detector.webgl ) detector.addgetwebglmessage();

        initgui();
        initrender();
        initscene();
        initcamera();
        initlight();
        initmodel();
        initcontrols();
        initstats();

        animate();
        window.onresize = onwindowresize;
    }
</script>
</html>

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网