美文网首页
threejs 自学 关于摄像机的使用

threejs 自学 关于摄像机的使用

作者: squidbrother | 来源:发表于2023-03-29 18:03 被阅读0次

摄像机运动的理解

观察一个模型的方式

  1. 保持摄像机不变情况下,通过修改被观察模型的旋转角度、位置、大小,来实现;
  2. 旋转摄像机的情况下,通过轨道控制器Orbit controls,实现摄像机的变化
  3. 不借助于轨道控制器,通过脚本来旋转摄像机 - (更加灵活,最重要一点,不需要人为操作)

基本使用

  1. 三维图查看角度
  • x轴方向观察
// 通过UI按钮改变相机观察角度
document.getElementById('x').addEventListener('click', function () {
    camera.position.set(500, 0, 0); //x轴方向观察
    camera.lookAt(0, 0, 0); //重新计算相机视线方向
})
  • y轴方向观察
// 通过UI按钮改变相机观察角度
document.getElementById('y').addEventListener('click', function () {
    camera.position.set(0, 500, 0); //y轴方向观察
    camera.lookAt(0, 0, 0); //重新计算相机视线方向
})
  • z轴方向观察
// 通过UI按钮改变相机观察角度
document.getElementById('z').addEventListener('click', function () {
    camera.position.set(0, 0, 500); //z轴方向观察
    camera.lookAt(0, 0, 0); //重新计算相机视线方向
})
  1. lookAt()的作用
    改变.position属性后,如果不执行.lookAt()方法,相机的观察方向默认不变
    如果你希望相机圆周运动的同时,改变相机视线方向,保持相机镜头始终指向坐标原点或其它位置,需要每次改变.position属性后,重新执行一遍.lookAt()方法
function render() {
    angle += 0.01;
    camera.position.x = R * Math.cos(angle);
    camera.position.z = R * Math.sin(angle);
    // .position改变,重新执行lookAt(0,0,0)计算相机视线方向
    camera.lookAt(0,0,0);
    requestAnimationFrame(render);
}
render();
  1. 镜头的基本运动
    模拟 贯穿 整个街道的镜头效果
    模拟 望远镜放大缩小( 最好使用目标与摄像机的距离,作为边界显示 )
// 渲染循环
function render() {
    camera.position.z -= 0.3; //-- 相机逐步向canvas画布内移动(如果目标的z值 比摄像机的z值 小的话)
    renderer.render(scene, camera);
    requestAnimationFrame(render);
}
render();
// 渲染循环
function render() {
    camera.position.z += 0.3; //-- 相机逐步向canvas画布外移动(如果目标的z值 比摄像机的z值 大的话)
    renderer.render(scene, camera);
    requestAnimationFrame(render);
}
render();

实际使用

  1. 操控摄像机围绕模型旋转
  • 参考案例链接: https://threejs.org/examples/webgl_interactive_cubes.html
let theta = 0;
init();
animate();
function init(){
  let camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
}
function animate(){
  requestAnimationFrame( animate );
  render();
}
function render(){
  theta += 0.1;
  camera.position.x = radius * Math.sin( THREE.MathUtils.degToRad( theta ) );
  camera.position.y = radius * Math.sin( THREE.MathUtils.degToRad( theta ) );
  camera.position.z = radius * Math.cos( THREE.MathUtils.degToRad( theta ) );
  camera.lookAt( scene.position );
  camera.updateMatrixWorld();
}
  1. 将移动镜头封装为一个函数,并且增加缓动效果
  • 参考案例链接: https://dragonir.github.io/3d/#/shadow - 光、模型与摄像机
import { TWEEN } from 'three/examples/jsm/libs/tween.module.min.js';
...
function animateCamera(position, rotation) {
  //相机 - 位置动画
  new TWEEN.Tween(camera.position)
    .to(position, 1800)
    .easing(TWEEN.Easing.Quadratic.InOut)
    .start()
    .onComplete(function () {
      TWEEN.remove(this)
    })
  //相机 - 旋转动画
  new TWEEN.Tween(camera.rotation)
    .to(rotation, 1800)
    .easing(TWEEN.Easing.Quadratic.InOut)
    .start()
    .onComplete(function () {
      TWEEN.remove(this)
    })
}

// 点击第一Tab菜单
document.getElementById('one').addEventListener('click', () => {
  document.getElementById('one').classList.add('active');
  document.getElementById('two').classList.remove('active')
  document.getElementById('content').innerHTML = 一段文字'
  animateCamera({ x: 3.2, y: 2.8, z: 3.2 }, { y: 1 });
});
  1. 摄像机沿着指定轨迹漫游
    示例地址 - http://www.webgl3d.cn/pages/188907/

  2. 操作摄像机与模型互动,如 开门进入车内动画

  • 操作摄像机移动到指定位置
    示例地址 - https://juejin.cn/post/7028780379649605646
    代码片段
  1. 当小人模型移动到某个指定区域范围时候,修改摄像机的位置以及朝向
