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;
}
相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95273 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大3 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师3 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学3 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端