当前位置: 首页 > news >正文

Three.js相机Camera控件知识梳理

原文:https://juejin.cn/post/7231089453695238204?searchId=20241217193043D32C9115C2057FE3AD64

1. 相机类型

Three.js 主要提供了两种类型的相机:正交相机(OrthographicCamera)和透视相机(PerspectiveCamera)。

1.1 正交相机

正交相机(OrthographicCamera)使用正交投影进行渲染。在正交投影中,物体的大小不会随着距离的增加而减小,这意味着所有物体在渲染时保持相同的尺寸,不受距离的影响。这种相机在制作 2D 游戏和 CAD 工具等应用中非常有用。

创建正交相机的代码如下:

1

2

3

4

5

6

7

const camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far);

// 正投影相机案例

const width = window.innerWidth; //canvas画布宽度

const height = window.innerHeight; //canvas画布高度

const k = width / height; //canvas画布宽高比

const s = 600;//控制left, right, top, bottom范围大小

const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 8000);

参数(属性)含义
left渲染空间的左边界
right渲染空间的右边界
top渲染空间的上边界
bottom渲染空间的下边界
nearnear属性表示的是从距离相机多远的位置开始渲染,一般情况会设置一个很小的值。 默认值0.1
farfar属性表示的是距离相机多远的位置截止渲染,如果设置的值偏小小,会有部分场景看不到。 默认值2000

1.2 透视相机

透视相机(PerspectiveCamera)使用透视投影进行渲染。在透视投影中,物体的大小会随着距离的增加而减小,这使得远离相机的物体看起来更小,符合现实世界中的透视效果。这种相机在制作 3D 游戏和仿真应用中非常常见。

创建透视相机的代码如下:

1

2

3

4

5

6

7

const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);

//透视相机案例

// width和height用来设置Three.js输出的Canvas画布尺寸(像素px)

const width = 800; //宽度

const height = 500; //高度

// 30:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000:远裁截面

const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);

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

2. 相机属性

Three.js 中的相机具有一些基本属性,这些属性决定了相机的视角和视野。

2.1 视角(FOV)

仅透视相机具有视角属性(FOV)。视角表示相机的垂直视野范围,单位为度。较大的视角值会导致更大的视野,但可能会产生畸变。较小的视角值则会产生更窄的视野和更低的畸变。

2.2 宽高比(Aspect)

仅透视相机具有宽高比属性。宽高比表示相机水平视野范围与垂直视野范围的比值。通常,宽高比应该与渲染目标(如 Canvas 或 WebGLRenderTarget)的宽高比相同,以避免图像被拉伸或压缩。

2.3 近裁剪面(Near)和远裁剪面(Far)

近裁剪面和远裁剪面定义了相机的渲染范围。位于近裁剪面之前的物体和位于远裁剪面之后的物体都不会被渲染。为了提高渲染性能,通常应该尽量将近裁剪面和远裁剪面之间的距离设置得较小。

3. 不同方向的投影视图

3.1 x轴方向观察

1

2

3

4

5

// 通过UI按钮改变相机观察角度

document.getElementById('x').addEventListener('click', function () {

    camera.position.set(500, 0, 0); //x轴方向观察

    camera.lookAt(0, 0, 0); //重新计算相机视线方向

})

3.2 y轴方向观察

1

2

3

4

5

// 通过UI按钮改变相机观察角度

document.getElementById('y').addEventListener('click', function () {

    camera.position.set(0, 500, 0); //y轴方向观察

    camera.lookAt(0, 0, 0); //重新计算相机视线方向

})

3.3 z轴方向观察z轴方向观察

1

2

3

4

5

// 通过UI按钮改变相机观察角度

document.getElementById('z').addEventListener('click', function () {

    camera.position.set(0, 0, 500); //z轴方向观察

    camera.lookAt(0, 0, 0); //重新计算相机视线方向

})

4. 相机动画(.position和.lookAt())

