Babylon.js学习之路《四、Babylon.js 中的相机(Camera)与视角控制》

在这里插入图片描述

文章目录

  • 1. 引言:为什么相机是 3D 场景的“眼睛”?
    • 1.1 相机的核心作用
    • 1.2 常见相机类型概览
  • 2. 相机基础参数解析
    • 2.1 通用属性
    • 2.2 相机坐标系
  • 3. 详解常用相机类型
    • 3.1 自由相机(FreeCamera)
    • 3.2 弧形旋转相机(ArcRotateCamera)
    • 3.3 跟随相机(FollowCamera)
    • 3.4 其他相机类型(快速概览)
  • 4. 视角交互实战技巧
    • 4.1 多相机切换
    • 4.2 自定义输入控制
    • 4.3 相机动画与过渡
  • 5. 相机性能优化与调试
    • 5.1 视锥剔除(Frustum Culling)
    • 5.2 避免过度绘制
    • 5.3 使用调试工具
  • 6. 实战任务
    • 任务 1:构建可切换的相机系统
    • 任务 2:实现“物体聚焦”功能
  • 7. 常见问题解答
  • 8. 总结与下一章预告
    • 8.1 关键知识点回顾
    • 8.2 下一章预告


1. 引言:为什么相机是 3D 场景的“眼睛”?

  • 上一章简单介绍了场景中如何添加标准形状的物体,并且介绍了如何调整物体属性,包括位置、旋转、缩放,以及父级关系的设置。
  • 这一章详细介绍一下Babylon中,相机相关的知识。涵盖相机类型、交互配置及实战技巧。

1.1 相机的核心作用

  • 定义用户视角:观察场景的位置、方向、视野范围。
  • 交互基础:通过鼠标/键盘/触控控制视角移动。

