Three.js相机Camera控件知识梳理
目录
1. 相机类型1.1 正交相机1.2 透视相机2. 相机属性2.1 视角(FOV)2.2 宽高比(Aspect)2.3 近裁剪面(Near)和远裁剪面(Far)3. 不同方向的投影视图3.1 x轴方向观察3.2 y轴方向观察3.3 z轴方向观察z轴方向观察4. 相机动画(.position和.lookAt())4.1 相机运动动画4.2 相机圆周运动相机圆周运动4.3 执行lookAt()计算相机视线方向5. 相机控件OrbitControls5.1 OrbitControls使用6. 相机控件MapControls6.1 MapControls使用7. 窗口变化的自适应渲染7.1 正投影相机OrthographicCamera自适应渲染7.2 透视投影相机PerspectiveCamera自适应渲染1. 相机类型
Three.js 主要提供了两种类型的相机:正交相机(OrthographicCamera)和透视相机(PerspectiveCamera)。
1.1 正交相机
正交相机(OrthographicCamera)使用正交投影进行渲染。在正交投影中,物体的大小不会随着距离的增加而减小,这意味着所有物体在渲染时保持相同的尺寸,不受距离的影响。这种相机在制作 2D 游戏和 CAD 工具等应用中非常有用。
【资料图】
创建正交相机的代码如下:
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 | 渲染空间的下边界 |
near | near属性表示的是从距离相机多远的位置开始渲染,一般情况会设置一个很小的值。 默认值0.1 |
far | far属性表示的是距离相机多远的位置截止渲染,如果设置的值偏小小,会有部分场景看不到。 默认值2000 |
1.2 透视相机
透视相机(PerspectiveCamera)使用透视投影进行渲染。在透视投影中,物体的大小会随着距离的增加而减小,这使得远离相机的物体看起来更小,符合现实世界中的透视效果。这种相机在制作 3D 游戏和仿真应用中非常常见。
创建透视相机的代码如下:
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轴方向观察
// 通过UI按钮改变相机观察角度 document.getElementById("x").addEventListener("click", function () { camera.position.set(500, 0, 0); //x轴方向观察 camera.lookAt(0, 0, 0); //重新计算相机视线方向 })
3.2 y轴方向观察
// 通过UI按钮改变相机观察角度 document.getElementById("y").addEventListener("click", function () { camera.position.set(0, 500, 0); //y轴方向观察 camera.lookAt(0, 0, 0); //重新计算相机视线方向 })
3.3 z轴方向观察z轴方向观察
// 通过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
,就可以获得一个动画效果。
课件案例源码是一个工厂模型,相机在空中俯视工厂,如果在渲染循环中不停地改变相机位置,这时候产生的视觉效果,就好比你在天上运动,看地面的效果。
// 渲染循环 function render() { camera.position.z -= 0.3;//相机直线运动动画 renderer.render(scene, camera); requestAnimationFrame(render); } render();
4.2 相机圆周运动相机圆周运动
在渲染循环中,改变相机位置,在XOZ平面上绕着y轴圆周运动。
// 渲染循环 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()
方法
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度旋转预览效果,改变透视投影相机距离模型的距离,就可以改变相机能看到的视野范围。
// 引入轨道控制器扩展库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本质上就是改变相机的参数,比如相机的位置属性、相机目标观察点。
// 引入相机控件`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
事件监听器:
window.addEventListener("resize", onWindowResize);
接下来,我们定义 onWindowResize
函数。在这个函数中,我们需要完成以下任务:
aspect
)。更新相机的投影矩阵。更新渲染器的大小。
7.1 正投影相机OrthographicCamera自适应渲染
// 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自适应渲染
// 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的资料请关注脚本之家其它相关文章!
标签:

进入了发展快车道 冷链行业市场规模正在快速膨胀
2022-03-21

行业正站在风口 数字化时代在为传统的自行车产业赋能
2022-03-21

以做强实体经济支撑为重点 成都单个项目年度计划投资同比提升
2022-03-21

拥有多个国际赛事的直播版权 广州游戏电竞企业业绩向好
2022-03-21

投诉量激增 直播带货存在这么多问题的主要原因是什么?
2022-03-21

工作专班深入到各企业 春寒料峭挡不住松原市施工热情
2022-03-21

引导企业向提供“产品+服务”转变 湖南加快智能农机服务化转型
2022-03-21

创新平台建设和科技成果转化 德州加大力度重奖创新
2022-03-21

潜在风险进一步放大 商品房现房销售已是大势所趋
2022-03-21