通过相机对象Camera.position属性和.lookAt()方法,可实现一段相机动画。

4.1 相机运动动画

改变相机的位置.position,三维场景在canvas画布上呈现不同的效果,如果连续改变相机的位置.position,就可以获得一个动画效果。

课件案例源码是一个工厂模型,相机在空中俯视工厂,如果在渲染循环中不停地改变相机位置,这时候产生的视觉效果,就好比你在天上运动,看地面的效果。

1

2

3

4

5

6

7

// 渲染循环

function render() {

    camera.position.z -= 0.3;//相机直线运动动画

    renderer.render(scene, camera);

    requestAnimationFrame(render);

}

render();

4.2 相机圆周运动相机圆周运动

在渲染循环中,改变相机位置,在XOZ平面上绕着y轴圆周运动。

1

2

3

4

5

6

7

8

9

10

11

12

// 渲染循环

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);

    requestAnimationFrame(render);

}

render();

4.3 执行lookAt()计算相机视线方向

改变.position属性后,如果不执行.lookAt()方法,相机的观察方向默认不变。

如果你希望相机圆周运动的同时,改变相机视线方向,保持相机镜头始终指向坐标原点或其它位置,需要每次改变.position属性后,重新执行一遍.lookAt()方法

1

2

3

4

5

6

7

8

9

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();

5. 相机控件OrbitControls

通常需要为用户提供一种直观的方式来浏览和操作场景。OrbitControls 是 Three.js 提供的一种常用的相机控制器,允许用户通过鼠标或触摸屏操作来旋转、平移和缩放场景。

5.1 OrbitControls使用

  • 旋转:拖动鼠标左键
  • 缩放:滚动鼠标中键
  • 平移:拖动鼠标右键

OrbitControls本质上就是改变相机的参数,比如相机的位置属性,改变相机位置也可以改变相机拍照场景中模型的角度,实现模型的360度旋转预览效果,改变透视投影相机距离模型的距离,就可以改变相机能看到的视野范围。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

// 引入轨道控制器扩展库OrbitControls.js

import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

// 设置相机控件轨道控制器OrbitControls

const controls = new OrbitControls(camera, renderer.domElement);

// 如果OrbitControls改变了相机参数,重新调用渲染器渲染三维场景

controls.addEventListener('change', function () {

    renderer.render(scene, camera); //执行渲染操作

    console.log('camera.position',camera.position);

});//监听鼠标、键盘事件

//相关限制方法:

controls.enablePan = false; //禁止平移

controls.enableZoom = false;//禁止缩放

controls.enableRotate = false; //禁止旋转

// 缩放范围

controls.minZoom = 0.5;

controls.maxZoom = 2;

// 上下旋转范围

controls.minPolarAngle = 0;

controls.maxPolarAngle = Math.PI/2;

// 左右旋转范围

controls.minAzimuthAngle = -Math.PI/2;

controls.maxAzimuthAngle = Math.PI/2;

//更新方法

function animate() {

  requestAnimationFrame(animate);

  // 更新控制器

  controls.update();

  // 渲染场景

  renderer.render(scene, camera);

}

6. 相机控件MapControls

在某些 Three.js 应用中,例如地图、地形或者 GIS 类型的项目,需要为用户提供一种直观且符合习惯的方式来浏览和操作场景。MapControls 是一个类似于 Google Maps 风格的相机控制器,允许用户通过鼠标和触摸屏操作来平移、缩放和旋转场景。

6.1 MapControls使用

  • 平移:鼠标左键拖动
  • 旋转:鼠标右键拖动
  • 缩放:鼠标中键滚动

MapControls本质上就是改变相机的参数,比如相机的位置属性、相机目标观察点。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

// 引入相机控件`MapControls`

import { MapControls } from 'three/addons/controls/OrbitControls.js';

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);

});

//相关限制方法:

controls.enablePan = false; //禁止平移

controls.enableZoom = false;//禁止缩放

controls.enableRotate = false; //禁止旋转

