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

其参数分别为:

  1. fov :摄像机视锥体垂直视野角度,以角度来表示。默认值是50

  2. aspect :摄像机视锥体宽高比:默认值为 1,一般用渲染器到宽高比

  3. near:摄像机视锥体近截面,默认值是0.1

  4. 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 = "正交相机";
});

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

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

相关文章

【力扣】Z字形变换,模拟+直接构造

Z字形变换原题地址 方法一&#xff1a;利用二维矩阵模拟 对于特殊情况&#xff0c;z字形变换后只有一行或只有一列&#xff0c;则变换后的字符串和原字符串相同。 对于一般情况&#xff0c;我们可以考虑按照题目要求&#xff0c;把字符串按照Z字形存储到二维数组中&#xff…

Django模板(一)

一、基本规则 作为一个Web框架,Django需要一种方便的方式来动态生成HTML。最常用的方法依赖于模板。模板包含所需HTML输出的静态部分以及描述如何插入动态内容的特殊语法 1.1、django默认模板 在settings中配置: TEMPLATES = [{BACKEND: django.template.backends.django.…

车位检测,YOLOV8,OPENCV调用

车位检测YOLOV8NANO,opencv调用 车位检测&#xff0c;YOLOV8NANO&#xff0c;训练得到PT模型&#xff0c;然后转换成ONNX&#xff0c;OPENCV的DNN调用&#xff0c;支持C,PYTHON,ANDROID

QXlsx Qt操作excel

QXlsx 是一个用于处理Excel文件的开源C库。它允许你在你的C应用程序中读取和写入Microsoft Excel文件&#xff08;.xlsx格式&#xff09;。该库支持多种操作&#xff0c;包括创建新的工作簿、读取和写入单元格数据、格式化单元格、以及其他与Excel文件相关的功能。 支持跨平台…

Mysql索引优化建议

1&#xff0c;最左前缀法则 如果为一张表创建了多列的组合索引&#xff0c;要遵守最左前缀法则。就是指查询从索引的最左前列开始并且不要跳过索引中的列。&#xff08;因为Mysql的InnoDB引擎的索引树是一个按顺利排序存储的数据结构&#xff08;BTREE&#xff09;&#xff0c…

第01课:自动驾驶概述

文章目录 1、无人驾驶行业概述什么是无人驾驶智慧出行大趋势无人驾驶能解决什么问题行业趋势无人驾驶的发展历程探索阶段&#xff08;2004年以前&#xff09;发展阶段&#xff08;2004年-2016年&#xff09;成熟阶段&#xff08;2016年以后&#xff09; 2、无人驾驶技术路径无人…

uniapp canvas游标卡尺效果

效果 根据公司业务仿照写的效果。原项目从微信小程序转uniapp,未测试该效果在android端效果。 uniapp直接使用canvas不可做子组件,否则无效果显示,其次显示时要考虑页面渲染超时的问题。 如效果所见,可以设置取值精度。 gitee地址:project_practice: 项目练习 - Gitee.…

【LangChain-04】利用权重和偏差跟踪和检查LangChain代理的提示

利用权重和偏差跟踪和检查LangChain代理的提示 一、说明 考虑到&#xff08;生成&#xff09;人工智能空间&#xff0c;&#xff08;自主&#xff09;代理现在无处不在&#xff01;除了更强大且幸运的是开放的大型语言模型&#xff08;LLM&#xff09;之外&#xff0c;LangCh…

宝塔+php+ssh+vscode+虚拟机 远程调试

远程(虚拟机)宝塔 安装扩展 配置文件添加&#xff0c;zend_extension看你虚拟机的具体位置 [Xdebug] zend_extension/www/server/php/74/lib/php/extensions/no-debug-non-zts-20190902/xdebug.so xdebug.modedebug xdebug.start_with_requesttrigger xdebug.client_host&quo…

Dockerfile文件参数配置和使用

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

Qt安装配置教程windows版(亲测可行)

QT为嵌入式系统提供了大量的库和可重用组件。 WPS Office&#xff0c;咪咕音乐&#xff0c;Linux桌面环境等都是QT开发的。 下载 windows版Qt下载地址 也可下载5.9.0或者5.12.0版的 安装 选择安装位置&#xff08;不可以是中文&#xff09;点击下一步。 下个步骤是协议&…

SpringBoot:@Profile注解和Spring EL

&#x1f3e1;浩泽学编程&#xff1a;个人主页 &#x1f525; 推荐专栏&#xff1a;《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》 &#x1f6f8;学无止境&#xff0c;不骄不躁&#xff0c;知行合一 文章目录 前言一、Prof…

GLSL ES 1.0

GLSL ES 概述 写在前面 程序是大小写敏感的每一个语句都应该以英文分号结束一个shader必须包含一个main函数&#xff0c;该函数不接受任何参数&#xff0c;并且返回voidvoid main() { }数据值类型 GLSL支持三种数据类型&#xff1a; 整型浮点型&#xff1a;必须包含小数点&…

【大模型上下文长度扩展】FlashAttention:高效注意力计算的新纪元

FlashAttention&#xff1a;高效注意力计算的新纪元 核心思想核心操作融合&#xff0c;减少高内存读写成本分块计算&#xff08;Tiling&#xff09;&#xff0c;避免存储一次性整个矩阵块稀疏注意力&#xff0c;处理长序列时的效率问题利用快速 SRAM&#xff0c;处理内存与计算…

二分查找------蓝桥杯

题目描述&#xff1a; 请实现无重复数字的升序数组的二分查找 给定一个元素升序的、无重复数字的整型数组 nums 和一个目标值 target&#xff0c;写一个函数搜索 nums 中的target&#xff0c;如果目标值存在返回下标 (下标从0 开始)&#xff0c;否则返回-1 数据范围: 0 < l…

【Java 数据结构】反射

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

网络编程套接字

目录 本节重点一、预备知识1.1 理解源IP地址和目的IP地址1.2 认识端口号1.3 理解 "端口号" 和 "进程ID"1.4 理解源端口号和目的端口号1.5 认识TCP协议1.6 认识UDP协议1.7 网络字节序 二、socket编程接口2.1 socket常见的API2.2 sockaddr结构2.3 in_addr结构…

SpringBoot集成axis发布WebService服务

文章目录 1、使用maven-web项目生成server-config.wsdd文件1.1、新建maven-web项目1.1.1、新建项目1.1.2、添加依赖 1.2、编写服务接口和实现类1.2.1、OrderService接口1.2.2、OrderServiceImpl实现类 1.3、配置deploy.wsdd文件deploy.wsdd文件 1.4、配置tomcat1.4.1、配置tomc…

MySQL数据库练习【一】

MySQL数据库练习【一】 一、建库建表-数据准备二、习题2.1. 查询部门编号为30的部门的员工详细信息2.2.查询从事clerk工作的员工的编号、姓名以及其部门号2.3.查询奖金多于基本工资的员工的信息、查询奖金小于基本工资的员工的信息2.4.查询奖金多于基本工资60%的员工的信息2.5.…

宠物空气净化器适合养猫家庭吗?除猫毛好的猫用空气净化器推荐

宠物掉毛是一个普遍存在的问题&#xff0c;尤其在脱毛季节&#xff0c;毛发似乎无处不在。这给家中的小孩和老人带来了很多麻烦&#xff0c;他们容易流鼻涕、过敏等不适。此外&#xff0c;宠物有时还会不规矩地拉扯和撒尿&#xff0c;这股气味实在是难以忍受。家人们对宠物的存…