Three.js——scene场景、几何体位置旋转缩放、正射投影相机、透视投影相机
个人简介
👀个人主页: 前端杂货铺
🙋♂️学习方向: 主攻前端方向,正逐渐往全干发展
📃个人状态: 研发工程师,现效力于中国工业软件事业
🚀人生格言: 积跬步至千里,积小流成江海
🥇推荐学习:🍍前端面试宝典 🍉Vue2 🍋Vue3 🍓Vue2/3项目实战 🥝Node.js🍒Three.js🍖数据结构与算法体系教程🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧
| 内容 | 参考链接 |
|---|---|
| WebGL专栏 | WebGL 入门 |
| Three.js(一) | 创建场景、渲染三维对象、添加灯光、添加阴影、添加雾化 |
文章目录
- 前言
- 一、scene 场景
- 二、几何体位置、旋转、缩放
- 三、正射投影相机
- 四、透视投影相机
- 总结
前言
大家好,这里是前端杂货铺。
上篇文章我们学习了 创建场景、渲染三维对象、添加灯光、添加阴影、添加雾化,接下来继续我们 three.js 的学习!
在学习的过程中,如若需要深入了解或扩展某些知识,可以自行查阅 => three.js官方文档
一、scene 场景
在上篇文章中,我们已经使用过它,scene 场景能够让我们在什么地方、摆放什么东西来交给 three.js 来渲染,这是我们放置物体、灯光和摄像机的地方。
接下来,我们熟悉几个 scene 的常用 方法和属性。
| 方法名 | 用途 |
|---|---|
| add() | 向场景中添加对象 |
| getObjectByName() | 通过命名获取对象 |
| remove() | 从场景中移除对象 |
| 属性名 | 用途 |
|---|---|
| children | 返回场景中所有对象的列表 |
| fog | 设置场景中的雾化效果 |
| overrideMaterial | 强制场景中所有对象使用相同材质 |
下面代码的场景中,我们添加了两个物体:立方体和球体。
我们使用 getObjectByName() 方法实现获取球体并放大球体为原来的两倍。使用 remove 方法移除了球体。
我们使用 chidren 属性查看场景中的对象列表(由于我们删除了球体,所有只有立方体和聚光灯)。使用 fog 属性在场景中添加雾化效果。使用 overrideMaterial 强制场景中所有对象使用同一材质。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="../lib/three/three.js"></script><style>* {margin: 0;padding: 0;}</style>
</head><body><script>// 创建场景const scene = new THREE.Scene();// 创建相机 视野角度FOV、长宽比、近截面、远截面const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);// 设置相机位置camera.position.set(0, 0, 20);// 创建渲染器const renderer = new THREE.WebGLRenderer();// 设置渲染器尺寸renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 添加立方体const cubeGeometry = new THREE.BoxGeometry(2, 2, 2);// 创建立方体材质const cubeMaterial = new THREE.MeshBasicMaterial({color: 0xff0000,wireframe: false});const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);// 添加到场景scene.add(cube);// 添加球体const sphereGeometry = new THREE.SphereGeometry(1, 10, 10);// 创建球体材质const sphereMatrial = new THREE.MeshBasicMaterial({color: 0x00ff00,wireframe: true})const sphere = new THREE.Mesh(sphereGeometry, sphereMatrial);// 给球体命名sphere.name = 'sphere';// 添加到场景scene.add(sphere);// 通过命名放大球体为原来的两倍scene.getObjectByName("sphere").scale.set(2, 2, 2);// 添加灯光const spotLight = new THREE.SpotLight(0xffffff);spotLight.position.set(-10, 10, 10);scene.add(spotLight);// 查看场景中所有对象列表console.log(scene.children);// 设置场景中的雾化效果scene.fog = new THREE.Fog(0xffffff, 1, 50);// 移除立方体scene.remove(sphere);// 强制场景中所有对象使用相同材质scene.overrideMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000});const animation = () => {cube.rotation.x += 0.01;cube.rotation.y += 0.01;sphere.rotation.x += 0.01;sphere.rotation.y += 0.01;// 渲染renderer.render(scene, camera);requestAnimationFrame(animation);}animation();</script>
</body></html>

