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光源报错解决及原因分析

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/63247.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一条线上的点

给你一个数组 points &#xff0c;其中 points[i] [xi, yi] 表示 X-Y 平面上的一个点。求最多有多少个点在同一条直线上。 提示&#xff1a; 1 < points.length < 300points[i].length 2-104 < xi, yi < 104points 中的所有点 互不相同 解析&#xff1a;使用斜…

XX服务器上的npm不知道咋突然坏了

收到同事的V&#xff0c;说是&#xff1a;182上的npm不知道咋突然坏了&#xff0c;查到这里了&#xff0c;不敢动了。 咱一定要抓重点&#xff1a;突然坏了。这里的突然肯定不是瞬间&#xff08;大概率是上次可用&#xff0c;这次不可用&#xff0c;中间间隔了多长时间&#x…

HALCON 算子 之 形态学操作算子

文章目录 什么是形态学操作&#xff1f;为什么要形态学操作&#xff1f;怎么形态学操作&#xff1f;腐蚀 —— Erosionerosion1erosion_circle&#xff1a;erosion_rectangle1&#xff1a; 膨胀 —— Dilationdilation1dilation_circledilation_rectangle1 打开 —— Openingop…

pytest入门九:feature

fixture是pytest特有的功能&#xff0c;用以在测试执行前和执行后进行必要的准备和清理工作。使用pytest.fixture标识&#xff0c;定义在函数前面。在你编写测试函数的时候&#xff0c;你可以将此函数名称做为传入参数&#xff0c;pytest将会以依赖注入方式&#xff0c;将该函数…

秒优科技-供应链管理系统 login/doAction SQL注入漏洞复现

0x01 产品简介 秒优科技提供的供应链管理系统,即秒优SCM服装供应链管理系统,是一款专为服装电商企业设计的全方位解决方案。是集款式研发、订单管理、物料管理、生产管理、工艺管理、收发货管理、账单管理、报表管理于一体的服装电商供应链管理解决方案。它涵盖了从企划到开…

136.WEB渗透测试-信息收集-小程序、app(7)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;135.WEB渗透测试-信息收集-小程序、app&#xff08;6&#xff09; 进入之后我们通过输入…

K近邻原理和距离

K近邻 基本思想欧氏距离算法流程代码基于近邻用户的协同过滤基于近邻物品的协同过滤杰卡德相似度 基本思想 我们根据涂色样本点和未涂色样本点 X 的距离给涂色样本点编号1-6&#xff0c;即&#xff1a;1号样本点距离X最近&#xff0c;其余次之。 那么问题来了&#xff1a;样本…

模型 A/B测试(科学验证)

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。控制变量法。 1 A/B测试的应用 1.1 Electronic Arts&#xff08;EA&#xff09;《模拟城市》5游戏网站A/B测试 定义目标&#xff1a; Electronic Arts&#xff08;EA&#xff09;在发布新版《模拟城…

Git merge 和 rebase的区别(附图)

在 Git 中&#xff0c;merge 和 rebase 是两种用于整合分支变化的方法。虽然它们都可以将一个分支的更改引入到另一个分支中&#xff0c;但它们的工作方式和结果是不同的。以下是对这两者的详细解释&#xff1a; Git Merge 功能&#xff1a;合并分支&#xff0c;将两个分支的…

耐蚀镍基合金的焊接技术与质量控制

耐蚀镍基合金是一类在腐蚀环境中具有优异性能的合金材料&#xff0c;广泛应用于化工、海洋工程、石油天然气等领域。其焊接技术与质量控制对于确保合金的使用性能和安全性至关重要。以下是对耐蚀镍基合金焊接技术与质量控制的详细探讨。 一、焊接技术 焊条选择 耐蚀镍基合金的焊…

机器视觉与OpenCV--01篇