//-- 检测修改摄像机位置函数
function checkChangeCameraFn(roleObject){
    //-- 当前摄像机的位置
    var camPos = new THREE.Vector3(
      camera.position.x,
      camera.position.y,
      camera.position.z
    );

    //-- 目标摄像机的位置
    var targetPos;
    
    //-- 角色进入指定范围
    if ( rolePosition.position.x > -3 && rolePosition.position.x < 22 && rolePosition.position.z > 31 && roleObject.position.z < 58 ) {
      targetPos = new THREE.Vector3(
        roleObject.position.x,
        roleObject.position.y + 50,
        roleObject.position.z + 40
      );
    }else{
        //-- 角色不在指定范围内,摄像机位置回到之前与角色关系位置
        targetPos = new THREE.Vector3(
          roleObject.position.x,
          roleObject.position.y + 30,
          roleObject.position.z + 60
        );
    }
    
    //-- 通过Vector3的lerp方法,实现当前位置与目标位置的缓动动画
    camPos.lerp(targetPos, 0.033);
    //-- 修改摄像机的位置以及朝向
    camera.position.copy(camPos);
    camera.lookAt(ballPosition.position);
}
animate();
function animate(){
    requestAnimationFrame( animate );
    ...
    //-- 摄像机位置朝向改变
    checkChangeCameraFn(小人模型对象);
    renderer.render( scene, camera );
}
  1. 模型沿着指定轨迹行驶,渲染时候切换三个摄像机镜头 -- (既有轨迹运动也有镜头切换,推荐!)
  • 添加若干相机,如全局相机,模型相机,被模型盯住模型上的相机,切换相机来显示
  • 沿着指定轨迹行驶
    原贴地址 - https://juejin.cn/post/7061203887536996360
    效果图

OrbitControls轨道控制器 与 摄像机的关系

  • 说明:
    OrbitControls轨道控制器,是一个threejs的非核心库,无需安装,只要显示引入js文件即可

执行构造函数THREE.OrbitControls()浏览器会同时干两件事,
给浏览器定义了一个鼠标、键盘事件,自动检测鼠标键盘的变化,如果变化了就会自动更新相机的数据, 执行该构造函数同时会返回一个对象
给该对象添加一个监听事件,只要鼠标或键盘发生了变化,就会触发渲染函数

作者:3D建模学习
链接:https://juejin.cn/post/7221777883160510525
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 轨道控制器与摄像机的关系
    ※ OrbitControls.target属性对应目标 等同于 camera.lookAt()的观察目标
    ※ OrbitControls.update(); 等同于 相机控件内部会执行 camera.lookAt(controls.target);
    ※ 对于透视投影相机而言,OrbitControls缩放,本质上就是改变camera.position
轨道控制器与摄像机的关系 轨道控制器与摄像机的关系2
  • 轨道控制器常用属性和方法
controls.enablePan = false; //禁止右键拖拽
controls.enableRotate = false; //禁止旋转
controls.enableZoom = false;//禁止缩放
controls.minDistance = 200; //相机位置与观察目标点最小值
controls.maxDistance = 500; //相机位置与观察目标点最大值
controls.getDistance(); //计算出camera.position和controls.target的距离
  • 限制摄像机的旋转范围
    默认上下旋转范围:
// 上下旋转范围
controls.minPolarAngle = 0; //-- 默认值0
controls.maxPolarAngle = Math.PI; //-- 默认值Math.PI

限制不能看到模型底部

controls.maxPolarAngle = Math.PI/2;

限制左右范围 - 如: 前方180度内

controls.minAzimuthAngle = -Math.PI/2;
controls.maxAzimuthAngle = Math.PI/2;
  • 借助轨道控制器查看摄像机的位置变化
orbitControl.addEventListener( 'change', function () {

    //相机位置与目标观察点距离
    // const pos = camera.position;
    // console.log( 'pos', pos );
    // const dis = orbitControl.getDistance();
    // console.log( 'dis', dis );

} );

未完待续.....

相关文章

  • threejs绘制中文方案

    1. 使用threejs创建文字几何体 使用threejs自带的helvetiker_bold.typeface字...

  • 微信小程序ThreeJs加载3D模型

    微信小程序使用ThreeJs需要使用官方库threejs-miniprogram[https://github.c...

  • 【ThreeJs】06 - 纹理

    项目搭建小提示 创建vue项目 安装ThreeJs 导入ThreeJs到组件中可以使用全部到如之后使用 自定义名称...

  • 关于一次数据渲染 WebGLRenderer renderBuf

    关于threejs threejs是webgl的封装库,提供了方便用户调用调用的接口和函数,涉及几何模型生产,用户...

  • threejs 详解(一)

    1. 开始 1.1 开使用threejs写一个最简洁的demo 1.2 threejs常用对象或对象属性 1.2...

  • 场景

    场景是threejs中所有object 元素盛放的容器,场景并没有多余复杂的操作,只需要在每次使用threejs构...

  • Venus: ThreeJS FBXLoader

    01.关于3D文件格式的选择 threejs提供了很多格式的 Loader但是却只提供了 obj 格式的使用文档,...

  • 怎样选择教育EPTZ自动跟踪摄像机4K摄像机

    怎样选择教育EPTZ自动跟踪摄像机4K摄像机 1080P摄像机广泛使用,在医学、会议、教学中常有会议云台摄像机使用...

  • ThreeJs简单使用

    Three.js 是一款运行在浏览器中的 3D 引擎,你可以用它在 web 中创建各种三维场景,包括了摄影机、光影...

  • Threejs 在加载模型和材质遇到的坑

    今天在使用 Vue 和 Threejs 结合的项目里遇到了一些坑,记录下来。 模型加载 Threejs 在加载 o...

网友评论

      本文标题:threejs 自学 关于摄像机的使用

      本文链接:https://www.haomeiwen.com/subject/hhatddtx.html