当前位置: 首页 > backend >正文

1.Three.js 场景(Scene)详解

✨ Three.js 是一款非常流行的 Web3D 渲染库,而场景 Scene 是构建三维世界的起点。本篇将带你详细了解 Three.js 中 Scene 的作用、使用方式及进阶技巧。


目录

1️⃣ 什么是 Scene?

2️⃣ Scene 的基本使用

(1)创建一个 Scene

(2)给场景设置背景色

(3)添加物体到场景中

3️⃣ Scene 中可以添加什么内容?

4️⃣ Scene 的常用属性和方法

(1)background

(2)environment

(3)add( object )

(4)remove( object )

(5)traverse( callback )

5️⃣ 进阶:多个场景的切换与管理

示例:两个 Scene 渲染

6️⃣ 小结

7️⃣ 附录:完整示例(简单立方体)

❤️ 如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、评论!

❤️ 关注我,持续分享 Three.js、前端三维可视化、WebGL 开发经验!


1️⃣ 什么是 Scene?

在 Three.js 中,Scene(场景)是所有物体、灯光、特效的容器。

可以理解为:

  • HTML 中的 <body> 标签

  • Unity3D 里的 "场景"

  • 一个 3D 世界的根节点

特点:

  • 统一管理物体、灯光、环境等元素

  • 可以无限添加子对象(Object3D)

  • 渲染时,Renderer 会从 Scene 出发,遍历并绘制所有对象


2️⃣ Scene 的基本使用

(1)创建一个 Scene

import * as THREE from 'three' // 创建场景对象 
const scene = new THREE.Scene()

简单吧?一行代码就完成了初始化。


(2)给场景设置背景色

scene.background = new THREE.Color(0x87CEEB) // 天空蓝

如果你希望场景有默认的颜色,可以通过 background 属性设置。

也可以设置为纹理贴图(天空盒):

const textureLoader = new THREE.TextureLoader() scene.background = textureLoader.load('sky.jpg')

(3)添加物体到场景中

// 创建一个立方体 
const geometry = new THREE.BoxGeometry(1, 1, 1) const material = new THREE.MeshBasicMaterial({ color: 0xff0000 }) const cube = new THREE.Mesh(geometry, material) // 将立方体加入场景 
scene.add(cube)

总结一句话
只要是 Object3D 的实例,都可以 add 到 Scene 中。


3️⃣ Scene 中可以添加什么内容?

类型说明
Mesh网格模型,基本的立方体、球体、模型等
Light各种灯光,比如环境光、点光源、平行光
Camera相机(一般不会直接添加到场景,但可以)
Group分组管理对象
Audio三维声音
Sprites精灵(2D 图标)
Particle Systems粒子系统
Helpers辅助线、坐标轴助手等

几乎你能想象到的 3D 内容,都能添加到 Scene 中。


4️⃣ Scene 的常用属性和方法

(1)background

设置场景背景,可以是纯色,也可以是贴图。

scene.background = new THREE.Color(0x000000)

(2)environment

设置环境贴图,用于 PBR 材质的环境反射。

