核心提示:简介顾名思义,通过第一视角控制器你可以像第一视角射击游戏那样控制摄像机。鼠标用于控制视角,键盘用于控制移动角色。本人感觉最类似的效果就是cs游戏死亡后,能够随意漂浮的感觉。案例实现首先,引入相关库文件...
简介
顾名思义,通过第一视角控制器你可以像第一视角射击游戏那样控制摄像机。鼠标用于控制视角,键盘用于控制移动角色。本人感觉最类似的效果就是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>