Three.js正投影相机OrthographicCamera和透视投影相机PerspectiveCamera

本文深入探讨了Three.js中两种主要的相机投影方式:正投影和透视投影。详细介绍了正投影相机OrthographicCamera和透视投影相机PerspectiveCamera的设置方法及应用场景,包括构造函数参数的含义和使用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

正投影相机OrthographicCamera和透视投影相机PerspectiveCamera

本文是Three.js电子书的9.1节

相机 基类Camera 正投影相机  透视投影相机 立方相机 OrthographicCamera PerspectiveCamera CubeCamera 视图矩阵.matrixWorldInverse 投影矩阵.projectionMatrix 属性

针对不同应用的三维场景需要使用不同的投影方式,比如机械、工业设计领域常常采用正投影(平行投影), 大型游戏场景往往采用透视投影(中心投影)。为了完成三维场景不同的投影方式,three.js封装WebGL API和相关算法,提供了正投影相机OrthographicCamera和透视投影相机PerspectiveCamera

正投影和透视投影简单解释

下面对正投影相机和透视投影相机的投影算法进行简单介绍,对于初学者你有一个印象就可以,如果想深入了解,可以学习图形学或者阅读threejs官方源码src目录下文件OrthographicCamera.jsPerspectiveCamera.js

生活中的物体都是三维的,但是人的眼睛只能看到正面,不能看到被遮挡的背面,三维几何体在人眼睛中的效果就像一张相机拍摄的二维照片,你看到的是一个2D的投影图。 空间几何体转化为一个二维图的过程就是投影,不同的投影方式意味着投影尺寸不同的算法。

在这里插入图片描述

对于正投影而言,一条直线放置的角度不同,投影在投影面上面的长短不同;对于透视投影而言,投影的结果除了与几何体的角度有关,还和距离相关, 人的眼睛观察世界就是透视投影,比如你观察一条铁路距离越远你会感到两条轨道之间的宽度越小。无论正投影还是透视投影,three.js都对相关的投影算法进行了封装, 大家只需要根据不同的应用场景自行选择不同的投影方式。使用OrthographicCamera相机对象的时候,three.js会按照正投影算法自动计算几何体的投影结果; 使用PerspectiveCamera相机对象的时候,three.js会按照透视投影算法自动计算几何体的投影结果。

正投影相机对象OrthographicCamera

/**
 * 正投影相机设置
 */
var width = window.innerWidth; //窗口宽度
var height = window.innerHeight; //窗口高度
var k = width / height; //窗口宽高比
var s = 150; //三维场景显示范围控制系数,系数越大,显示的范围越大
//创建相机对象
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(200, 300, 200); //设置相机位置
camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
// 构造函数格式
OrthographicCamera( left, right, top, bottom, near, far )
参数(属性)含义
left渲染空间的左边界
right渲染空间的右边界
top渲染空间的上边界
bottom渲染空间的下边界
nearnear属性表示的是从距离相机多远的位置开始渲染,一般情况会设置一个很小的值。 默认值0.1
farfar属性表示的是距离相机多远的位置截止渲染,如果设置的值偏小小,会有部分场景看不到。 默认值1000

在这里插入图片描述
三维场景中坐标值不在三维空间中的网格模型不会被渲染出来,会被剪裁掉,比如你把上面代码中far参数的值从1000更改为420,你会发现长方体的一部分无法显示。

注意

左右边界的距离与上下边界的距离比值与画布的渲染窗口的宽高比例要一致,否则三维模型的显示效果会被单方向不等比例拉伸

构造函数OrthographicCamera的参数( left,right,top,bottom,near,far)本质上是对WebGL投影矩阵的封装,宽度width、高度height越大,三维模型顶点的位置坐标就会越大,超出可视区域的网格模型就会被剪裁掉, 不会再显示在屏幕上,大家还可以看到参数leftright、参数topbottom互为相反数,这样做的目的是lookAt指向的对象能够显示在canvas画布的中间位置。

透视投影相机PerspectiveCamera

/**
 * 透视投影相机设置
 */
var width = window.innerWidth; //窗口宽度
var height = window.innerHeight; //窗口高度
/**透视投影相机对象*/
var camera = new THREE.PerspectiveCamera(60, width / height, 1, 1000);
camera.position.set(200, 300, 200); //设置相机位置
camera.lookAt(scene.position); //设置相机方向(指向的场景对象)

构造函数PerspectiveCamera格式