二、几何体位置、旋转、缩放
position 控制物体的位置、rotation 控制物体的旋转、scale 控制物体的缩放。
下面的代码,我们使用 单个赋值 和 方法赋值 的方式来操作几何体。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="../lib/three/three.js"></script><style>* {margin: 0;padding: 0;}</style>
</head><body><script>// 创建场景const scene = new THREE.Scene();// 创建相机 视野角度FOV、长宽比、近截面、远截面const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);// 设置相机位置camera.position.set(0, 0, 20);// 创建渲染器const renderer = new THREE.WebGLRenderer();// 设置渲染器尺寸renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 添加立方体const cubeGeometry = new THREE.BoxGeometry(2, 2, 2);// 创建立方体材质const cubeMaterial = new THREE.MeshBasicMaterial({color: 0xff0000,wireframe: false});const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);// 单个赋值 效果同下// // 位置 x => 3// cube.position.x = 3;// // 旋转 45 度// cube.rotation.x = 0.125 * Math.PI;// cube.rotation.y = 0.125 * Math.PI;// cube.rotation.z = 0.125 * Math.PI;// // x 放大 2 倍// cube.scale.x = 2;// 通过方法赋值cube.position.set(3, 0, 0);cube.rotation.set(0.125 * Math.PI, 0.125 * Math.PI, 0.125 * Math.PI);cube.scale.set(2, 1, 1);// 添加到场景scene.add(cube);// 渲染renderer.render(scene, camera);</script>
</body></html>

三、正射投影相机
正射投影相机 new THREE.OrthographicCamera(渲染的图片中物体的大小都保持不变),它接收六个参数:
- left:左边界
- right:右边界
- top:上边界
- bottom:下边界
- near:近面
- far:远面
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="../lib/three/three.js"></script><style>* {margin: 0;padding: 0;}</style>
</head><body><script>// 创建场景const scene = new THREE.Scene();// 正射投影相机const camera = new THREE.OrthographicCamera(-10, 10, 10, -10, 1, 1000)// 设置相机位置camera.position.set(0, 0, 20);// 创建渲染器const renderer = new THREE.WebGLRenderer();// 设置渲染器尺寸renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 添加立方体const cubeGeometry = new THREE.BoxGeometry(2, 2, 2);// 创建立方体材质const cubeMaterial = new THREE.MeshBasicMaterial({color: 0xff0000,wireframe: false});const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);cube.rotation.set(0.125 * Math.PI, 0.125 * Math.PI, 0.125 * Math.PI);// 添加到场景scene.add(cube);// 渲染renderer.render(scene, camera);</script>
</body></html>

四、透视投影相机
正射投影相机 new THREE.PerspectiveCamera (用来模拟人眼所看到的景象,近大远小),它接收四个参数:
- fov:视角
- aspect:宽高比
- near:近面
- far:远面
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="../lib/three/three.js"></script><style>* {margin: 0;padding: 0;}</style>
</head><body><script>// 创建场景const scene = new THREE.Scene();// 透视投影相机 视野角度FOV、长宽比、近截面、远截面const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);// 设置相机位置camera.position.set(0, 0, 20);// 创建渲染器const renderer = new THREE.WebGLRenderer();// 设置渲染器尺寸renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 添加立方体const cubeGeometry = new THREE.BoxGeometry(2, 2, 2);// 创建立方体材质const cubeMaterial = new THREE.MeshBasicMaterial({color: 0xff0000,wireframe: false});const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);cube.rotation.set(0.125 * Math.PI, 0.125 * Math.PI, 0.125 * Math.PI);// 添加到场景scene.add(cube);// 渲染renderer.render(scene, camera);</script>
</body></html>

总结
本篇文章我们熟悉了scene场景的一些方法和属性的使用,认识了如何对几何体进行位置、选择和缩放的操作,并简单了解了正射投影相机和透视投影相机。
更多内容扩展请大家自行查阅 => three.js官方文档,真心推荐读一读!!
好啦,本篇文章到这里就要和大家说再见啦,祝你这篇文章阅读愉快,你下篇文章的阅读愉快留着我下篇文章再祝!
参考资料:
- Three.js 官方文档
- WebGL+Three.js 入门与实战【作者:慕课网_yancy】