//相机位置与观察目标点最小值

controls.minDistance = 200;

//相机位置与观察目标点最大值

controls.maxDistance = 500;

// 上下旋转范围

controls.minPolarAngle = 0;

controls.maxPolarAngle = Math.PI/2;

// 左右旋转范围

controls.minAzimuthAngle = -Math.PI/2;

controls.maxAzimuthAngle = Math.PI/2;

//更新方法

function animate() {

  requestAnimationFrame(animate);

  // 更新控制器

  controls.update();

  // 渲染场景

  renderer.render(scene, camera);

}

7. 窗口变化的自适应渲染

在开发 Three.js 项目时,我们需要考虑到不同的设备和屏幕尺寸。当用户调整浏览器窗口大小时,我们希望场景能够自适应地进行调整,以保持正确的比例和尺寸。

要实现自适应渲染,我们需要在浏览器窗口大小发生变化时更新相机和渲染器的设置。首先,我们需要为 window 对象添加一个 resize 事件监听器:

1

window.addEventListener('resize', onWindowResize);

接下来,我们定义 onWindowResize 函数。在这个函数中,我们需要完成以下任务:

  • 更新相机的宽高比(aspect)。
  • 更新相机的投影矩阵。
  • 更新渲染器的大小。

7.1 正投影相机OrthographicCamera自适应渲染

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

// onresize 事件会在窗口被调整大小时发生

function onWindowResize(){

  // 重置渲染器输出画布canvas尺寸

  renderer.setSize(window.innerWidth,window.innerHeight);

  // 重置相机投影的相关参数

  k = window.innerWidth/window.innerHeight;//窗口宽高比

  camera.left = -s*k;

  camera.right = s*k;

  camera.top = s;

  camera.bottom = -s;

  // 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix

  // 但是不会每渲染一帧,就通过相机的属性计算投影矩阵(节约计算资源)

  // 如果相机的一些属性发生了变化,需要执行updateProjectionMatrix ()方法更新相机的投影矩阵

  camera.updateProjectionMatrix ();

};

7.2 透视投影相机PerspectiveCamera自适应渲染

1

2

3

4

5

6

7

8

9

10

11

// onresize 事件会在窗口被调整大小时发生

function onWindowResize(){

  // 重置渲染器输出画布canvas尺寸

  renderer.setSize(window.innerWidth,window.innerHeight);

  // 全屏情况下:设置观察范围长宽比aspect为窗口宽高比

  camera.aspect = window.innerWidth/window.innerHeight;

  // 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix

  // 但是不会每渲染一帧,就通过相机的属性计算投影矩阵(节约计算资源)

  // 如果相机的一些属性发生了变化,需要执行updateProjectionMatrix ()方法更新相机的投影矩阵

  camera.updateProjectionMatrix ();

};

以上就是Three.js相机Camera的详细内容,更多关于Three.js相机Camera的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:

  • Three.js引用和环境搭建过程详解
  • Three.js概述和基础知识学习
  • Three.js材质Material类型示例详解
  • Three.js PBR物理渲染属性及使用介绍
  • Three.js 中的屏幕空间环境光遮蔽SSAO
  • Three.js物理引擎Cannon.js创建简单应用程序
  • Three.js中实现Bloom效果及完整示例
  • THREE.js添加多个castShadow光源报错解决及原因分析

相关文章:

Three.js相机Camera控件知识梳理

原文:https://juejin.cn/post/7231089453695238204?searchId20241217193043D32C9115C2057FE3AD64 1. 相机类型 Three.js 主要提供了两种类型的相机:正交相机(OrthographicCamera)和透视相机(PerspectiveCamera&…...

Unity 开发Apple Vision Pro空间锚点应用Spatial Anchor

空间锚点具有多方面的作用 虚拟物体定位与固定: 位置保持:可以把虚拟物体固定在现实世界中的特定区域或位置。即使使用者退出程序后再次打开,之前锚定过的虚拟物体仍然能够出现在之前所锚定的位置,为用户提供连贯的体验。比如在一…...

