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

什么是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 的主要特点
  1. 易于上手:Three.js 提供了高级抽象,隐藏了 WebGL 的复杂性,使得开发者可以更快地开始创作 3D 内容。
  2. 强大的社区支持:拥有活跃的社区,提供了大量的示例代码和教程,帮助开发者解决问题。
  3. 丰富的功能集:支持各种几何形状、纹理贴图、阴影计算、物理模拟等功能,满足不同应用场景的需求。
  4. 高性能:优化了渲染效率,能够在现代浏览器中流畅运行复杂的 3D 场景。
  5. 跨平台兼容性:可以在所有支持 WebGL 的平台上运行,包括桌面和移动设备。
  6. 模块化设计:可以通过引入特定模块来减少项目的文件大小,提高加载速度。
  7. 与其他技术的集成:容易与 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&#xff1f; Three.js 是一个基于 WebGL 技术的 JavaScript 3D 库。它允许开发者在网页上创建和展示 3D 图形内容&#xff0c;而无需用户安装任何额外的插件或软件。Three.js 简化了 WebGL 的复杂性&#xff0c;使得即便是对图形编程不太熟悉的人也能快速上手…...

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 防止出现以下错误&#xff1a;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文件夹&#xff0c;重命名为ASlateLearning&#xff0c;修改所有文件命名及内部名称。 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申请内存失败&#xff0c;返回NULL 2.2、new申请内存失败&#xff0c;抛出异常 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的缺陷&#xff1a;循环引用问题 3. shared_ptr 和 unique_…...

Linux中安装InfluxDB

什么是InfluxDB InfluxDB是一个开源的时间序列数据库&#xff0c;专为处理时间序列数据而设计。时间序列数据是指带有时间戳的数据点&#xff0c;例如传感器数据、应用程序日志、服务器指标等。InfluxDB 由 InfluxData 公司开发&#xff0c;广泛应用于物联网&#xff08;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来求解位姿&#xff0c;但是我们在实际中常见的都是非平面场景&#xff0c; 此时需要用基础矩阵F求解位姿。 1.函数声明 cv::Mat Initializer::ComputeF21(const vector<cv::Point2f> &vP1, const vector<cv::Point2f>…...

C# 读取多条数据记录导出到 Word标签模板之图片输出改造

目录 应用需求 设计 范例运行环境 配置Office DCOM 实现代码 组件库引入 ​核心代码 调用示例 小结 应用需求 在我的文章《C# 读取多条数据记录导出到 Word 标签模板》里&#xff0c;讲述读取多条数据记录结合 WORD 标签模板输出文件的功能&#xff0c;原有输出图片的…...

NSSCTF web刷题

1 虽然找到了flag,但是我要怎么去改他的代码,让他直接输出flag呢? (好像是要得到他的json代码,这题不让看) 2 wllm应该就是他的密码,进入许可了 意思是服务器可以执行通过POST的请求方式传入参数为wllm的命令&#xff0c;那这就是典型的命令执行&#xff0c;当然&#xff0c…...

对象排序得到方式

java实现 list 排序的方式&#xff0c;有三种 ① 对象实现Comparable 接口&#xff0c;然后代码里直接调用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&#xff1a;解答代码1035&#xff1a;学习成果1047&#xff1a;题目描述&#xff08;成功写出&#xff09;1047&#xff1a;解答代码1047&#xff1a;学习成果1085&#xf…...

Linux:进程间通信之进程池和日志

一、进程池的设计 因为每一次我们要进行进程间通信都需要fork&#xff0c;和操作系统做交互是存在很大成本的&#xff0c;所以我们是不是可以提前fork出几个进程&#xff0c;然后当我们想要使用的时候直接去给他们安排任务&#xff0c;这样就减少了系统调用的次数从而提高了内存…...

详细介绍HTTP与RPC:为什么有了HTTP,还需要RPC?

目录 一、HTTP 二、RPC 介绍 工作原理 核心功能 如何服务寻址 如何进行序列化和反序列化 如何网络传输 基于 TCP 协议的 RPC 调用 基于 HTTP 协议的 RPC 调用 实现方式 优点和缺点 使用场景 常见框架 示例 三、问题 问题一&#xff1a;是先有HTTP还是先有RPC&…...

Paddle Inference部署推理(十二)

十二&#xff1a;Paddle Inference推理 &#xff08;python&#xff09;API详解 15. PredictorPool 类 PredictorPool 对 Predictor 进行了简单的封装&#xff0c;通过传入 config 和 thread 的数目来完成初始化&#xff0c;在每个线程中&#xff0c;根据自己的线程 id 直接从…...

外观模式 (Facade Pattern)

外观模式 (Facade Pattern) 外观模式是一种 结构型设计模式&#xff0c;通过为子系统中的一组接口提供一个统一的高层接口&#xff0c;简化了子系统的使用&#xff0c;让复杂系统更易于访问。 原理 核心思想&#xff1a; 提供一个 统一的接口 来访问子系统中的多个接口&#…...

