学习threejs,使用第一视角控制器FirstPersonControls控制相机

👨‍⚕️ 主页: gis分享者

👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅!

👨‍⚕️ 收录于专栏:threejs gis工程师


文章目录


一、🍀前言

本文详细介绍如何基于threejs在三维场景中使用第一视角控制器FirstPersonControls控制相机,实现游戏第一人称效果,亲测可用。希望能帮助到您。一起学习,加油!加油!

1.1 ☘️第一视角控制器FirstPersonControls控制相机

THREE.FirstPersonControls 是 Three.js 的第一视角控制器,允许用户以第一人称视角进行三维场景的浏览、漫游。使用这个控制器时,用户可以通过鼠标或键盘来控制视角。
相关操控方法:

移动鼠标 向四周看

上、下、左、右方向键 向上、下、左、右移动

W 向前移动

A 向左移动

S 向后移动

D 向右移动

R 向上移动

F 向下移动

Q 停止移动
创建方法:

new THREE.FirstPersonControls(camera)

参数camera 为Threejs的相机对象
属性:

方法:

handleResize () : undefined 若应用程序窗口大小发生改变,则应当调用此函数。

lookAt ( vector : Vector3 ) : FirstPersonControls vector - 一个表示目标位置的向量。 或者,世界空间位置的x、y、z分量。 确保控制器将相机方向朝向到所传入的目标的位置。

lookAt ( x : Float, y : Float, z : Float ) : FirstPersonControls vector - 一个表示目标位置的向量。 或者,世界空间位置的x、y、z分量。 确保控制器将相机方向朝向到所传入的目标的位置。

二、🍀利用THREE.FirstPersonControls实现第一视角控制

1. ☘️实现思路

  • 1、初始化renderer渲染器
  • 2、初始化Scene三维场景
  • 3、初始化camera相机,定义相机位置 camera.position.set,设置相机方向camera.lookAt。
  • 4、初始化THREE.AmbientLight环境光源,scene场景加入环境光源,初始化THREE.PointLight点光源,设置点光源位置,设置点光源投影,scene添加点光源。
  • 5、加载几何模型:创建THREE.AxesHelper坐标辅助工具,创建THREE.MTLLoader加载器,调用load方法获取模型材质信息,在MTLLoader的load方法中创建THREE.OBJLoader obj模型加载器,OBJLoader 加载器设置材质为从MTLLoader获取的材质,调用OBJLoader的load方法,加载模型, 生成mesh物体,scene场景加入mesh和THREE.AxesHelper坐标辅助工具。
  • 6、创建第一视角控制器FirstPersonControls,设置控制器相关参数。加入stats监控器,监控帧数信息。

2. ☘️代码样例

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>learn44(使用第一视角控制器FIRSTPERSONCONTROLS控制相机)</title>
    <script src="lib/threejs/127/three.js-master/build/three.js"></script>
    <script src="lib/js/Detector.js"></script>
    <script src="lib/js/chroma.js"></script>
    <script src="lib/threejs/127/three.js-master/examples/js/loaders/OBJLoader.js"></script>
    <script src="lib/threejs/127/three.js-master/examples/js/loaders/MTLLoader.js"></script>
    <script src="lib/threejs/127/three.js-master/examples/js/controls/FirstPersonControls.js"></script>
    <script src="lib/threejs/127/three.js-master/examples/js/libs/stats.min.js"></script>
    <script src="lib/threejs/127/three.js-master/examples/js/libs/dat.gui.min.js"></script>
</head>
<style>
    html, body {
        margin: 0;
        height: 100%;
    }

    canvas {
        display: block;
    }
</style>
<body onload="draw()">
</body>
<script>
  var renderer
  var initRender = () => {
    renderer = new THREE.WebGLRenderer({antialias: true})
    renderer.setSize(window.innerWidth, window.innerHeight)
    renderer.sortObjects = false
    document.body.appendChild(renderer.domElement)
  }
  var camera
  var 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
  var initScene = () => {
    scene = new THREE.Scene()
  }
  var light
  var initLight = () => {
    scene.add(new THREE.AmbientLight)

    light = new THREE.PointLight(0xffffff)
    light.position.set(0, 50, 0)
    light.castShadow = true
    scene.add(light)
  }
  var initModel = () => {
    var helper = new THREE.AxesHelper(50)
    scene.add(helper)

    var mtlLoader = new THREE.MTLLoader()
    mtlLoader.setPath('data/model/city/')
    mtlLoader.load('city.mtl', material => {
      var objLoader = new THREE.OBJLoader()
      objLoader.setMaterials(material)
      objLoader.setPath('data/model/city/')
      objLoader.load('city.obj', object => {
        var scale = chroma.scale(['yellow', '008ae5'])
        setRandomColors(object, scale)
        scene.add(object)
      })
    })
  }
  var 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
  var initStats = () => {
    stats = new Stats()
    document.body.appendChild(stats.dom)
  }
  var controls
  var 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轴的角度
  }
  var render = () => {
    renderer.render(scene, camera)
  }
  var onWindowResize = () => {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    render()
    renderer.setSize(window.innerWidth, window.innerHeight)
  }
  var clock = new THREE.Clock()
  var animate = () => {
    render()
    stats.update()
    controls.update(clock.getDelta())
    requestAnimationFrame(animate)
  }
  var draw = () => {
    initRender()
    initScene()
    initCamera()
    initLight()
    initModel()
    initStats()
    initControls()

    animate()

    window.onresize = onWindowResize
  }
</script>
</html>

效果如下:

相关推荐
gis分享者20 小时前
学习threejs,使用PointLight点光源
threejs·点光源·pointlight
gis分享者5 天前
学习threejs,使用HemisphereLight半球光
threejs·hemispherelight·半球光
gis分享者9 天前
学习threejs,使用Lensflare模拟镜头眩光
threejs·lensflare·眩光
gis分享者12 天前
学习threejs,tga格式图片文件贴图
threejs·贴图·tga·tgaloader
gis分享者13 天前
学习threejs,pvr格式图片文件贴图
threejs·贴图·pvr
gis分享者1 个月前
学习threejs,使用OrbitControls相机控制器
threejs·相机·相机控制器·orbitcontrols
不系舟1781 个月前
threejs 实现镜面反射,只反射指定物体,背景透明
threejs
gis分享者1 个月前
学习threejs,使用RollControls相机控制器
threejs·相机控制器·rollcontrols
gis分享者1 个月前
学习threejs,使用FlyControls相机控制器
threejs·相机控制器·flycontrols
gis分享者1 个月前
学习threejs,使用TrackballControls相机控制器
threejs·trackball·相机控制器