PerspectiveCamera( fov, aspect, near, far )
参数含义默认值
fovfov表示视场,所谓视场就是能够看到的角度范围,人的眼睛大约能够看到180度的视场,视角大小设置要根据具体应用,一般游戏会设置60~90度45
aspectaspect表示渲染窗口的长宽比,如果一个网页上只有一个全屏的canvas画布且画布上只有一个窗口,那么aspect的值就是网页窗口客户区的宽高比window.innerWidth/window.innerHeight
nearnear属性表示的是从距离相机多远的位置开始渲染,一般情况会设置一个很小的值。0.1
farfar属性表示的是距离相机多远的位置截止渲染,如果设置的值偏小小,会有部分场景看不到1000

在这里插入图片描述

相机位置.posiiotn.lookAt(相机拍摄目标位置)

在这里插入图片描述

相机Camera的基类是Object3D,相机对象Camera具有位置属性.posiiotn,通过位置属性.posiiotn可以设置相机的位置。

.lookAt()方法用来指定相机拍摄对象的坐标位置,.lookAt()方法的参数是表示位置坐标的三维向量对象Vector3,所以.lookAt()方法的参数可以通过代码new THREE.Vector3(x,y,z)设置。实际开发的时候,你希望相机对准哪个对象,就返回那个对象的位置属性.posiiotn,比如上面代码中的scene.position, 就表示返回场景scene的位置坐标,如果把scene.position换成某个网格模型对象的位置就是mesh.positionmesh.position表示网格模型mesh的本地位置坐标。通过相机观察点的位置和.lookAt()方法指向的位置就可以计算出相机的拍摄角度,本质上就是计算出相机对象的视图矩阵.matrixWorldInverse

对于透视投影而言,相机位置与lookAt指向的观察目标位置间隔距离越小,场景中的三维模型放大倍数越大,准确地说是透视投影相机可以拍摄的范围更小,同时场景Scene中超出的相机参数约束范围的部分会被剪裁掉, 比如更改上面代码camera.position.set(100,200,200);(20,20,20),测试结果你会发现立方体几何体放大显示,超出区域被剪裁。

相机位置放置

如果是观察一个产品外观效果,相机就位于几何体的外面,如果是室内漫游预览,就把相机放在房间三维模型的内部。

Three.js 是一个基于 WebGL 的 JavaScript 库,用于创建展示复杂的 3D 2D 图形无需插件。Three.js 提供了多种内置对象、材质、光源等资源,简化了三维图形渲染的过程。 正投影相机Three.js 中的一种相机模型,它用于模拟二维空间中的平行投影效果,在三维场景中生成的图像保持线条平行性相对大小不变。这种类型的相机适用于绘制建筑平面图、技术图纸或其他需要保持物体间精确比例的视图。以下是关于正投影相机的一些关键特性: ### 特点 1. **线性透视**:在正投影中,所有平行线在投影面上仍然保持平行,这使得物体的比例在整个视野内保持一致,非常适合绘制结构图机械设计图。 2. **尺寸稳定性**:与透视投影相比,正投影下的物体不会因为距离的变化而改变其实际大小,这对于需要精确测量标注的场景非常有用。 3. **无变形效果**:在正投影下,无论物体离相机有多远,它们的形状都不会发生扭曲变形,有助于保持物体的真实形态。 4. **易于理解解释**:由于没有视觉上的深度错觉,用户能够更直接地理解所呈现的空间布局结构,这对于工程、建筑设计等领域尤为重要。 ### 使用示例 假设我们想创建一个正投影相机并将其应用到一个 Three.js 场景中: ```javascript // 引入Three.js库 import * as THREE from 'three'; // 创建一个新的场景 const scene = new THREE.Scene(); // 设置背景颜色 scene.background = new THREE.Color(0xffffff); // 白色背景 // 创建摄像机实例 - 使用透视相机(通常情况正投影相机Three.js中表示为透视相机而非一种特定的“正投影相机) const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, 0, 100); // 设置初始位置 // 创建渲染器实例 const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 添加一个立方体作为场景的一部分 const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // 调整相机视口以适应场景的大小 camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); // 渲染场景并持续更新 function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate(); ``` 在这个简单的例子中,我们首先导入了必要的 Three.js 文件,并创建了一个新的场景、摄像机以及一个立方体作为场景的内容。这里使用的是透视相机 `THREE.PerspectiveCamera` 类型的相机,它是 Three.js 默认提供的相机类型之一,尽管它默认配置的实际上是一种透视投影效果而不是纯正投影。对于真正的正投影效果,实际中并不常见于 Three.js 环境下,因为大多数图形处理需求涉及到视角变换透视效果,以获得更真实的三维体验。然而,上述代码提供了一个基础框架,用于在 Three.js 中操作渲染场景。 --- ### 相关问题: 1. 为什么在某些情况下选择正投影相机而非透视相机? 2. 怎样调整正投影相机的位置视角以优化3D场景的表现? 3. 正投影相机如何影响物体的显示交互,在设计过程中有哪些应用场景?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Threejs可视化

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值