人工智能-深度学习-Torch框架-手动构建回归流程

from sklearn.datasets import make_regression import math import random import torch from sklearn.datasets import make_regression: 导入make_regression函数&#xff0c;用于生成回归数据集。 import math: 导入math模块&#xff0c;用于进行数学计算&#xff0c;例如…...

SpringBoot源码解析(五):准备应用环境

SpringBoot源码系列文章 SpringBoot源码解析(一)&#xff1a;SpringApplication构造方法 SpringBoot源码解析(二)&#xff1a;引导上下文DefaultBootstrapContext SpringBoot源码解析(三)&#xff1a;启动开始阶段 SpringBoot源码解析(四)&#xff1a;解析应用参数args Sp…...

MySQL面试-1

InnoDB中ACID的实现 先说一下原子性是怎么实现的。 事务要么失败&#xff0c;要么成功&#xff0c;不能做一半。聪明的InnoDB&#xff0c;在干活儿之前&#xff0c;先将要做的事情记录到一个叫undo log的日志文件中&#xff0c;如果失败了或者主动rollback&#xff0c;就可以通…...

nginx配置不缓存资源

方法1 location / {index index.html index.htm;add_header Cache-Control no-cache,no-store;try_files $uri $uri/ /index.html;#include mime.types;if ($request_filename ~* .*\.(htm|html)$) {add_header Cache-Control "private, no-store, no-cache, must-revali…...

PHP导出EXCEL含合计行,设置单元格格式

PHP导出EXCEL含合计行&#xff0c;设置单元格格式&#xff0c;水平居中 垂直居中 public function exportSalary(Request $request){//水平居中 垂直居中$styleArray [alignment > [horizontal > Alignment::HORIZONTAL_CENTER,vertical > Alignment::VERTICAL_CE…...

RabbitMQ 之 死信队列

一、死信的概念 先从概念解释上搞清楚这个定义&#xff0c;死信&#xff0c;顾名思义就是无法被消费的消息&#xff0c;字面意思可以这样理 解&#xff0c;一般来说&#xff0c;producer 将消息投递到 broker 或者直接到 queue 里了&#xff0c;consumer 从 queue 取出消息进行…...

【创建型设计模式】单例模式

【创建型设计模式】单例模式 这篇博客接下来几篇都将阐述设计模式相关内容。 接下来的顺序大概是&#xff1a;单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。 一、什么是单例模式 单例模式是一种创建型设计模式&#xff0c;它保证一个类仅有一个实例&#…...

Charles抓包工具-笔记

摘要 概念&#xff1a; Charles是一款基于 HTTP 协议的代理服务器&#xff0c;通过成为电脑或者浏览器的代理&#xff0c;然后截取请求和请求结果来达到分析抓包的目的。 功能&#xff1a; Charles 是一个功能全面的抓包工具&#xff0c;适用于各种网络调试和优化场景。 它…...

Go语言使用 kafka-go 消费 Kafka 消息教程

Go语言使用 kafka-go 消费 Kafka 消息教程 在这篇教程中&#xff0c;我们将介绍如何使用 kafka-go 库来消费 Kafka 消息&#xff0c;并重点讲解 FetchMessage 和 ReadMessage 的区别&#xff0c;以及它们各自适用的场景。通过这篇教程&#xff0c;你将了解如何有效地使用 kafk…...

【论文笔记】Number it: Temporal Grounding Videos like Flipping Manga

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Number it: Temporal Grou…...

C语言菜鸟入门·关键字·int的用法

目录 1. int关键字 1.1 取值范围 1.2 符号类型 1.3 运算 1.3.1 加法运算() 1.3.2 减法运算(-) 1.3.3 乘法运算(*) 1.3.4 除法运算(/) 1.3.5 取余运算(%) 1.3.6 自增()与自减(--) 1.3.7 位运算 2. 更多关键字 1. int关键字 int 是一个关键字&#xff0…...

基于企业微信客户端设计一个文件下载与预览系统

在企业内部沟通与协作中&#xff0c;文件分享和管理是不可或缺的一部分。企业微信&#xff08;WeCom&#xff09;作为一款广泛应用于企业的沟通工具&#xff0c;提供了丰富的API接口和功能&#xff0c;帮助企业进行高效的团队协作。然而&#xff0c;随着文件交换和协作的日益增…...

昇思MindSpore第七课---文本解码原理

1. 文本解码原理 文本解码是将模型的输出&#xff08;通常是概率分布或词汇索引&#xff09;转换为可读的自然语言文本的过程。在生成文本时&#xff0c;常见的解码方法包括贪心解码、束搜索&#xff08;BeamSearch&#xff09;、随机采样等。 2 实践 2.1 配置环境 安装mindn…...