BGP的六种状态分别是什么?

此文章主要简单介绍下BGP的六种状态 1.Idle BGP会话的初始状态,路由器在此状态下不与任何BGP邻居通信,通常标识会话还没有开始或由于错误而未能启动,一般来说,缺乏去往BGP对等体的路由是导致BGP路由器其状态一直处于idle状态的常…...

IDEA搭建SpringBoot,MyBatis,Mysql工程项目

目录 一、前言 二、项目结构 三、初始化项目 四、SpringBoot项目集成Mybatis编写接口 五、代码仓库 一、前言 构建一个基于Spring Boot框架的现代化Web应用程序,以满足[公司/组织名称]对于[业务需求描述]的需求。通过利用Spring Boot简化企业级应用开发的优势&…...

Reactor

文章目录 正确的理解发送double free问题 1.把我们的reactor进行拆分2.链接管理3.Reactor的理论 listensock只需要设置_recv_cb,而其他sock,读,写,异常 所以今天写nullptr其实就不太对,添加为空就没办法去响应事件 获…...

在ESP32使用AT指令集与服务器进行TCP/IP通信时,<link ID> 解释

在ESP32使用AT指令集与服务器进行TCP/IP通信时&#xff0c;<link ID> 是一个非常重要的参数。它用于标识不同的连接实例&#xff0c;特别是在多连接场景下&#xff08;如同时建立多个TCP或UDP连接&#xff09;。每个连接都有唯一的<link ID>&#xff0c;通过这个ID…...

[SZ901] JTAG合并功能(类似FPGA菊花链)

SZ901 JTAG支持将JTAG端口组合&#xff0c;最多将四个JTAG变成一个 设置如下 Vivado 识别结果如下 两块板子&#xff0c;变成一组&#xff0c;&#xff0c;可以同时抓取信号&#xff0c;调试&#xff01; SZ901 已上架淘宝&#xff0c;搜素“SZ901”哦...

paimon中的Tag

TAG 在传统数仓场景中&#xff0c;从传统数据库中导入的事实表数据一般是全量导入&#xff0c;按天分区每天都存储一份全量数据&#xff0c;paimon对此提供了Tag机制&#xff0c;创建TAG时&#xff0c;会对当前数据做一份全量快照&#xff0c;在之后对表的数据进行更新也不会影…...

3分钟读懂数据分析的流程是什么

数据分析是基于商业目的&#xff0c;有目的地进行收集、整理、加工和分析数据&#xff0c;提炼出有价值的 信息的一个过程。整个过程大致可分为五个阶段&#xff0c;具体如下图所示。 1.明确目的和思路 在开展数据分析之前&#xff0c;我们必须要搞清楚几个问题&#xff0c;比…...

uniapp入门 01创建项目模版

