threejs教程-透视相机

简介

本系列教程需要具备threejs的基础入门知识,了场景、几何体、相机等基础概念。

学习本教程之前,建议学习笔者的【场景及坐标轴】的基础知识。

使用前置知识,可以很快的开发一个3D页面。

其核心代码如下:

js 复制代码
<template>
  <div class="wrap" ref="threeContainer"></div>
</template>

<script setup>
import * as THREE from "three";
import { onMounted, ref } from "vue";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
// import { CubeTextureLoader } from "three/examples/jsm/loaders/CubeTextureLoader.js";

const threeContainer = ref(null);

// 1、创建3D场景对象Scene
const scene = new THREE.Scene();
// 添加背景颜色
scene.background = new THREE.CubeTextureLoader().setPath("/sky/").load(["posx.jpg", "negx.jpg", "posy.jpg", "negy.jpg", "posz.jpg", "negz.jpg"]);

// 添加网格地面
const gridHelper = new THREE.GridHelper(200, 10);
scene.add(gridHelper);

// 添加三维坐标轴
const axesHelper = new THREE.AxesHelper(80);
axesHelper.position.y = 20;
scene.add(axesHelper);

// 2、创建几何体Geometry模型
const geometry = new THREE.BoxGeometry(20, 20, 20);

const material = new THREE.MeshBasicMaterial({
  color: "blue",
});
const mesh = new THREE.Mesh(geometry, material);
// 设置模型mesh的xyz坐标
mesh.position.set(0, 40, 0);
scene.add(mesh);

// 3、使用虚拟相机观察模型
const camera = new THREE.PerspectiveCamera();
camera.position.set(0, 50, 200);
camera.lookAt(0, 0, 20); //坐标原点

// 4、渲染3D场景到DOM上
const width = 800; //宽度
const height = 500; //高度
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height); //设置three.js渲染区域的尺寸(像素px)
renderer.setAnimationLoop(animation);
// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
// 添加阻尼
controls.enableDamping = true;
controls.dampingFactor = 0.01;
// 开启自动旋转
controls.autoRotate = true;
// 设置自动旋转速度
controls.autoRotateSpeed = 5;

function animation() {
  mesh.rotation.x += 0.05;
  mesh.rotation.y += 0.05;
  controls.update();
  renderer.render(scene, camera);
}

onMounted(() => {
  threeContainer.value.appendChild(renderer.domElement);
});
</script>

<style scoped></style>

透视相机

在Three.js中,透视相机(PerspectiveCamera)是用来模拟人眼所看到的景象,它是3D场景的渲染中使用得最普遍的投影模式。

我们创建项目的时候,采用的就是透视相机

js 复制代码
// 3、使用虚拟相机观察模型
const camera = new THREE.PerspectiveCamera();
camera.position.set(0, 50, 200);
camera.lookAt(0, 0, 20); //坐标原点

要想深入了解透视相机的使用方法,我们需要先学习一些基本的3D知识

PerspectiveCamera简介

语法结构:PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number )

参数 含义 默认值
fov 相机视锥体竖直方向视野角度 50
aspect 相机视锥体水平方向和竖直方向长度比,一般设置为Canvas画布宽高比width / height 1
near 相机视锥体近裁截面相对相机距离 0.1
far 相机视锥体远裁截面相对相机距离,far-near构成了视锥体高度方向 2000

透视投影相机的四个参数fov, aspect, near, far构成一个四棱台 3D空间,被称为视锥体,只有视锥体之内的物体,才会渲染出来,视锥体范围之外的物体不会显示在Canvas画布上。

使用官方编辑器学习透视相机

要想深入学习透视相机,我们可以借助官方提供的编辑器。

编辑器在线地址:threejs.org/editor/

创建物体和透视相机

透视相机的移动与旋转

透视相机与普通相机的视角切换

透视相机的参数调整

不同参数对透视相机位置的影响

代码示例

首先,我们关闭场景的自动旋转,方便观察。

PerspectiveCamera增加初始参数

js 复制代码
// 3、使用虚拟相机观察模型
const camera = new THREE.PerspectiveCamera(
  75, 
  window.innerWidth / window.innerHeight, 
  0.1, 
  1000
);

视野角度fov对视角的影响

js 复制代码
<template>
  <div class="wrap" ref="threeContainer"></div>
  <button @click="changeCameraAdd">+</button>
  <button>相机fov</button>
  <button @click="changeCameraDe">-</button>
</template>

updateProjectionMatrix()方法来更新投影矩阵,以确保场景在新的fov参数下正确渲染

截面near、far对视角的影响

近远截面及fov构成视椎体,当远近界面位置不恰当时,物体可能位于视椎体之外,渲染不出来。

js 复制代码
<template>
  <div class="wrap" ref="threeContainer"></div>
  <button @click="changeCameraAdd">+</button>
  <button>相机fov</button>
  <button @click="changeCameraDe">-</button>
  <button @click="nearAdd">+</button>
  <button>近界面near</button>
  <button @click="nearDe">-</button>
</template>
js 复制代码
function nearAdd() {
  camera.near += 10;
  camera.updateProjectionMatrix();
}
function nearDe() {
  camera.near -= 10;
  camera.updateProjectionMatrix();
}

相机位置对视角的影响

js 复制代码
<template>
  <div class="wrap" ref="threeContainer"></div>
  <button @click="changeCameraAdd">+</button>
  <button>相机fov</button>
  <button @click="changeCameraDe">-</button>
  <button @click="cameraYAdd">Y轴+</button>
  <button>相机位置</button>
  <button @click="cameraXdd">Z轴+</button>
</template>
js 复制代码
function cameraYAdd() {
  camera.position.x += 10;
  controls.update();
}
function cameraXdd() {
  camera.position.z += 10;
  controls.update();
}

物体位置对视角的影响

js 复制代码
<template>
  <div class="wrap" ref="threeContainer"></div>
  <button @click="meshAdd">Y轴+</button>
  <button>物体位置</button>
  <button @click="meshDe">Y轴-</button>
</template>
arduino 复制代码
function meshAdd() {
  mesh.position.y += 10;
}
function meshDe() {
  mesh.position.y -= 10;
}
相关推荐
y先森3 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy3 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189113 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿4 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡5 小时前
commitlint校验git提交信息
前端
虾球xz5 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇5 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒5 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员6 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐6 小时前
前端图像处理(一)
前端