const cubeTextureLoader = new THREE.CubeTextureLoader() const environmentMap = cubeTextureLoader.load([ 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' ]
) scene.environment = environmentMap

如果你使用物理材质(MeshStandardMaterialMeshPhysicalMaterial),设置 environment 可以让模型产生真实的反射效果!


(3)add( object )

将一个对象加入场景。

scene.add(mesh) scene.add(light) scene.add(group)

(4)remove( object )

从场景中移除对象。

scene.remove(mesh)

注意:如果移除后希望彻底释放内存,还需要手动调用 .dispose() 销毁材质、几何体、纹理等资源!


(5)traverse( callback )

遍历场景下所有子对象(递归),常用于批量设置材质、批量销毁对象等场景。

scene.traverse(function (child) { if (child.isMesh) { child.material.color.set(0x00ff00) } 
})

5️⃣ 进阶:多个场景的切换与管理

Three.js 支持多个场景并行渲染,比如:

  • 不同的地图区域

  • 镜头切换

  • 小地图(主视角 + 小窗口)

示例:两个 Scene 渲染

const scene1 = new THREE.Scene() const scene2 = new THREE.Scene() // 创建两个不同的物体 
const mesh1 = new THREE.Mesh(new THREE.BoxGeometry(), new THREE.MeshBasicMaterial({ color: 0xff0000 })) const mesh2 = new THREE.Mesh(new THREE.SphereGeometry(), new THREE.MeshBasicMaterial({ color: 0x00ff00 })) scene1.add(mesh1) scene2.add(mesh2) // 渲染时可以切换不同场景 
function render() { renderer.render(scene1, camera) // renderer.render(scene2, camera) requestAnimationFrame(render) 
} render()

只需更换 renderer.render(scene, camera) 的第一个参数,即可切换要渲染的场景。


6️⃣ 小结

  • Scene 是 Three.js 的核心容器,承载了所有可渲染元素。

  • 正确理解 Scene,有助于搭建更清晰的 3D 世界结构。

  • backgroundenvironmentaddremovetraverse 是日常开发必备。

  • 场景之间可以灵活切换,满足不同项目需求。


7️⃣ 附录:完整示例(简单立方体)

import * as THREE from 'three' // 创建场景 
const scene = new THREE.Scene() 
scene.background = new THREE.Color(0xcccccc) // 创建相机 
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000) 
camera.position.z = 5 // 创建渲染器 
const renderer = new THREE.WebGLRenderer() 
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement) // 创建一个立方体 
const geometry = new THREE.BoxGeometry() 
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }) 
const cube = new THREE.Mesh(geometry, material) 
scene.add(cube) // 动画循环 
function animate() { requestAnimationFrame(animate) cube.rotation.x += 0.01 cube.rotation.y += 0.01renderer.render(scene, camera) 
} 
animate()

❤️ 如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、评论!

❤️ 关注我,持续分享 Three.js、前端三维可视化、WebGL 开发经验!

http://www.xdnf.cn/news/327.html

相关文章:

  • Ext系列⽂件系统
  • Attention 机制核心 - Transformer 的基石
  • CVE-2023-46604漏洞复现与深度分析
  • 他吞吞吐吐他吞吞吐吐
  • 前沿篇|CAN XL 与 TSN 深度解读
  • 管家婆工贸ERP BB034.销售订单保存获取价格跟踪
  • 如何模拟浏览器行为获取网页中的隐藏表单数据?
  • 动态规划入门:4种背包问题大纲
  • 自适应布局,平均分配,自动换行,上下对齐
  • C++常用锁总结
  • 需求:金额字段要求只能输入两位且直接进行截断
  • 楼梯上下检测数据集VOC+YOLO格式5462张2类别
  • ifconfig -bash: ifconfig: command not found
  • bulk-seq分析,表达量你使用fpkm?还是tpm?
  • 邮件自动回复助手(Rasa/SMTP)实现教程
  • 【Triton 教程】triton_language.full
  • 代码随想录算法训练营第二十一天
  • 【认知觉醒】是什么? 如何做到 ? ( 持续更新ing )
  • 2021 CCF CSP-S2.廊桥分配
  • Arduino无线体感机器手——问题汇总
  • 土建施工员备考经验分享
  • o3和o4-mini的升级有哪些亮点?
  • JS反混淆网站
  • 使用MQTT协议实现VISION如何与Node-red数据双向通信
  • 每日算法-250418
  • 基于autoware1.14的实车部署激光雷达循迹,从建图、定位、录制轨迹巡航点、到实车运行。
  • linux查看及修改用户过期时间
  • Flutter_学习记录_状态管理之GetX
  • 从Archery到NineData:积加科技驱动数据库研发效能与数据安全双升级
  • C++:PTA L1-006 连续因子