0安装 hbuilder x 标准版 1.创建模版工程 2.创建官方 案例工程 index.uvuewen 文件解析 <!-- 模版 标签 --> <template><view></view></template><!-- 脚本 --> <script>export default {data() {return {}},onLoad() {},methods:…...

React 19新特性探索:提升性能与开发者体验

React作为最受欢迎的JavaScript库之一&#xff0c;不断推出新版本以应对日益复杂的应用需求。React 19作为最新的版本&#xff0c;引入了一系列令人兴奋的新特性和改进&#xff0c;旨在进一步提升应用的性能、开发效率和用户体验。 本文将深入探讨React 19的新特性&#xff0c;…...

Hive是什么,Hive介绍

官方网站&#xff1a;Apache Hive Hive是一个基于Hadoop的数据仓库工具&#xff0c;主要用于处理和查询存储在HDSF上的大规模数据‌。Hive通过将结构化的数据文件映射为数据库表&#xff0c;并提供类SQL的查询功能&#xff0c;使得用户可以使用SQL语句来执行复杂的​MapReduce任…...

[LeetCode-Python版] 定长滑动窗口1(1456 / 643 / 1343 / 2090 / 2379)

思路 把问题拆解成三步&#xff1a;入-更新-出。 入&#xff1a;下标为 i 的元素进入窗口&#xff0c;更新相关统计量。如果 i<k−1 则重复第一步。更新&#xff1a;更新答案。一般是更新最大值/最小值。出&#xff1a;下标为 i−(k-1) 的元素离开窗口&#xff0c;更新相关…...

imx6ull qt多页面控制系统(正点原子imx系列驱动开发)

开题答辩完了也考完了四六级&#xff0c;赶紧来更新一下一个月前留下的坑吧 QAQ首先&#xff0c;因为毕业设计需要用到这些知识所以就从网络上找了一个智能车机系统&#xff0c;借鉴了一下大佬的项目思路&#xff0c;缝缝补补一个月终于完成了这一内容。 在这里先感谢从两位大佬…...

OCR:文字识别

使用场景: 远程身份认证 自动识别录入用户身份/企业资质信息&#xff0c;应用于金融、政务、保险、电商、直播等场景&#xff0c;对用户、商家、主播进行实名身份认证&#xff0c;有效降低用户输入成本&#xff0c;控制业务风险 文档电子化 识别提取各类办公文档、合同文件、企…...

SQL Server通过存储过程实现自定义邮件格式并定时发送

在 SQL Server 中,可以通过存储过程实现自定义邮件格式并定时发送。这通常涉及以下几个步骤: 1. 配置 Database Mail:首先需要配置 SQL Server 的 Database Mail 功能。 2. 创建存储过程:编写存储过程来生成自定义邮件格式并发送邮件。 3. 设置 SQL Server 代理作…...

【进阶编程】MVC和MVVM实现前后端分离的实现

在 WPF 开发中&#xff0c;通常使用 MVVM&#xff08;Model-View-ViewModel&#xff09;架构来分离视图和业务逻辑&#xff0c;但在某些情况下&#xff0c;你可能希望将 MVC&#xff08;Model-View-Controller&#xff09;模式与 MVVM 结合使用。这种结合有时是为了兼顾不同的架…...

HT81297 18W内置升压单声道D类音频功放

1、特征 扩频技术 输出功率 18W(VBAT3.7V, RL4Ω, THDN10%, fN 1kHz) 16W(VBAT3.7V,RL-4Ω,THDN1%,fN1kHz) 8W(VBAT3.3V,RL-8Ω,THDN1%, fN1kHz) VBAr供电范围:3.0V至12V 高效H类升压功能 -自适应功放功率的升压轨&#xff0c;延长电池播放时间 (HT81297A) -可调节最大限流值&…...

linux ipmitool配置机器的BMC(服务器管理后台)

前置&#xff1a;mgnt口和网卡1连接入内网&#xff0c;并分配静态ip 1. 安装 ipmitool Debian/Ubuntu: sudo apt-get update sudo apt-get install ipmitool CentOS/RHEL: sudo yum install ipmitool2. 配置 BMC 的 IP 地址 #打印当前ipmi 地址配置信息。 ipmitool lan p…...

【项目实战】location.href 实现文件下载

应用场景 最近在项目中看到一种新的文件下载方式,原理是将[后台地址接口地址请求参数]拼接成一个url,直接将下载任务丢给浏览器去执行.但是在需要校验token的项目中,需要后台单独给这个接口放开token校验 location.href 相关内容 window.location.protocol: 返回当前 URL 的…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...

jmeter聚合报告中参数详解

sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample&#xff08;样本数&#xff09; 表示测试中发送的请求数量&#xff0c;即测试执行了多少次请求。 单位&#xff0c;以个或者次数表示。 示例&#xff1a;…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...

【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?

FTP&#xff08;File Transfer Protocol&#xff09;本身是一个基于 TCP 的协议&#xff0c;理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况&#xff0c;主要原因包括&#xff1a; ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...