计算机眼中的图像 像素 像素是图像的基本单位&#xff0c;每个像素存储着图像的颜色、亮度或者其他特征&#xff0c;一张图片就是由若干个像素组成的。 RGB 在计算机中&#xff0c;RGB三种颜色被称为RGB三通道&#xff0c;且每个通道的取值都是0到255之间。 计算机中图像的…

操作系统(14)请求分页

前言 操作系统中的请求分页&#xff0c;也称为页式虚拟存储管理&#xff0c;是建立在基本分页基础上&#xff0c;为了支持虚拟存储器功能而增加了请求调页功能和页面置换功能的一种内存管理技术。 一、基本概念 分页&#xff1a;将进程的逻辑地址空间分成若干个大小相等的页&am…

git企业开发的相关理论(一)

目录 一.初识git 二.git的安装 三.初始化/创建本地仓库 四.配置用户设置/配置本地仓库 五.认识工作区、暂存区、版本库 六.添加文件__场景一 七.查看 .git 文件/添加到本地仓库后.git中发生的变化 1.执行git add后的变化 index文件&#xff08;暂存区&#xff09; log…

wxpython图形用户界面编程

wxpython图形用户界面编程 一、wxpython的基础 1.1 wxpython的基础 作为图形用户界面开发工具包 wxPython&#xff0c;主要提供了如下 GUI 内容&#xff1a; 窗口。控件。事件处理。布局管理。 1.2 wxpython的类层次机构 1.3 wxpython的安装 Windows 和 macOS 平台安装&a…

水仙花数(流程图,NS流程图)

题目&#xff1a;打印出所有的100-999之间的"水仙花数"&#xff0c;并画出流程图和NS流程图。所谓"水仙花数"是指一个三位数&#xff0c;其各位数字立方和等于该数本身。例如&#xff1a;153是一个"水仙花数"&#xff0c;因为1531的三次方&#…

不配置python环境,直接用PyCharm就可以?

有的伙伴可能遇到不安装python环境只安装pycharm也可以进行运行代码。 所以自认为是不需要解释器就可以运行&#xff1f; 这个是不现实的&#xff0c;有很多伙伴可能是安装了Pycharm&#xff0c;但Pycharm看你电脑上没有解释器&#xff0c;所以在安装的时候给你默认安装在C盘…

前端面试汇总(不定时更新)

目录 HTML & CSS1. XML、HTML、XHTML 有什么区别&#xff1f;⭐2. XML和JSON的区别&#xff1f;3. 是否了解W3C的规范&#xff1f;⭐4. 什么是语义化标签&#xff1f;⭐⭐5. 行内元素和块级元素的区别&#xff1f;⭐6. 行内元素和块级元素的转换&#xff1f;⭐7. 常用的块级…

SpringCloud微服务实战系列:03spring-cloud-gateway业务网关灰度发布

目录 spring-cloud-gateway 和zuul spring webflux 和 spring mvc spring-cloud-gateway 的两种模式 spring-cloud-gateway server 模式下配置说明 grayLb://system-server 灰度发布代码实现 spring-cloud-gateway 和zuul zuul 是spring全家桶的第一代网关组件&#x…

ActiveMQ 反序列化漏洞CVE-2015-5254复现

文章目录 一、产生原因二、利用条件三、利用过程四、PoC&#xff08;概念验证&#xff09;五、poc环境验证使用find搜索vulhub已安装目录打开activeMQ组件查看配置文件端口启动镜像-文件配置好后对于Docker 镜像下载问题及解决办法设置好镜像源地址&#xff0c;进行重启docker查…

vue3监听横向滚动条的位置;鼠标滚轮滑动控制滚动条滚动;监听滚动条到顶端

1.横向取值scrollLeft 竖向取值scrollTop 2.可以监听到最左最右侧 3.鼠标滚轮滑动控制滚动条滚动 效果 <template><div><div class"scrollable" ref"scrollableRef"><!-- 内容 --><div style"width: 2000px; height: 100…