什么是Three.js,有什么特点
什么是 Three.js?
Three.js 是一个基于 WebGL 技术的 JavaScript 3D 库。它允许开发者在网页上创建和展示 3D 图形内容,而无需用户安装任何额外的插件或软件。Three.js 简化了 WebGL 的复杂性,使得即便是对图形编程不太熟悉的人也能快速上手,构建出令人印象深刻的 3D 场景和动画。
Three.js 的历史背景
Three.js 项目由西班牙开发者 Ricardo Cabello(昵称 Mr.doob)于 2010 年发起。最初,它是为了简化 WebGL 编程的难度,让更多的开发者能够利用 WebGL 的强大功能来创造丰富的视觉体验。随着时间的发展,Three.js 不断吸收社区贡献,增加了大量的新特性,并且保持了良好的兼容性和性能表现,成为了目前最流行的 3D JavaScript 库之一。
Three.js 的核心概念
使用 Three.js 创建 3D 内容的基本流程通常包括以下几个核心概念:
- 场景 (Scene): 3D 世界的容器,所有对象都必须添加到场景中才能显示。
- 相机 (Camera): 定义了从哪个角度查看场景。Three.js 支持多种类型的相机,如透视相机(Perspective Camera)和平行相机(Orthographic Camera)。
- 渲染器 (Renderer): 负责将场景中的 3D 对象通过相机视角绘制到 HTML5 的
<canvas>元素上。 - 物体 (Object): 包括几何体(Geometries)、材质(Materials)和光源(Lights)等,用于构建具体的 3D 对象。
- 动画 (Animation): 通过改变物体的位置、旋转或缩放等属性,实现动态效果。
Three.js 的主要特点
- 易于上手:Three.js 提供了高级抽象,隐藏了 WebGL 的复杂性,使得开发者可以更快地开始创作 3D 内容。
- 强大的社区支持:拥有活跃的社区,提供了大量的示例代码和教程,帮助开发者解决问题。
- 丰富的功能集:支持各种几何形状、纹理贴图、阴影计算、物理模拟等功能,满足不同应用场景的需求。
- 高性能:优化了渲染效率,能够在现代浏览器中流畅运行复杂的 3D 场景。
- 跨平台兼容性:可以在所有支持 WebGL 的平台上运行,包括桌面和移动设备。
- 模块化设计:可以通过引入特定模块来减少项目的文件大小,提高加载速度。
- 与其他技术的集成:容易与 React、Vue 等前端框架结合,也支持与后端服务进行数据交互。
Three.js 的应用场景
Three.js 的应用非常广泛,几乎涵盖了所有需要 3D 可视化的领域:
- 游戏开发:虽然 Three.js 主要用于创建 Web 游戏,但它也可以作为游戏引擎的一部分,负责渲染部分。
- 虚拟现实 (VR) 和增强现实 (AR):结合 WebXR API,Three.js 可以用来开发 VR/AR 应用程序。
- 数据可视化:利用 3D 效果展示复杂的数据关系,使信息更加直观易懂。
- 建筑设计:建筑师可以使用 Three.js 来预览他们的设计模型,或者为客户提供交互式的设计演示。
- 教育工具:创建互动的教育材料,帮助学生更好地理解科学概念。
- 广告营销:制作吸引人的 3D 广告,提升品牌形象。
- 艺术创作:艺术家们可以用 Three.js 实现创意性的数字艺术作品。
示例说明
为了更具体地理解 Three.js 的使用方式,下面通过几个简单的例子来说明如何使用 Three.js 创建基本的 3D 场景。
示例 1:创建一个简单的立方体
这个例子展示了如何使用 Three.js 创建一个基本的 3D 场景,其中包括一个立方体。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Simple Cube</title><style>body { margin: 0; }canvas { display: block; }</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>// 创建场景const scene = new THREE.Scene();// 创建相机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.01;renderer.render(scene, camera);}animate();
</script>
</body>
</html>
在这个例子中,我们首先创建了一个空的场景,然后定义了一个透视相机,并设置了它的位置。接着,我们创建了一个 WebGL 渲染器,并将其附加到页面上。之后,我们构建了一个简单的立方体,使用了基础材质并赋予了绿色。最后,我们设置了一个渲染循环,不断更新立方体的旋转状态,并重新渲染整个场景。
示例 2:添加光源和阴影
这个例子进一步扩展了前一个示例,加入了点光源和阴影效果。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Light and Shadow</title><style>body { margin: 0; }canvas { display: block; }</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>// 创建场景const scene = new THREE.Scene();// 创建相机const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);camera.position.z = 10;// 创建渲染器const renderer = new THREE.WebGLRenderer({ antialias: true });renderer.setSize(window.innerWidth, window.innerHeight);renderer.shadowMap.enabled = true;document.body.appendChild(renderer.domElement);// 创建地面const planeGeometry = new THREE.PlaneGeometry(20, 20);const planeMaterial = new THREE.MeshStandardMaterial({ color: 0xffffff, side: THREE.DoubleSide });const plane = new THREE.Mesh(planeGeometry, planeMaterial);plane.receiveShadow = true;plane.rotation.x = -Math.PI / 2;scene.add(plane);// 创建立方体const geometry = new THREE.BoxGeometry();const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });const cube = new THREE.Mesh(geometry, material);cube.castShadow = true;cube.position.set(0, 1, 0);scene.add(cube);// 添加光源const light = new THREE.PointLight(0xffffff, 1, 100);light.position.set(10, 10, 10);light.castShadow = true;light.shadow.mapSize.width = 512;light.shadow.mapSize.height = 512;light.shadow.camera.near = 0.1;light.shadow.camera.far = 50;scene.add(light);// 渲染循环function animate() {requestAnimationFrame(animate);// 旋转立方体cube.rotation.x += 0.01;cube.rotation.y += 0.01;renderer.render(scene, camera);}animate();
</script>
</body>
</html>
这里,我们在场景中添加了一个平面作为地面,并设置了接收阴影的属性。同时,创建了一个点光源,并启用了阴影投射。通过这些设置,我们可以看到立方体投射在地面上的阴影效果。
示例 3:加载外部 3D 模型
Three.js 还支持加载外部的 3D 模型文件,例如 .obj 或 .glb 文件。以下是一个加载 .glb 模型的例子。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Load 3D Model</title><style>body { margin: 0; }canvas { display: block; }</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/loaders/GLTFLoader.js"></script>
<script>// 创建场景const scene = new THREE.Scene();// 创建相机const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);camera.position.z = 15;// 创建渲染器const renderer = new THREE.WebGLRenderer({ antialias: true });renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 加载 3D 模型const loader = new THREE.GLTFLoader();loader.load('path/to/your/model.glb', function(gltf) {scene.add(gltf.scene);}, undefined, function(error) {console.error(error);});// 渲染循环function animate() {requestAnimationFrame(animate);renderer.render(scene, camera);}animate();
</script>
</body>
</html>
在这个例子中,我们使用了 GLTFLoader 来加载一个 .glb 格式的 3D 模型。加载完成后,模型会被添加到场景中。注意,你需要将 'path/to/your/model.glb' 替换为你实际的模型文件路径。
总结
Three.js 是一个功能强大且易于使用的 3D JavaScript 库,它极大地降低了使用 WebGL 创建 3D 内容的技术门槛。无论是初学者还是有经验的开发者,都可以通过 Three.js 快速构建出高质量的 3D 应用。随着 Web 技术的不断发展,Three.js 在未来将继续发挥重要作用,推动 3D 内容在互联网上的普及和创新。
相关文章:
什么是Three.js,有什么特点
什么是 Three.js? Three.js 是一个基于 WebGL 技术的 JavaScript 3D 库。它允许开发者在网页上创建和展示 3D 图形内容,而无需用户安装任何额外的插件或软件。Three.js 简化了 WebGL 的复杂性,使得即便是对图形编程不太熟悉的人也能快速上手…...
Linux笔记--基于OCRmyPDF将扫描件PDF转换为可搜索的PDF
1--官方仓库 https://github.com/ocrmypdf/OCRmyPDF 2--基本步骤 # 安装ocrmypdf库 sudo apt install ocrmypdf# 安装简体中文库 sudo apt-get install tesseract-ocr-chi-sim# 转换 # -l 表示使用的语言 # --force-ocr 防止出现以下错误:ERROR - PriorOcrFoundE…...
Unity 导出 Xcode 工程 修改 Podfile 文件
Unity 导出 Xcode 工程 修改 Podfile 文件 在 Editor 文件夹下新建 xxx.cs 脚本 实现静态方法 [PostProcessBuild]public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject){// Unity 导出 Xcode 工程自动调用这个方法 }using System.IO; using…...
UE5 slate BlankProgram独立程序系列
源码版Engine\Source\Programs\中copy BlankProgram文件夹,重命名为ASlateLearning,修改所有文件命名及内部名称。 ASlateLearning.Target.cs // Copyright Epic Games, Inc. All Rights Reserved.using UnrealBuildTool; using System.Collections.Ge…...
内存不足引发C++程序闪退崩溃问题的分析与总结
目录 1、内存不足一般出现在32位程序中 2、内存不足时会导致malloc或new申请内存失败 2.1、malloc申请内存失败,返回NULL 2.2、new申请内存失败,抛出异常 3、内存不足项目实战案例中相关细节与要点说明 3.1、内存不足导致malloc申请内存失败&#…...
C++ —— 以真我之名 如飞花般绚丽 - 智能指针
目录 1. RAII和智能指针的设计思路 2. C标准库智能指针的使用 2.1 auto_ptr 2.2 unique_ptr 2.3 简单模拟实现auto_ptr和unique_ptr的核心功能 2.4 shared_ptr 2.4.1 make_shared 2.5 weak_ptr 2.6 shared_ptr的缺陷:循环引用问题 3. shared_ptr 和 unique_…...
Linux中安装InfluxDB
什么是InfluxDB InfluxDB是一个开源的时间序列数据库,专为处理时间序列数据而设计。时间序列数据是指带有时间戳的数据点,例如传感器数据、应用程序日志、服务器指标等。InfluxDB 由 InfluxData 公司开发,广泛应用于物联网(IoT&am…...
nginx服务器实现上传文件功能_使用nginx-upload-module模块
目录 conf文件内容如下html文件内容如下上传文件功能展示 conf文件内容如下 #user nobody; worker_processes 1;error_log /usr/logs/error.log; #error_log /usr/logs/error.log notice; #error_log /usr/logs/error.log info;#pid /usr/logs/nginx.pid;events …...
ORB-SLAM2源码学习:Initializer.cc:Initializer::ComputeF21地图初始化——计算基础矩阵
前言 在平面场景我们通过求解单应矩阵H来求解位姿,但是我们在实际中常见的都是非平面场景, 此时需要用基础矩阵F求解位姿。 1.函数声明 cv::Mat Initializer::ComputeF21(const vector<cv::Point2f> &vP1, const vector<cv::Point2f>…...
C# 读取多条数据记录导出到 Word标签模板之图片输出改造
目录 应用需求 设计 范例运行环境 配置Office DCOM 实现代码 组件库引入 核心代码 调用示例 小结 应用需求 在我的文章《C# 读取多条数据记录导出到 Word 标签模板》里,讲述读取多条数据记录结合 WORD 标签模板输出文件的功能,原有输出图片的…...
NSSCTF web刷题
1 虽然找到了flag,但是我要怎么去改他的代码,让他直接输出flag呢? (好像是要得到他的json代码,这题不让看) 2 wllm应该就是他的密码,进入许可了 意思是服务器可以执行通过POST的请求方式传入参数为wllm的命令,那这就是典型的命令执行,当然,…...
对象排序得到方式
java实现 list 排序的方式,有三种 ① 对象实现Comparable 接口,然后代码里直接调用Collections.sort(list) ②使用内部类Comparator ③使用stream.sort 代码如下 实现Comparable接口的实体类 Data public class Student implements Comparable<Stud…...
Day2 洛谷1035+1047+1085+1089+1150+1151
零基础洛谷刷题记录 Day1 2024.11.18 Day2 2024.11.25 文章目录 零基础洛谷刷题记录1035:题目描述1035:解答代码1035:学习成果1047:题目描述(成功写出)1047:解答代码1047:学习成果1085…...
Linux:进程间通信之进程池和日志
一、进程池的设计 因为每一次我们要进行进程间通信都需要fork,和操作系统做交互是存在很大成本的,所以我们是不是可以提前fork出几个进程,然后当我们想要使用的时候直接去给他们安排任务,这样就减少了系统调用的次数从而提高了内存…...
详细介绍HTTP与RPC:为什么有了HTTP,还需要RPC?
目录 一、HTTP 二、RPC 介绍 工作原理 核心功能 如何服务寻址 如何进行序列化和反序列化 如何网络传输 基于 TCP 协议的 RPC 调用 基于 HTTP 协议的 RPC 调用 实现方式 优点和缺点 使用场景 常见框架 示例 三、问题 问题一:是先有HTTP还是先有RPC&…...
Paddle Inference部署推理(十二)
十二:Paddle Inference推理 (python)API详解 15. PredictorPool 类 PredictorPool 对 Predictor 进行了简单的封装,通过传入 config 和 thread 的数目来完成初始化,在每个线程中,根据自己的线程 id 直接从…...
外观模式 (Facade Pattern)
外观模式 (Facade Pattern) 外观模式是一种 结构型设计模式,通过为子系统中的一组接口提供一个统一的高层接口,简化了子系统的使用,让复杂系统更易于访问。 原理 核心思想: 提供一个 统一的接口 来访问子系统中的多个接口&#…...
人工智能-深度学习-Torch框架-手动构建回归流程
from sklearn.datasets import make_regression import math import random import torch from sklearn.datasets import make_regression: 导入make_regression函数,用于生成回归数据集。 import math: 导入math模块,用于进行数学计算,例如…...
SpringBoot源码解析(五):准备应用环境
SpringBoot源码系列文章 SpringBoot源码解析(一):SpringApplication构造方法 SpringBoot源码解析(二):引导上下文DefaultBootstrapContext SpringBoot源码解析(三):启动开始阶段 SpringBoot源码解析(四):解析应用参数args Sp…...
MySQL面试-1
InnoDB中ACID的实现 先说一下原子性是怎么实现的。 事务要么失败,要么成功,不能做一半。聪明的InnoDB,在干活儿之前,先将要做的事情记录到一个叫undo log的日志文件中,如果失败了或者主动rollback,就可以通…...
别再硬调PI参数了!手把手教你用MATLAB/Simulink搞定PMSM FOC电流环整定(附模型下载)
永磁同步电机FOC控制:从电流环整定到系统优化的工程实践 永磁同步电机(PMSM)因其高效率、高功率密度和优异的动态性能,在工业驱动、电动汽车和航空航天等领域得到广泛应用。而磁场定向控制(FOC)作为PMSM的主…...
从零开始:基于 Chroma+Ollama 的本地知识库搭建与智能问答实战指南
1. 为什么选择 ChromaOllama 组合? 如果你正在寻找一个既轻量又强大的本地知识库解决方案,Chroma 和 Ollama 的组合绝对值得考虑。我最初接触这个组合是因为需要一个完全离线的知识管理系统,经过多次对比测试后发现,这对搭档在易用…...
为什么conda装不上opencv-python?深入解析conda与pip的包管理差异
为什么conda装不上opencv-python?深入解析conda与pip的包管理差异 在Python生态系统中,conda和pip是最常用的两种包管理工具。许多开发者习惯使用conda创建和管理虚拟环境,但在安装某些特定包如opencv-python时,却常常遇到"P…...
LabVIEW高手进阶:巧用层叠移位寄存器,轻松实现数据队列与历史状态追踪
LabVIEW高手进阶:巧用层叠移位寄存器实现工业级数据流处理 在工业自动化测试和实时信号处理领域,数据流的连续处理能力往往决定着整个系统的可靠性。传统的数据缓存方案要么消耗过多内存资源,要么引入难以预测的延迟,而LabVIEW中一…...
QWEN-AUDIO声波可视化效果展示:CSS3动态波形+玻璃拟态UI交互截图
QWEN-AUDIO声波可视化效果展示:CSS3动态波形玻璃拟态UI交互截图 基于通义千问 Qwen3-Audio 架构构建的新一代语音合成系统,集成情感指令微调与声波可视化交互,致力于提供具有"人类温度"的超自然语音体验。 1. 视觉交互效果全景展示…...
HS6621CG低功耗调试实战:从5uA到50uA,我踩过的那些坑(附sysdump日志分析)
HS6621CG低功耗调试实战:从5uA到50uA的排查指南 当你的HS6621CG蓝牙芯片功耗从理想的5uA飙升到50uA时,那种感觉就像看着手机电量在眼前飞速下降。作为一款主打低功耗的蓝牙SoC,HS6621CG在实际应用中却常常因为各种隐蔽问题导致功耗异常。本文…...
知识蒸馏(Knowledge Distillation)完全指南:原理、实践与进阶
一句话概括:知识蒸馏是一种模型压缩技术,它让一个轻量级的“学生模型”模仿一个高性能的“教师模型”的输出行为,从而在保持小体积、低延迟的同时,获得接近大模型的能力。一、为什么需要知识蒸馏?—— 大模型的“奢侈”…...
SOONet模型Python从入门到集成:环境配置与核心调用
SOONet模型Python从入门到集成:环境配置与核心调用 如果你刚接触AI模型,想用Python把SOONet这样的模型跑起来,可能会觉得有点无从下手。环境怎么配?依赖库怎么装?模型文件放哪里?代码怎么写?这…...
如何突破微信设备限制?WeChatPad带来的多设备协同新体验
如何突破微信设备限制?WeChatPad带来的多设备协同新体验 【免费下载链接】WeChatPad 强制使用微信平板模式 项目地址: https://gitcode.com/gh_mirrors/we/WeChatPad 问题引入:微信生态的设备枷锁 当代数字生活中,微信已成为不可或缺…...
TIA Portal精智面板动画外观实战:从基础图形到变量控制
1. 精智面板动画外观入门指南 第一次接触TIA Portal的精智面板动画功能时,我被它强大的可视化能力惊艳到了。简单拖拽几个图形,关联PLC变量,就能实现酷炫的工业界面效果。下面我就用最直白的语言,带大家从零开始玩转这个功能。 首…...
