学习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分享者2 天前
学习threejs,scene.overrideMaterial全局材质效果
threejs·全局材质·overridemater
我码玄黄4 天前
在THREEJS中加载3dtile模型
前端·javascript·3d·threejs
gis分享者12 天前
学习threejs,加载天地图
threejs·加载天地图
踏实探索15 天前
Three.js教程_02场景、相机与渲染器全面解析
开发语言·javascript·数码相机·threejs
gis分享者16 天前
学习threejs,实现配合使用WebWorker
多线程·threejs·webworker
AllBlue16 天前
threejs相机辅助对象cameraHelper
threejs
gis分享者19 天前
学习threejs,使用VideoTexture实现视频Video更新纹理
threejs·视频贴图·videotexture
gis分享者20 天前
学习threejs,通过设置纹理属性来修改纹理贴图的位置和大小
threejs·纹理贴图·位置和大小
gis分享者24 天前
学习threejs,使用设置normalMap法向量贴图创建更加细致的凹凸和褶皱
threejs·normalmap·法向量贴图
gis分享者24 天前
学习threejs,使用CubeCamera相机创建反光效果
threejs·cubecamera·立方体相机·反光效果