Threejs之相机基础

参考资料

知识点

注:基于Three.jsv0.155.0

  • 正投影相机
  • 正投影相机-Canvas尺寸变化
  • 包围盒Box3
  • 地图案例(包围盒、正投影)
  • 相机动画(.position和.lookAt())
  • 不同方向的投影视图
  • 旋转渲染结果(.up相机上方向)
  • 管道漫游案例
  • OrbitControls旋转缩放限制
  • 相机控件MapControls

代码实现

javascript 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Three.js</title>
</head>
  <body>
  </body>
  <!-- 具体路径配置,你根据自己文件目录设置,我的是课件中源码形式 -->
  <script type="importmap">
    {
      "imports": {
        "three": "./js/three.module.js",
        "three/addons/": "../three.js/examples/jsm/"
      }
    }
  </script>
  <script type="module">
    import * as THREE from 'three';
    import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
    import { MapControls } from 'three/addons/controls/MapControls.js';

    const width = window.innerWidth
    const height = window.innerHeight

    // 场景
    const scene = new THREE.Scene();

    const data = [
      [110.3906, 34.585],
      [110.8301, 34.6289],
      [111.1816, 34.8047],
      [111.5332, 34.8486],
      [111.7969, 35.0684],
      [112.0605, 35.0684],
      [112.0605, 35.2881],
      [112.7637, 35.2002],
      [113.1152, 35.332],
      [113.6426, 35.6836],
      [113.7305, 36.3428],
      [114.873, 36.123],
      [114.9609, 36.0791],
      [115.1367, 36.2109],
      [115.3125, 36.0791],
      [115.4883, 36.167],
      [115.3125, 35.8154],
      [116.1035, 36.0791],
      [115.4883, 35.7275],
      [115.2246, 35.4199],
      [115.0488, 35.376],
      [114.7852, 35.0684],
      [115.4004, 34.8486],
      [115.5762, 34.585],
      [116.1914, 34.585],
      [116.1914, 34.4092],
      [116.543, 34.2773],
      [116.6309, 33.9258],
      [116.1914, 33.7061],
      [116.0156, 33.9697],
      [115.6641, 34.0576],
      [115.5762, 33.9258],
      [115.5762, 33.6621],
      [115.4004, 33.5303],
      [115.3125, 33.1787],
      [114.873, 33.1348],
      [114.873, 33.0029],
      [115.1367, 32.8711],
      [115.2246, 32.6074],
      [115.5762, 32.4316],
      [115.8398, 32.5195],
      [115.9277, 31.7725],
      [115.4883, 31.6846],
      [115.4004, 31.4209],
      [115.2246, 31.4209],
      [115.1367, 31.5967],
      [114.7852, 31.4648],
      [114.6094, 31.5527],
      [114.5215, 31.7725],
      [114.1699, 31.8604],
      [113.9941, 31.7725],
      [113.8184, 31.8604],
      [113.7305, 32.4316],
      [113.4668, 32.2998],
      [113.2031, 32.4316],
      [112.3242, 32.3438],
      [111.5332, 32.6074],
      [111.0059, 33.2666],
      [111.0059, 33.5303],
      [110.6543, 33.8379],
      [110.6543, 34.1455],
      [110.4785, 34.2334],
      [110.3906, 34.585]
  ]
    const pointsArr = [];// 一组二维向量表示一个多边形轮廓坐标
    data.forEach(function(e){
        // data坐标数据转化为Vector2构成的顶点数组
        const v2 = new THREE.Vector2(e[0],e[1])
        pointsArr.push(v2);
    })
    // Shape表示一个平面多边形轮廓,参数是二维向量构成的数组pointsArr
    const shape = new THREE.Shape(pointsArr);
    // 多边形shape轮廓作为ShapeGeometry参数,生成一个多边形平面几何体
    const geometry = new THREE.ShapeGeometry(shape);
    // 生成一个平面网格模型
    const mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
      color: '#0000ff',
      side: THREE.DoubleSide
    }))
    // 设置模型位置
    mesh.position.set(0, 0, 0);
    // 添加模型到场景
    scene.add(mesh);

    // 点光源
    const pointLight = new THREE.PointLight( 0xffffff, 1.0, 0, 0);
    pointLight.position.set(200, 200, 200 );
    scene.add( pointLight );
    
    // 环境光
    const ambientLight = new THREE.AmbientLight( 0xffffff, 1);
    scene.add( ambientLight );

    // 坐标系
    const axes = new THREE.AxesHelper(200);
    scene.add(axes);

    // 相机
    const s = 2.5;//控制left, right, top, bottom范围大小
    const k = width / height; //canvas画布宽高比
    const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 8000);
    // const camera = new THREE.PerspectiveCamera(75, width/height, 0.1, 3000);
    // camera.position.set(300, 300, 300); 
    // camera.lookAt(0, 0, 0); //指向坐标原点
    
    // 包围盒计算模型对象的大小和位置
    const box3 = new THREE.Box3();
    box3.expandByObject(mesh); // 计算模型包围盒
    const size = new THREE.Vector3();
    box3.getSize(size); // 计算包围盒尺寸
    console.log('模型包围盒尺寸',size);
    const center = new THREE.Vector3();
    box3.getCenter(center); // 计算包围盒中心坐标
    console.log('模型中心坐标1',center);

    const x = 113.51,y = 33.88;
    camera.position.set(x, y, 300);
    // 你可以看到模型相比原来上下颠倒  y坐标轴朝下
    camera.up.set(0,-1,0)
    camera.lookAt(x, y, 0);

    // 渲染器
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(width, height);
    renderer.render(scene, camera);
    document.body.appendChild(renderer.domElement);

    renderer.outputColorSpace = THREE.SRGBColorSpace;//设置为SRGB颜色空间

    // const controls = new OrbitControls(camera, renderer.domElement);
    // controls.target.set(x, y, 0); //与lookAt参数保持一致
    // controls.update();//update()函数内会执行camera.lookAt(controls.target)
    // // 左右旋转范围
    // controls.minAzimuthAngle = -Math.PI/2;
    // controls.maxAzimuthAngle = Math.PI/2;
    // // Vector3 {x: -49.803731395661714, y: 146.90160246353028, z: 35.47368304973255}
    // // Vector3 {x: -11.970638355445846, y: -51.0801205834488, z: 0.7429414745816755}
    // // 渲染循环
    // let angle = 0; //用于圆周运动计算的角度值
    // const R = 100; //相机圆周运动的半径
    // function render() {
    //     angle += 0.01;
    //     // 相机y坐标不变,在XOZ平面上做圆周运动
    //     camera.position.x = R * Math.cos(angle);
    //     camera.position.z = R * Math.sin(angle);
    //     renderer.render(scene, camera);
    //     camera.lookAt(0,0,0);
    //     // console.log('🚀 ~ file: 6.加载外部三维模型.html:70 ~ render ~ camera:', camera.position) // 鼠标左键改变相机位置
    //     // console.log('🚀 ~ file: 6.加载外部三维模型.html:66 ~ controls:', controls.target) // 鼠标右键改变相机观察点
    //     requestAnimationFrame(render);
    // }
    // // render();

    // 控制器

    // controls.addEventListener('change', () => {
    //   // 因为动画渲染了,所以这里可以省略
    //   renderer.render(scene, camera);
    // });

    const controls = new MapControls(camera, renderer.domElement);
    controls.addEventListener('change', function () {
      // 鼠标右键旋转时候,查看.position变化
      // 鼠标左键拖动的时候,查看.position、.target的位置会变化
      console.log('camera.position',camera.position);
      console.log('controls.target',controls.target);
    });
  </script>
</html>
相关推荐
gis分享者13 小时前
学习threejs,PerspectiveCamera透视相机和OrthographicCamera正交相机对比
threejs·透视相机·正交相机
gis分享者4 天前
学习threejs,scene.overrideMaterial全局材质效果
threejs·全局材质·overridemater
我码玄黄5 天前
在THREEJS中加载3dtile模型
前端·javascript·3d·threejs
gis分享者13 天前
学习threejs,加载天地图
threejs·加载天地图
踏实探索16 天前
Three.js教程_02场景、相机与渲染器全面解析
开发语言·javascript·数码相机·threejs
gis分享者17 天前
学习threejs,实现配合使用WebWorker
多线程·threejs·webworker
AllBlue17 天前
threejs相机辅助对象cameraHelper
threejs
gis分享者20 天前
学习threejs,使用VideoTexture实现视频Video更新纹理
threejs·视频贴图·videotexture
gis分享者21 天前
学习threejs,通过设置纹理属性来修改纹理贴图的位置和大小
threejs·纹理贴图·位置和大小
gis分享者25 天前
学习threejs,使用设置normalMap法向量贴图创建更加细致的凹凸和褶皱
threejs·normalmap·法向量贴图