相关文章:
Three.js——scene场景、几何体位置旋转缩放、正射投影相机、透视投影相机
个人简介 👀个人主页: 前端杂货铺 🙋♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…...
springboot集成rabbitmq
一 添加pom <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId> </dependency>二,配置yml spring:rabbitmq:host: 192.168.56.200port: 5672username: adminpasswor…...
腾讯云轻量4核8G12M应用服务器性能测评和优惠价格表
腾讯云4核8G服务器价格:轻量4核8G12M优惠价格646元15个月、CVM S5服务器4核8G配置1437元买1年送3个月。腾讯云4核8G服务器支持多少人同时在线?支持30个并发数,可容纳日均1万IP人数访问。腾讯云百科txybk.com整理4核8G服务器支持多少人同时在线…...
判断点在多边形内的算法
在计算几何中,判定点是否在多边形内,是个非常有趣的问题。通常有两种方法: 一、Crossing Number(交叉数) 它计算从点P开始的射线穿过多边形边界的次数。当“交叉数”是偶数时,点在外面;当它是奇数时&…...
Network AIS Receiver R400N
目录 Introduction OVERVIEW BASIC FEATURES APPLICATIONS SPECIFICATIONS Introduction OVERVIEW The R400N provides a method of monitoring the position, speed and heading of AIS vessels within VHF range. It can decode of Class A, Class B, Aids to Navigat…...
JavaScript循环
JavaScript的循环有两种,一种是for循环,通过初始条件、结束条件和递增条件来循环执行语句块: var x 0; var i; for (i1; i<10000; i) { x x i; } x; // 50005000 for循环的3个条件都是可以省略的,如果没有退出循环的判断条件…...
9Proxy,跨境电商一站式解决方案
文章目录 跨境电商什么是跨境电商跨境电商的机遇跨境电商技术支撑 海外代理IP什么是海外代理IP海外代理IP的作用如何选择海外代理IP 9Proxy9Proxy的优势9Proxy的解决方案价格汇总搜索引擎优化市场调查多重核算数据抓取广告技术 价格上手体验注册登录下载安装数据采集 总结福利 …...
ObjectiveC-08-OOP面向对象程序设计-类的分离与组合
本节用一简短的文章来说下是ObjectiveC中的类。类其实是OOP中的一个概念,概念上简单来讲类是它是一组关系密切属性的集合,所谓的关系就是对现实事物的抽象。 上面提到的关系包括很多种,比如has a, is a,has some等&…...
Qt 总结
由于工作需要用到Qt。把过程中学习到的东西记录下来,希望能帮到他人和将来的自己。 由于需要快速实现需求,所以对Qt只是使用,并没有对原理的深入理解。 故此文只适合入门,不适合深入学习Qt。 文章目录 安装&维护示例&教…...
中间件复习之-RPC框架
什么是RPC框架? RPC(Remote Procedure Call):远程过程调用。当多个应用部署在多个服务器上时,由于他们不在一个内存空间上,因此需要网络来进行通信,而RPC允许它像调用本地方法一样调用远程服务。 RPC原理 服务消费方通过RPC客户…...
AcWing 787. 归并排序——算法基础课题解
AcWing 787. 归并排序 文章目录 题目描述CGo模板 题目描述 给定你一个长度为 n 的整数数列。 请你使用归并排序对这个数列按照从小到大进行排序。 并将排好序的数列按顺序输出。 输入格式 输入共两行,第一行包含整数 n。 第二行包含 n 个整数(所有…...
力扣1379---找出克隆二叉树的相同节点(Java、DFS、简单题)
目录 题目描述: 思路描述: 代码: (1): (2): 题目描述: 给你两棵二叉树,原始树 original 和克隆树 cloned,以及一个位于原始树 ori…...
FLink学习(三)-DataStream
一、DataStream 1,支持序列化的类型有 基本类型,即 String、Long、Integer、Boolean、Array复合类型:Tuples、POJOs 和 Scala case classes Tuples Flink 自带有 Tuple0 到 Tuple25 类型 Tuple2<String, Integer> person Tuple2.…...
Failed to resolve import “Home/components/HomeNew.vue“. Does the file exist?
错误信息 [plugin:vite:import-analysis] Failed to resolve import "/apis/home.js" from "src/views/Home/components/HomeNew.vue". Does the file exist? 错误原因 路径错误 解决方法...
《价值》-张磊-高瓴资本-3-建立人脉和信任;顺应趋势,把握机遇;
第三章 价值投资初试炼 2005.6.1 创办高瓴资本 许多人问我为什么一直在创业,其实我倒没想到自己非要创业成功不可,只是觉得一定要做点事,做点有意义的事。归根到底,可能是“爱折腾,不满足现状,爱挑战自己”…...
游戏引擎中的物理应用
一、 角色控制器 Character Controller和普通的动态对象(Dynamic Actor )是不同的,主要的三个特点是: 它拥有可控制的刚体间的交互假设它是有无穷的摩擦力(可以站停在位置上),没有弹性加速和刹车几乎立即…...
复现k8s黄金票据学习
1.什么是黄金票据 在 Kubernetes 中,"黄金票据"并不是一个常见的术语。可能你想了解的是服务账户(Service Account)。服务账户是 Kubernetes 中用于身份验证和授权的一种机制。它们允许 Pods 或其他工作负载在 Kubernetes 集群中与…...
08-JavaScript BOM定时器及JS动画
1. 设置定时器 1.1设置超时定时器 超时调用需要使用window对象的setTimeout()方法,该方法接受两个参数:调用函数或计算表达式和以毫秒为单位的时间(即在执行代码前需要等待多少毫秒)。 //setTimeout(callback, after) //callba…...
边缘计算盒子与云计算:谁更适合您的业务需求?
边缘计算盒子和云计算,这两个概念听起来可能有点复杂,但其实它们就是两种不同的数据处理方式。那谁更适合您的业务需求呢?咱们来详细说说。 边缘计算盒子,就像是个小型的数据处理中心,放在离你业务现场比较近的地方。它…...
浅聊什么是Redis?
需求:MySQL面临大量的查询,即读写操作,因此类比CPU,给数据加缓存,Redis诞生。应用程序从MySQL查询的数据,在Redis设置缓存(记录在内存中,无需IO操作),后再需要…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