有序复工复产 1—2月份工业经济发展新动能持续增强
2022-03-21
行业正站在风口 数字化时代在为传统的自行车产业赋能
以做强实体经济支撑为重点 成都单个项目年度计划投资同比提升
拥有多个国际赛事的直播版权 广州游戏电竞企业业绩向好
投诉量激增 直播带货存在这么多问题的主要原因是什么?
工作专班深入到各企业 春寒料峭挡不住松原市施工热情
引导企业向提供“产品+服务”转变 湖南加快智能农机服务化转型
创新平台建设和科技成果转化 德州加大力度重奖创新
潜在风险进一步放大 商品房现房销售已是大势所趋
有序复工复产 1—2月份工业经济发展新动能持续增强
多层次高频调度 1至2月河北省工业运行先行指标稳中有增
以车路协同为基础 智能交通推动城市交通绿色高质量发展
人才短板成为制约产业链高质量发展的关键节点
通过技术手段整合调配供给资源 家政行业不断提质扩容
强化产业链深层次合作 加强重大装备国产化“一条龙”模式构建
如何进一步提升纳税人缴费人的减税降费获得感?
探索建设大数据及网络安全示范试点城市有哪些积极意义?
对制造业中小微企业实施缓缴税费政策有哪些积极意义?
进一步增强自我保护意识 消费者需注意辨别谨慎消费
将“走出去”变“请进来” 西安贸易产业转移承接作用不断得到增强
厦门应如何融入“数字中国”的重大战略发展大局?
江苏省如何不断满足老人日益增长的养老服务需求?
建设一体化的职业健康信息管理平台 天津职业人群保障加强
潜力持续释放 1—2月乡村消费品市场恢复略好于城镇
直接对接社会化服务 楼宇调解室将整体提升青岛劳动争议水平
成功化解纠纷11.47万件 银保监会服务质量日趋提高
春雷响百虫出 惊蛰文化在其他方面有了进一步发展
青绿山水画在古代山水画发展史上有着怎样的影响与地位?
开播即爆款 “文化类节目收视率低”这一固有印象被推翻
涵盖了109件真迹作品 凯斯·哈林展览将持续至6月13日


- 带有一点自信的自嘲 “隔路”是另一种味道的“凡尔赛”
- 与文渊阁前后呼应 “何以中国”特展隆重致敬文化大成
- 严重者可造成暂时性失明 享受冰雪运动要注意眼睛的健康防护
- 种类繁多让人眼花缭乱 选购牛奶时需要重点关注什么?
- 网课让孩子感到不安焦虑怎么办?八问八答回应广大家长关切
- 循环系统很容易受到刺激 “倒春寒”期间老人该如何做?
- 青少年患者睡眠问题日趋增加 9条建议为孩子助眠
- 我国肥胖人群正逐年递增 不良饮食习惯是重要诱因
- 如何减少噪声对听力的损伤?这份耳部和听力保健小贴士请收好
- 强化住房限购措施 西安限购限售范围进一步扩大
- 多种方式增加供给 进一步降低新市民和青年人的居住成本
- 预计9月下旬海口可实现安居房申请网上办理
- 政策调控力度持续升级 8月百城二手房市场均价止涨转跌
- 8月中国新房找房热度依然保持平稳 环比微涨0.2%
- 进一步加强商品房销售价格备案管理 今年全国楼市调控刷新历史纪录
- 西安第二批集中供地中28宗为现场拍卖方式出让
- 细分化需求得到释放 房屋居住的属性越发凸显
- 佛山顺德龙江近日挂牌商住地起拍价约19.88亿元
- 青岛市4宗地竞品质抽签结果出炉 地溢价均约15%
- 坚持政策支持、多方参与 浙江版保障性租赁住房明确新增比例目标
- 简化审批流程 武汉将实现房源申请配租全程网上办
- 哈尔滨新增本土确诊病例3例 活动轨迹公布
- 哈尔滨市公布3例新增本土新冠肺炎确诊病例活动轨迹
- 山东深耕文化资源 推动旅游业高质量发展
- 今年新增952件(套)!南京大屠杀再添新证
- 四川非遗传承人张雄志:巧手捏面塑 指尖传非遗
- 10月以来我国寒潮为何如此频繁?中国气象局回应
- 56位残疾人士登上黄山 互利互勉共建生活希望
- 安徽潜山两车相撞 已致8人死亡3人受伤
- 上海洋山海关首次在出口货运渠道查获夹带卷烟
- 山西忻州古城:一城风华延续千年历史文脉
- 呼伦贝尔新巴尔虎右旗公布1例无症状感染者行动轨迹
- 新增“53+1” 内蒙古累计本土确诊病例增至185例
- 昆明公安打击破坏生物多样性犯罪 抓获130名涉案嫌疑人
- 山西朔州“11·11”较大透水事故调查报告发布 对38人问责处理
- “海关国门小卫士”竞争上岗 淘汰率接近一半
- 深圳摧毁特大品牌化妆品走私网
- 28人被问责!山西石港煤业“3·25”事故调查报告公布
- 湖南韶山以河长制带动全民治水 让每一处水面“长治久清”
- 上海市奉贤区人大常委会原党组书记袁晓林被“双开”
- 民进会员谈反映社情民意信息工作:心怀大我 敢讲实情
- 80岁“留守”奶奶短视频诉孤独 千万网友心疼:我们陪您唠嗑
- 40年来为子弟兵送出1.3万余双布鞋和鞋垫的“布鞋奶奶”走了
- 当男幼师是什么体验?他们说:有委屈尴尬 但大部分是幸福
- 庐阳警方通报幼童坠亡事件:嫌疑人已被刑拘
- 内蒙古新增本土确诊病例53例、本土无症状感染者1例
- 哈尔滨市启动部分地区第一轮全员核酸检测
- 四川通江发生两车相撞事故 致3人死亡
- 11月谣言在“身边”,别信这些无稽之谈
- 追剧为何上瘾?你追的不是剧,而是及时满足的快感