Three.js学习6:透视相机和正交相机
一、相机
相机 camera,可以理解为摄像机。在拍影视剧的时候,最终用户看到的画面都是相机拍出来的内容。
Three.js 里,相机 camera 里的内容就是用户能看到的内容。从这个角度来看,相机其实就是用户的视野,就像用户的眼睛。
Three.js 主要有四种不同的相机模式:
-
透视相机 PerspectiveCamera:具有透视效果,近大远小,也是用的最多的相机。
-
正交相机 OrthographicCamera:不具有透视效果,所有的元素的尺寸大小都是相同的,不管距离。
-
立体相机 StereoCamera:主要做VR用的。就是让左右视觉有点点不一样的相机。
-
立方体相机 CubeCamera:主要用作反射镜面纹理。
本文主要讨论透视相机和正交相机。
前面案例中应用到的轨道控制器,名为轨道,其实控制的就是相机的视角。
二、透视相机
透视相机(PerspectiveCamera)中的物体具有“近大远小”的特点,是3D场景的渲染中使用得最普遍的投影模式。
1. 参数解析
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far );
其参数分别为:
-
fov :摄像机视锥体垂直视野角度,以角度来表示。默认值是50。
-
aspect :摄像机视锥体宽高比:默认值为 1,一般用渲染器到宽高比。
-
near:摄像机视锥体近截面,默认值是0.1。
-
far:摄像机视锥体远截面,默认值是2000。
const camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 );
scene.add( camera );
只有在视锥体范围内,近截面和远截面之间的物体才会被渲染出来。
Three.js 编辑器里视锥体的样子:
可以通过点语法的形式修改相机视锥体的参数,但是必须调用camera.updateProjectionMatrix()
方法,让修改生效。
const camera = new THREE.PerspectiveCamera(50, winW/winH,1, 10);
camera.near = 5; // 修改参数
camera.far = 37;
camera.updateProjectionMatrix(); // 让参数修改生效
2. 修改相机坐标
因为,相机默认在原点上,物体也默认在原点上。所以,要看到物品,要把相机往后挪动位置,也既修改 z 轴位置。
// 调整相机位置 x,y,z
camera.position.z = 0;
camera.position.x = 0;
camera.position.y = 10;// 或者
camera.position.set(0,0,10);
3. 镜头对准物体
不过有时候,移动相机的时候,相机必须要盯着目标物体,避免物体跑出视野之外。
camera.lookAt( Xmesh.position ); // 相机镜头盯着x物体
也可以对准某个具体的位置:
camera.lookAt(new THREE.Vector3(x,y,z));
4. 缩放镜头
camera.zoom = 4;
camera.updateProjectionMatrix(); // 让参数修改生效
获取或者设置摄像机的缩放倍数,其默认值为1。
-
>1
:镜头里的物体会被放大 -
<1
:物体会被缩小 -
=1
:物体正常大小
必须调用camera.updateProjectionMatrix()
方法,让修改生效。
三、正交相机
正交相机(OrthographicCamera),无论物体距离相机距离远或者近,在最终渲染物体的大小都保持不变。
主要用于渲染 2D 场景或者UI元素。如下图所示:
1. 参数解析
const camera = new THREE.OrthographicCamera(OrthographicCamera( left, right, top, bottom, near, far);
scene.add( camera );
其参数依次分别为:
-
left : 摄像机视锥体左侧面。
-
right : 摄像机视锥体右侧面。left 与 right 互为反数。
-
top:摄像机视锥体上侧面。
-
bottom: 摄像机视锥体下侧面。top 与 bottom 互为反数。
-
near : 摄像机视锥体近截面。其默认值为0.1。
-
far: 摄像机视锥体远截面。其默认值为2000。
这几个参数刚好组成一个立方体。
例如:
const k = winW / winH; //canvas画布宽高比
const s = 2; // 显示控制系数。
const camera = new THREE.OrthographicCamera( -s*k, k*s, s, -s, 0.1, 2000 );
camera.position.set(8,8,8);
scene.add( camera );
为了保持照相机的横竖比例,需要保证 (right - left)
与 (top - bottom)
的比例与 Canvas(也就是渲染器)宽度与高度的比例一致。所以才有了两个变量 k、s。
-
变量 k:render 渲染的宽高比。因为,正交相机默认渲染的是一个正方形,但是我们渲染的范围(canvas)不一定是一个正方形。正交相机区域将被拉伸以适合我们的矩形画布,因此我们需要使用画布的宽高比。
-
变量 S 是正交相机显示控制系数。值越小,画面越大。反之,画面越小。如果为1,画面会很大。所以,这里用“单位”的2倍。当然,也可以根据需要自行调整数据。
Three.js 编辑器里正交相机视锥体的样子:
跟透视相机一样,可以通过点语法的形式修改相机视锥体的参数,但是必须调用camera.updateProjectionMatrix()
方法,让修改生效。
2. 正交相机例子
let winW = window.innerWidth;
let winH = window.innerHeight;// 场景
const scene = new THREE.Scene();
scene.background = new THREE.Color("#cccccc");// 网格辅助器
const grid = new THREE.GridHelper(1000,10);
scene.add(grid);// 物体
const geometry = new THREE.BoxGeometry(100,100,100);
const material = new THREE.MeshBasicMaterial({color:"#f00"
});
const mesh = new THREE.Mesh( geometry, material );
mesh.position.set(0,0,0);
scene.add( mesh );// 正投影相机案例
const k = winW / winH; //canvas画布宽高比
const s = 2; // 显示控制系数。网格单位*2
const camera = new THREE.OrthographicCamera( -s*k, k*s, s, -s, 0.1, 2000 );
camera.position.set(8,8,8);
scene.add( camera );// 渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize( winW, winH );
document.body.appendChild( renderer.domElement );
renderer.render(scene, camera);// 轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.update();
controls.addEventListener(function(){console.info( camera.position );
});// 动画
function aniFun(){renderer.render( scene, camera );controls.update();requestAnimationFrame( aniFun );
}
aniFun();
可以看到,正交相机的图像是没有近大远小的透视感的。
四、相机切换示例
html:
<div class="btns"><button type="button" id="tsBtn">透视相机</button><button type="button" id="zjBtn">正交相机</button><h1 id="tit">透视相机</h1>
</div><script type="importmap">{"imports":{"three":"./js/three.module.min.js","three/addons/":"./js/jsm/"}}
</script>
<script type="module" src="./js/myjs5-3.js"></script>
JS:
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";let scene,camera,controls, grid,renderer;
let winW = window.innerWidth,winH = window.innerHeight;let tsBtn = document.getElementById("tsBtn"),zjBtn = document.getElementById("zjBtn"),tit = document.getElementById("tit");// 场景
scene = new THREE.Scene();
scene.background = new THREE.Color("#cccccc");// 透视相机
function pCamera(){camera = new THREE.PerspectiveCamera(50, winW/winH,1, 1000);camera.position.set( 8,8,8 );camera.lookAt( scene.position );scene.add( camera );
}// 正交相机
function oCamera(){const k = winW / winH; //canvas画布宽高比const s = 8; // 显示控制系数。camera = new THREE.OrthographicCamera( -s*k, k*s, s, -s, 0.1, 2000 );camera.position.set(8,8,8);camera.lookAt( scene.position );scene.add( camera );
}// 渲染器
function renderFun(){renderer = new THREE.WebGLRenderer();renderer.setSize( winW, winH );document.body.appendChild( renderer.domElement );
}// 网格辅助
function gridHelperFun(){grid = new THREE.GridHelper(10,10);scene.add(grid);
}// 立方体
function cubeFun(){let geometry = new THREE.BoxGeometry(1,1,1);let metiral = new THREE.MeshBasicMaterial({color:"#ff3300"});let mesh = new THREE.Mesh( geometry, metiral);scene.add( mesh );
}// 函数调用
pCamera();
renderFun();
gridHelperFun();
cubeFun();renderer.render(scene, camera);// 动画渲染
function animateFun(){// 渲染renderer.render( scene, camera);requestAnimationFrame(animateFun);
}
animateFun();// 按钮事件
tsBtn.addEventListener("click",function(){pCamera();renderer.render(scene, camera);tit.innerHTML = "透视相机";
});
zjBtn.addEventListener("click",function(){oCamera();renderer.render(scene, camera);tit.innerHTML = "正交相机";
});
相关文章:

Three.js学习6:透视相机和正交相机
一、相机 相机 camera,可以理解为摄像机。在拍影视剧的时候,最终用户看到的画面都是相机拍出来的内容。 Three.js 里,相机 camera 里的内容就是用户能看到的内容。从这个角度来看,相机其实就是用户的视野,就像用户的眼…...

❤ React18 环境搭建项目与运行(地址已经放Gitee开源)
❤ React项目搭建与运行 环境介绍 node v20.11.0 react 18.2 react-dom 18.2.0一、React环境搭建 第一种普通cra搭建 1、检查本地环境 node版本 18.17.0 检查node和npm环境 node -v npm -v 2、安装yarn npm install -g yarn yarn --version 3、创建一个新的React项目…...

2024 RTE行业(实时互动行业)人才发展学习总结
解决方案 人才画像 开发者人才素质要求: 具备多个领域的技术知识注重团队合作,具备协作能力以用户为导向的用户体验意识具备创新思维和解决问题的能力需快速响应行业变化和持续的学习能力具备项目管理能力 学习和吸收新知识的渠道 RTE人才分类...

92.网游逆向分析与插件开发-游戏窗口化助手-显示游戏数据到小助手UI
内容参考于:易道云信息技术研究院VIP课 上一个内容:游戏窗口化助手的UI设计-CSDN博客 码云地址(游戏窗口化助手 分支):https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号:e8116af3a7b0186adba…...

Stable Diffusion 模型下载:majicMIX fantasy 麦橘幻想
文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十 下载地址 模型介绍 非常推荐的一个非常绚丽、充满幻想的大模型,由国人“Merjic”发布,下载量颇高。这个模型风格炸裂,远距离脸部需要inpaint以达成…...
docker compose安装minio
要使docker-compose管理的容器(如MinIO)在系统启动时自动启动,你需要使用Docker的重启策略。在你的docker-compose.yml文件中为MinIO服务添加restart策略即可实现这一目标。restart: always指令确保了在容器退出时总是重新启动容器࿰…...

二、SSM 整合配置实战
本章概要 依赖整合和添加控制层配置编写(SpringMVC 整合)业务配置编写(AOP/TX 整合)持久层配置编写(MyBatis 整合)容器初始化配置类整合测试 2.1 依赖整合和添加 数据库准备 数据库脚本 CREATE DATABASE mybatis-example;USE mybatis-example;CREATE TABLE t_emp(emp_id INT…...

『运维备忘录』之 Yum 命令详解
运维人员不仅要熟悉操作系统、服务器、网络等只是,甚至对于开发相关的也要有所了解。很多运维工作者可能一时半会记不住那么多命令、代码、方法、原理或者用法等等。这里我将结合自身工作,持续给大家更新运维工作所需要接触到的知识点,希望大…...
CSS中可继承与不可继承属性有哪些
一、无继承性的属性 1.display:规定元素应该生成的框的类型 属性值作用none元素不显示,并且会从文档流中移除。block块类型。默认宽度为父元素宽度,可设置宽高,换行显示。inline行内元素类型。默认宽度为内容宽度,不…...

Zephyr NRF7002 实现AppleJuice
BLE的基础知识 ble的信道和BR/EDR的信道是完全不一样的。但是范围是相同的,差不多也都是2.4Ghz的频道。可以简单理解为空中有40个信道0~39信道。两个设备在相同的信道里面可以进行相互通信。 而这些信道SIG又重新编号: 这个编号就是把37 38 39。 3个信道…...

(已解决)vue+element-ui实现个人中心,仿照原神
差一个个人中心页面,看到了这个博主的个人中心,真的很不错 地址:vueelement仿原神实现好看的个人中心 最终效果:...
Webpack插件浅析
常用的webpack插件功能介绍: 1.HotModuleReplacementPlugin 模块热更新插件。Hot-Module-Replacement的热更新是依赖于webpack-dev-server,有时是在打包文件改变时更新打包文件或者重新加载刷新整个页面,HMR是只更新修改的部分。 HotModul…...

【Java 数据结构】反射
反射 1 定义2 用途(了解)3 反射基本信息4 反射相关的类(重要)4.1 Class类(反射机制的起源 )4.1.1 Class类中的相关方法(方法的使用方法在后边的示例当中) 4.2 反射示例4.2.1 获得Class对象的三种方式4.2.2 反射的使用 5、反射优点和缺点 1 定义 Java的反…...

LangChain结合通义千问的自建知识库
LangChain结合通义千问的自建知识库 在使用了通义千问API了之后,下一步就是构建知识库文档,使用了比较有名的LangChian,最后成果将自己的txt生成了知识向量库,最后我还把自己的论文生成了一个知识向量库,然后问他我的…...

【证书管理】实验报告
证书管理实验 【实验环境】 ISES客户端 【实验步骤】 查看证书 查看证书详细信息 选择任意证书状态,在下方“证书列表”中出现符合要求的所有证书。在“证书列表”中点击要查看证书,在右侧“证书详细信息”栏出现被选证书信息。 上述操作如图1.2.…...

App Store外区账号分享
App Store外区账号分享及注意事项 外区苹果ID分享指南什么是外区苹果ID?为什么需要外区苹果ID?获取方法分享外区苹果ID的注意事项方式2获取步骤 外区苹果ID分享指南 在数字时代,我们的生活与各种应用和服务紧密相连。 对于苹果用户而言&#…...
判断字符串是否包含正则表达式默认的特殊字符c++
判断字符串是否包含正则表达式默认的特殊字符 业务描述: 上层配置的字符列表中,既有准确的字符串,又有可以进行正则匹配的字符串,这时候需要区分出来那些是正则匹配的字符串。 思路: 判断字符串中,是否存在正则表达…...

【蓝桥杯选拔赛真题64】python数字塔 第十五届青少年组蓝桥杯python 选拔赛比赛真题解析
python数字塔 第十五届蓝桥杯青少年组python比赛选拔赛真题 一、题目要求 (注:input()输入函数的括号中不允许添加任何信息) 提示信息: 数字塔是由 N 行数堆积而成,最顶层只有一个数,次顶层两个数,以此类推。相邻层之间的数用线连接,下一层的每个数与它上一层左上…...

javaEE - 23( 21000 字 Servlet 入门 -1 )
一:Servlet 1.1 Servlet 是什么 Servlet 是一种实现动态页面的技术. 是一组 Tomcat 提供给程序猿的 API, 帮助程序猿简单高效的开发一个 web app. 构建动态页面的技术有很多, 每种语言都有一些相关的库/框架来做这件事,Servlet 就是 Tomcat 这个 HTTP…...
【sentinel流量卫兵搭建与微服务整合】
sentinel流量卫兵搭建与微服务整合 搭建sentinel dashboard控制台微服务整合搭建sentinel dashboard控制台 1、下载 官网链接 由于官网github网络原因,导致长时间下载失败。 网盘链接 网盘提取码:dwgj 2、运行 将下载jar包放在任意非中文、不包含特殊字符的目录下,重名为…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...
土建施工员考试:建筑施工技术重点知识有哪些?
《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目,核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容,附学习方向和应试技巧: 一、施工组织与进度管理 核心目标: 规…...
前端调试HTTP状态码
1xx(信息类状态码) 这类状态码表示临时响应,需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分,客户端应继续发送剩余部分。 2xx(成功类状态码) 表示请求已成功被服务器接收、理解并处…...
k8s从入门到放弃之Pod的容器探针检测
k8s从入门到放弃之Pod的容器探针检测 在Kubernetes(简称K8s)中,容器探测是指kubelet对容器执行定期诊断的过程,以确保容器中的应用程序处于预期的状态。这些探测是保障应用健康和高可用性的重要机制。Kubernetes提供了两种种类型…...

解密鸿蒙系统的隐私护城河:从权限动态管控到生物数据加密的全链路防护
摘要 本文以健康管理应用为例,展示鸿蒙系统如何通过细粒度权限控制、动态权限授予、数据隔离和加密存储四大核心机制,实现复杂场景下的用户隐私保护。我们将通过完整的权限请求流程和敏感数据处理代码,演示鸿蒙系统如何平衡功能需求与隐私安…...