1.2 常见相机类型概览

  • 自由相机(FreeCamera
  • 弧形旋转相机(ArcRotateCamera
  • 跟随相机(FollowCamera
  • 第一人称相机(UniversalCamera

2. 相机基础参数解析

2.1 通用属性

  • 位置(Position)camera.position = new BABYLON.Vector3(x, y, z)
  • 目标(Target)camera.setTarget(new BABYLON.Vector3(x, y, z))
  • 视野(FOV)camera.fov = 0.8(弧度制,影响广角效果)。
  • 近裁面与远裁面(Clipping Planes)
    camera.minZ = 0.1; // 近裁面(避免渲染过近物体)camera.maxZ = 1000; // 远裁面(避免渲染过远物体)

2.2 相机坐标系

  • 局部坐标系:相机的移动方向基于自身朝向。
  • 世界坐标系:相机的移动方向基于全局坐标轴。

3. 详解常用相机类型

3.1 自由相机(FreeCamera)

在这里插入图片描述

  • 特点:类似第一人称射击游戏的自由移动视角。
  • 代码创建
  const freeCamera= new BABYLON.FreeCamera("freeCamera", new BABYLON.Vector3(0, 5, -10), scene);freeCamera.setTarget(BABYLON.Vector3.Zero());
  • 控制配置
    • 键盘移动:默认 WASD 控制前后左右,QE 控制升降。
    • 鼠标控制视角camera.attachControl(canvas, true)
    • 灵敏度调整
    freeCamera.speed = 0.5; // 移动速度freeCamera.angularSensibility = 2000; // 鼠标灵敏度(值越大越迟钝)
  • 其他相机配置参数
	// 相机反转freeCamera.invertRotation = true;// 相机转动速度freeCamera.inverseRotationSpeed = 3;// 相机y轴角度freeCamera.rotation.y = (rotation * Math.PI) / 180;// 添加滚轮输入freeCamera.inputs.addMouseWheel();// 开启触摸控制freeCamera.inputs.attached.mouse.touchEnabled = true;// 鼠标输入灵敏度。(默认值为2000.0)值越高,灵敏度越低。freeCamera.angularSensibility = 1300;// 定义摄像头可以看到的最小距离 太小会闪面freeCamera.minZ = 10;// 定义摄像头可以看到的最大距离freeCamera.maxZ = 20000;// 广角freeCamera.fov = 1.6;// 定义相机的默认惯性。这有助于使相机运动平稳freeCamera.inertia = 0.8// 设置相机每个窗口的大小freeCamera.viewport = new BABYLON.Viewport(0, 0, 1, 1);

3.2 弧形旋转相机(ArcRotateCamera)

在这里插入图片描述

  • 特点:围绕目标点旋转、缩放,适合展示物体。
  • 代码创建
  const arcRotatecamera = new BABYLON.ArcRotateCamera("arcCam", alpha, beta, radius, // 初始角度(弧度)、半径target, // 目标点(Vector3)scene);arcRotatecamera.attachControl(canvas, true);
  • 其他相机配置参数
    // 最大移动距离arcRotatecamera.upperRadiusLimit = 50000;// 最小移动距离arcRotatecamera.lowerRadiusLimit = 10000;// 角度灵敏度XarcRotatecamera.angularSensibilityX = 5000;// 角度灵敏度YarcRotatecamera.angularSensibilityY = 5000;// 平移灵敏度arcRotatecamera.panningSensibility = 8000;// Beta角上限arcRotatecamera.upperBetaLimit = 0;// Beta角上限arcRotatecamera.lowerBetaLimit = 0;// 纵轴最大角度,限制摄影机在场景中的移动arcRotatecamera.upperAlphaLimit = 0;// 纵轴最小角度arcRotatecamera.lowerAlphaLimit = 0;// 允许上下颠倒arcRotatecamera.allowUpsideDown = false;// 滚轮精度arcRotatecamera.wheelPrecision = 0.01;// 指针捏合精度arcRotatecamera.pinchPrecision = 0.01;// 使用自然捏缩放arcRotatecamera.useNaturalPinchZoom = false;// 广角arcRotatecamera.fov = 0.5;// 照相机渲染的最大距离arcRotatecamera.maxZ = 100000;// 照相机渲染的最小距离  太小会闪面arcRotatecamera.minZ = 5;// 让视图相机倾斜一点角度arcRotatecamera.alpha = 0;arcRotatecamera.beta = 0;// 设置相机每个窗口的大小arcRotatecamera.viewport = new BABYLON.Viewport(0, 0, 1, 1);

在这里插入图片描述
这里将 弧形旋转相机自由相机 做对比,对于同一个场景,可见 自由相机 对场景有拉伸效果,甚至对场景的显示效果都有影响。
因此,选择适合自己的相机格外重要。

  • 关键参数
    • 限制旋转角度camera.lowerBetaLimit = 0.1; camera.upperBetaLimit = Math.PI/2
    • 限制缩放范围camera.lowerRadiusLimit = 5; camera.upRadiusLimit = 20
  • 交互优化
    • 启用惯性效果:camera.inertia = 0.9(拖拽后平滑停止)。

3.3 跟随相机(FollowCamera)

  • 特点:跟随某个物体移动,适合角色扮演游戏。
  • 代码创建
  const camera = new BABYLON.FollowCamera("followCam", new BABYLON.Vector3(0, 5, -10), // 初始位置scene);camera.radius = 10; // 跟随距离camera.heightOffset = 2; // 垂直偏移camera.lockedTarget = playerMesh; // 绑定目标物体

3.4 其他相机类型(快速概览)

  • 第一人称相机(UniversalCamera):针对移动端优化的自由相机。
  • VR 设备相机(WebXRCamera):通过 WebXR 支持 VR 头显。

4. 视角交互实战技巧

4.1 多相机切换

  • 代码示例
  const camera1 = new BABYLON.FreeCamera(...);const camera2 = new BABYLON.ArcRotateCamera(...);scene.activeCamera = camera1; // 切换活动相机

4.2 自定义输入控制

  • 覆盖默认按键事件
  camera.keysUp = [87];    // W 键前进camera.keysDown = [83];  // S 键后退camera.keysLeft = [65];  // A 键左移camera.keysRight = [68]; // D 键右移
  • 添加鼠标滚轮缩放(适用于 ArcRotateCamera):
  camera.wheelPrecision = 50; // 滚轮灵敏度

4.3 相机动画与过渡

  • 平滑移动相机到新位置
  BABYLON.Animation.CreateAndStartAnimation("camMove", camera, "position",30, 120, // 帧率、总帧数camera.position, // 起始位置new BABYLON.Vector3(10, 5, 0), // 目标位置BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);

5. 相机性能优化与调试

5.1 视锥剔除(Frustum Culling)

  • 原理:只渲染相机视野内的物体。
  • Babylon.js 默认启用,可通过 mesh.isVisible = false 手动控制。

5.2 避免过度绘制

  • 调整 maxZ 值,减少远处物体渲染。

5.3 使用调试工具

  • 显示相机视锥
  camera.showFrustum = true; // 显示视锥线框
  • 实时调试参数:通过 scene.debugLayer 调整相机属性。

6. 实战任务

任务 1:构建可切换的相机系统

  • 场景中放置两个相机:自由相机(默认)和弧形旋转相机。
  • 按空格键切换相机,并添加过渡动画。

我这里添加了两个按钮,用来切换相机,其中使用 弧形旋转相机 ArcRotateCamera 模拟了上帝视角。

在这里插入图片描述
在这里插入图片描述

任务 2:实现“物体聚焦”功能

  • 点击场景中的物体,弧形旋转相机自动对准该物体并调整距离。
  mesh.actionManager = new BABYLON.ActionManager(scene);mesh.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger,() => {arcCamera.setTarget(mesh.position);arcCamera.radius = mesh.getBoundingInfo().diagonalLength * 2;}));

7. 常见问题解答

  • Q1:相机看不到物体?
    • 检查相机位置与目标点是否在物体附近。
    • 确认物体的位置未被其他物体遮挡。
  • Q2:移动端触控不灵敏?
    • 调整 angularSensibilitywheelPrecision
    • 使用 UniversalCamera 替代 FreeCamera

8. 总结与下一章预告

8.1 关键知识点回顾

  • 自由相机、弧形旋转相机的适用场景与控制优化。
  • 多相机切换与自定义交互逻辑。

8.2 下一章预告

  • 《灯光与阴影:让场景栩栩如生的关键》:学习点光源、方向光与阴影渲染技术。

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

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

相关文章

【Python】普通方法、类方法和静态方法的区分

Python 中普通方法、类方法和静态方法的区分 下面我将从多个维度对这三种方法进行详细对比,并通过示例说明它们的使用场景和区别。 1. 核心区别总结 特性普通方法(实例方法)类方法(classmethod)静态方法(staticmethod)定义装饰器无classmethodstaticmethod第一个…

geoserver发布arcgis瓦片地图服务(最新版本)

第一步:下载geoserver服务,进入bin目录启动 需要提前安装好JDK环境,1.8及以上版本 安装完成,页面访问端口,进入控制台界面,默认用户名密码admin/geoserver 第二步:下载地图 破解版全能电子地图下载器&…

Linux服务之lvs集群与dr模式部署

目录 一.lvs相关概述 1.lvs集群的工作模式 2.lvs调度算法 3.ipvsadm工具 二.DR模式部署 一.lvs相关概述 1.lvs集群的工作模式 lvs-nat:修改请求报文的目标IP,多目标IP的DNAT lvs-dr:操纵封装新的MAC地址(直接路由)lvs-tu…

OFCMS代码审计-freemaker注入sql注入xxexss文件上传

环境搭建 下载地址&#xff1a;https://gitee.com/oufu/ofcms/repository/archive/V1.1.2?formatzip SSTI模板注入&#xff08;freemaker) FreeMarker模板注入实现远程命令执行 - Eleven_Liu - 博客园 在admin中找到这个 发现请求的是这个 找到他 <#assign value"f…

一键部署NSFW检测模型:快速识别并过滤敏感图片内容

以下是对nsfw_detector的简单介绍&#xff1a; nsfw_detector是一个 NSFW 内容检测器&#xff0c;支持快速docker私有部署&#xff0c;提供API服务低资源消耗&#xff0c;2GB内存即可运行该模型&#xff0c;多核CPU自动调度加速推理 - 可以识别多种文件类型&#xff1a;图片、…

【Redis】缓存穿透、缓存雪崩、缓存击穿

1.缓存穿透 是指客户端请求的数据在缓存中和数据库中都不存在&#xff0c;这样缓存永远不会生效&#xff0c;导致请求直接穿透缓存到达数据库&#xff0c;给数据库带来压力的情况。 常见的解决方案有两种&#xff1a; 缓存空对象&#xff1a;实现简单&#xff0c;维护方便&am…

【C】初阶数据结构15 -- 计数排序与稳定性分析

本文主要讲解七大排序算法之外的另一种排序算法 -- 计数排序 目录 1 计数排序 1&#xff09; 算法思想 2&#xff09; 代码 3&#xff09; 时间复杂度与空间复杂度分析 &#xff08;1&#xff09; 时间复杂度 &#xff08;2&#xff09; 空间复杂度 4&#xff09; 计…

mysql的一个缺点

最近再移植一个从oracle转mysql的项目&#xff0c;喜提一个报错&#xff1a; You cant specify target table A016 for update in FROM clause 对应的程序代码&#xff1a; public void setCurrent(String setId, String pk, String userId) throws SysException {String[]…

Ubuntu 上安装 FTP 服务、开放指定端口并创建用户

一、安装 FTP 服务&#xff08;vsftpd&#xff09; sudo apt update sudo apt install vsftpd -y二、修改 vsftpd 配置&#xff0c;使用 21000 端口 编辑配置文件&#xff1a; sudo nano /etc/vsftpd.conf修改或添加以下配置&#xff1a; 使用以下配置文件需要修改的地方:l…

用自写的jQuery库+Ajax实现了省市联动

1. 省市联动&#xff1a;在网页上&#xff0c;选择对应的省份之后&#xff0c;动态的关联出该省份对应的市。选择对应的市之后&#xff0c;动态地关联出城市对应的区。 2. 设计数据库表 t_area &#xff08;区域表&#xff09; id(PK-自增) code name pcode ------------…

【行为型之迭代器模式】游戏开发实战——Unity高效集合遍历与场景管理的架构精髓

文章目录 &#x1f504; 迭代器模式&#xff08;Iterator Pattern&#xff09;深度解析一、模式本质与核心价值二、经典UML结构三、Unity实战代码&#xff08;背包系统遍历&#xff09;1. 定义迭代器与聚合接口2. 实现具体聚合类&#xff08;背包物品集合&#xff09;3. 实现具…

18前端项目----Vue项目收尾优化|重要知识

收尾/知识点汇总 项目收尾二级路由未登录全局路由守卫路由独享守卫图片懒加载路由懒加载打包上线 重要知识点汇总组件通信方式1. props2. 自定义事件3. 全局事件总线4. 订阅与发布pubsub5. Vuex6. 插槽 sync修饰符attrs和listeners属性children和parent属性mixin混入作用域插槽…

【Linux】基础指令(Ⅱ)

目录 1. mv指令 2. cat指令 3.echo指令 补&#xff1a;输出重定向 4. more指令 5. less指令 6. head指令和tail指令 7.date指令 时间戳&#xff1a; 8. cal指令 9. alias指令 10.grep指令 1. mv指令 语法&#xff1a;mv [选项]... 源文件/目录 目标文件/目录 …

docker及docker-compose安装及使用

docker compose &#x1f517;官网地址 一、为什么要使用docker compose 1. 简化管理 • 通过一个 YAML 文件定义和管理多容器应用。 • 简化服务间的编排与协调&#xff0c;方便环境的管理与复制。 2. 提升协作效率 • 配置文件易于共享&#xff0c;便于开发、运维等团队协…

JVM学习专题(二)内存模型深度剖析

目录 1.JVM结构体系 ​编辑 2.跨平台特性 3.JVM整体结构及内存模型 1.栈内存 1、栈帧&#xff1a; 1.局部变量表 2.操作数栈 3.动态链接 4.方法出口 2、创建对象 2.程序计数器&#xff1a; 3.方法区 ​4.堆 5.本地方法区 6.总结 1.JVM结构体系 JDK、JRE 和 JVM…

Flink之Table API

Apache Flink 的 Table API 是 Flink 提供的一种高级抽象&#xff0c;用于以声明式方式处理批处理和流处理数据。它是基于关系模型的 API&#xff0c;用户可以像编写 SQL 一样&#xff0c;以简洁、类型安全的方式编写数据处理逻辑。 一、基本概念 1. 什么是 Table API&#xf…

基于Vue3.0的高德地图api教程005:实现绘制线并编辑功能

文章目录 6、绘制多段线6.1 绘制多段线6.1.1 开启绘制功能6.1.2 双击完成绘制6.1.3 保存到数据库6.2 修改多段线6.2.1 点击线,进入编辑模式6.2.2 编辑线6.3 完整代码6、绘制多段线 6.1 绘制多段线 6.1.1 开启绘制功能 实现代码: const changeSwitchDrawPolyline = ()=>…

“redis 目标计算机积极拒绝,无法连接” 解决方法,每次开机启动redis

如果遇到以上问题 先打开“服务” 找到App Readiness 右击-启动 以管理员身份运行cmd&#xff0c;跳转到 安装redis的目录 运行&#xff1a;redis-server.exe redis.windows.conf 以管理员身份打开另一cmd窗口&#xff0c;跳转到安装redis的目录 运行&#xff1a;redis-…

Java 大视界——Java 大数据在智慧交通智能停车诱导系统中的数据融合与实时更新

面对城市停车资源错配导致的30%以上交通拥堵问题&#xff0c;本文以某新一线城市智慧交通项目为蓝本&#xff0c;深度解析Java大数据技术如何实现多源停车数据融合、动态路径规划与诱导策略优化。通过构建“感知-计算-决策”全链路系统&#xff0c;实现车位状态更新延迟<200…

牛客周赛 Round 92(再现京津冀蓝桥杯???)

1. 小红的签到题 现在小红希望你写出一个长度为 nnn 的、使用了下划线命名法命名的变量。为了显出特征&#xff0c;请保证该变量至少由两个单词组成。 输入描述: 输入一个正整数 n(3≦n≦100)&#xff0c;代表需要构造的变量长度。 输出描述: 输出一个长度为 n 的字符串&#x…