Three.js - 打开Web 3D世界的大门

文章目录

    • 前言
    • 一、Three.js 的起源与背景
    • 二、Three.js 的特点
    • 三、Three.js 的核心组件详解
    • 四、实际应用案例
    • 结语


前言

Three.js 是一个基于JavaScript的库,它极大地简化了使用WebGL创建3D图形的过程。通过封装复杂的WebGL API,Three.js为开发者提供了一个更加友好和高效的开发环境,使得即使是对3D编程不太熟悉的开发者也能够快速上手,并创造出令人印象深刻的交互式3D内容。


一、Three.js 的起源与背景

Three.js 是由一位西班牙的开发者 Ricardo Cabello(又名 Mr.doob)于2010年发起的项目。其初衷是为了简化WebGL(Web Graphics Library)的使用难度,因为直接使用WebGL进行3D渲染需要大量的代码编写,并且API相对复杂。Three.js通过封装WebGL的功能,提供了一个更加友好、易于使用的接口,使得更多的开发者可以快速上手并创造出令人惊艳的3D内容。

二、Three.js 的特点

  • 易用性:Three.js 提供了丰富的文档和支持,拥有庞大的社区,对于初学者来说是一个很好的入门选择。
  • 跨平台兼容性:由于它是基于WebGL构建的,因此可以在任何支持HTML5和WebGL的浏览器上运行,无需安装额外的插件。
  • 广泛的适用性:无论是游戏开发、虚拟现实应用还是数据可视化,Three.js都能提供强有力的支持。
  • 性能优化:随着版本迭代,Three.js不断改进性能,确保即使是在处理复杂场景时也能保持流畅。

三、Three.js 的核心组件详解

场景(Scene)

场景是所有3D对象、光源和其他元素的容器。在Three.js中,我们首先需要创建一个场景对象,然后将其他组件添加到这个场景中。

const scene = new THREE.Scene();

相机(Camera)

相机决定了用户从哪个视角观看场景。Three.js提供了多种类型的相机,如透视相机(PerspectiveCamera),它模仿人眼的视觉效果,适合大多数应用场景;还有正交相机(OrthographicCamera),它用于创建技术图纸或UI元素等不需要透视效果的内容。

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;

渲染器(Renderer)

渲染器负责将场景中的内容绘制到HTML页面上的canvas元素中。Three.js支持多种渲染器,但最常用的是WebGLRenderer,因为它提供了最好的性能和兼容性。

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

物体(Object)

物体是由几何形状(Geometry)和材质(Material)组成的3D模型。Three.js内置了许多常见的几何形状,比如球体、立方体、圆柱体等,并且可以通过自定义几何体来实现更复杂的设计。

const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

动画与交互

Three.js不仅限于静态图像,还支持动画和用户交互。你可以使用requestAnimationFrame循环更新场景,或者监听鼠标事件来响应用户的操作。

function animate() {requestAnimationFrame(animate);// 更新物体的位置或旋转等属性cube.rotation.x += 0.01;cube.rotation.y += 0.01;renderer.render(scene, camera);
}
animate();

四、实际应用案例

案例1:旋转的立方体

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Simple FPS Game</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>// 创建场景var scene = new THREE.Scene();// 创建相机var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);camera.position.z = 5;// 创建渲染器var renderer = new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 创建一个立方体几何体var geometry = new THREE.BoxGeometry();// 创建一个材质var material = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true });// 创建一个网格(几何体 + 材质)var 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();// 处理窗口大小调整window.addEventListener('resize', function () {var width = window.innerWidth;var height = window.innerHeight;renderer.setSize(width, height);camera.aspect = width / height;camera.updateProjectionMatrix();});</script>
</body></html>

案例2:轨道运动动画

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Simple FPS Game</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>// 初始化场景、相机和渲染器var scene = new THREE.Scene();var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);var renderer = new THREE.WebGLRenderer({ antialias: true });renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 创建球体并设置初始位置function createOrbitingSphere(radius, distance, speed) {var geometry = new THREE.SphereGeometry(radius, 32, 32);var material = new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff });var sphere = new THREE.Mesh(geometry, material);sphere.position.x = distance;sphere.distance = distance;sphere.angle = 0;sphere.speed = speed;scene.add(sphere);return sphere;}var spheres = [];for (var i = 0; i < 10; i++) {spheres.push(createOrbitingSphere(0.5 + Math.random(), 5 + i * 2, 0.005 + Math.random() * 0.01));}camera.position.z = 20;function animate() {requestAnimationFrame(animate);spheres.forEach(function (sphere) {sphere.angle += sphere.speed;sphere.position.x = Math.cos(sphere.angle) * sphere.distance;sphere.position.y = Math.sin(sphere.angle) * sphere.distance;});renderer.render(scene, camera);}animate();// 窗口调整事件处理window.addEventListener('resize', function () {var width = window.innerWidth;var height = window.innerHeight;renderer.setSize(width, height);camera.aspect = width / height;camera.updateProjectionMatrix();});</script>
</body></html>

案例3:随机生成的粒子系统

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Simple FPS Game</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>var scene = new THREE.Scene();var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);var renderer = new THREE.WebGLRenderer({ antialias: true });renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);camera.position.z = 50;var particlesCount = 5000;var particlesGeometry = new THREE.BufferGeometry();var particlesPositions = new Float32Array(particlesCount * 3);for (var i = 0; i < particlesCount * 3; i++) {particlesPositions[i] = (Math.random() - 0.5) * 100;}particlesGeometry.setAttribute('position', new THREE.BufferAttribute(particlesPositions, 3));var particlesMaterial = new THREE.PointsMaterial({ color: 0x00ff00 });var particles = new THREE.Points(particlesGeometry, particlesMaterial);scene.add(particles);function animateParticles() {var positions = particles.geometry.attributes.position.array;for (var i = 0; i < positions.length; i += 3) {positions[i + 1] -= 0.1;if (positions[i + 1] < -50) {positions[i + 1] = 50;}}particles.geometry.attributes.position.needsUpdate = true;}function animate() {requestAnimationFrame(animate);animateParticles();renderer.render(scene, camera);}animate();// 窗口调整事件处理window.addEventListener('resize', function () {var width = window.innerWidth;var height = window.innerHeight;renderer.setSize(width, height);camera.aspect = width / height;camera.updateProjectionMatrix();});</script>
</body></html>

结语

Three.js作为Web 3D开发的强大工具,正在不断推动着网络技术的发展边界。无论是创建沉浸式的用户体验、教育工具,还是进行复杂的数据可视化,Three.js都展现出了其独特的价值。随着社区的不断壮大和技术的进步,Three.js的应用前景无疑将更加广阔。

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

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

相关文章

Redis Java 集成到 Spring Boot

Hi~&#xff01;这里是奋斗的明志&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f331;&#x1f331;个人主页&#xff1a;奋斗的明志 &#x1f331;&#x1f331;所属专栏&#xff1a;Redis &#x1f4da;本系列文章为个人学习笔…

鸿蒙开发(29)弹性布局 (Flex)

概述 弹性布局&#xff08;Flex&#xff09;提供更加有效的方式对容器中的子元素进行排列、对齐和分配剩余空间。常用于页面头部导航栏的均匀分布、页面框架的搭建、多行数据的排列等。 容器默认存在主轴与交叉轴&#xff0c;子元素默认沿主轴排列&#xff0c;子元素在主轴方…

LangChain速成课程_构建基于OpenAI_LLM的应用

思维导图 什么是LangChain 特点描述基于语言模型LangChain 是一个专为语言模型&#xff08;如 GPT-4&#xff09;设计的开发框架。模型输入/输出支持灵活的模型输入和输出处理&#xff0c;可以适应各种不同的应用需求。数据感知能够将语言模型与其他数据源&#xff08;如维基百…

将txt转成excel正则化公式的调整

将训练的结果转换成excel是送到画图的关键&#xff0c;但是在转的过程中出现了问题&#xff0c;发现是正则化公式的结果。 使用网站进行调试&#xff0c;最终可以转了。下面是调试的工具以及调试好的代码。 regex101: build, test, and debug regex 上面是正则化公式&#xf…

Linux的proc目录与什么有关?【以及它里面的文件各自记录着什么信息】

在 Linux 系统中&#xff0c;/proc 目录是一个虚拟文件系统&#xff0c;提供了关于内核、进程和系统状态的实时信息。它与系统的 内核 和 进程 运行状态紧密相关&#xff0c;是系统管理员、开发人员和用户了解系统运行状况的重要途径。 /proc 目录的名称来源于 “process”&am…

28、使用StreamPark管理作业中,关于默认环境变量设置和默认动态参数设置的修改

在使用过一段时间的streampark后&#xff0c;发现flink on k8s作业配置过于繁琐了&#xff0c;特别是pod-template.yaml的编写&#xff08;主要是环境变量设置&#xff0c;环境变量关系着前面的日志插件中通过环境变量获取作业名称&#xff09;&#xff0c;动态参数的编写&…

springboot + vue+elementUI图片上传流程

1.实现背景 前端上传一张图片&#xff0c;存到后端数据库&#xff0c;并将图片回显到页面上。上传组件使用现成的elementUI的el-upload。、 2.前端页面 <el-uploadclass"upload-demo"action"http://xxxx.xxx.xxx:9090/file/upload" :show-file-list&q…

《HeadFirst设计模式》笔记(上)

设计模式的目录&#xff1a; 1 设计模式介绍 要不断去学习如何利用其它开发人员的智慧与经验。学习前人的正统思想。 我们认为《Head First》的读者是一位学习者。 一些Head First的学习原则&#xff1a; 使其可视化将文字放在相关图形内部或附近&#xff0c;而不是放在底部…

TensorRT-LLM中的MoE并行推理

2种并行方式&#xff1a; moe_tp_size&#xff1a;按照维度切分&#xff0c;每个GPU拥有所有Expert的一部分权重。 moe_ep_size: 按照Expert切分&#xff0c;每个GPU有用一部分Expert的所有权重。 二者可以搭配一起使用。 限制&#xff1a;二者的乘积&#xff0c;必须等于模…

GoChina备案管家

阿里云的 GoChina备案管家 是阿里云提供的一项服务&#xff0c;旨在帮助企业和个人快速、高效地完成中国大陆的 网站备案&#xff08;ICP备案&#xff09;。根据中国的互联网法律法规&#xff0c;所有在中国境内运行的网站都需要进行备案&#xff0c;才能合法发布内容。 GoChin…

Linux存储管理之核心秘密(The Core Secret of Linux Storage Management)

Linux存储管理之核心秘密 如果你来自Windows环境&#xff0c;那么Linux处理和管理存储设备的方式对你而言可能显得格外不同。我们知道&#xff0c;Linux的文件系统并不采用Windows那样的物理驱动器表示方式&#xff08;如C:、D:或E:&#xff09;&#xff0c;而是构建了一个以&…

平面坐标转大地坐标(arcgisPro中进行)

1、将需要转换的红线导入arcgisPro中&#xff0c;如下&#xff1a; 2、在地图菜单栏中&#xff0c;选择坐标转换工具&#xff0c;如下&#xff1a; 3、打开坐标转换工具 4、开启捕捉 5、 设置大地坐标显示格式 6、如下&#xff1a; 7、显示如图&#xff1a; 8、再依次添加几个待…

QT 端口扫描附加功能实现 端口扫描5

上篇QT 下拉菜单设置参数 起始端口/结束端口/线程数量 端口扫描4-CSDN博客 在扫描结束后设置Scan按钮为可用&#xff0c;并提示扫描完成 在 MainWindow 类中添加一个成员变量来跟踪正在进行的扫描任务数量&#xff1a; 在 MainWindow 的构造函数中初始化 activeScanTasks&…

使用WPF在C#中制作下载按钮

本示例使用 WPF 制作一个下载按钮。以下 XAML 代码显示了程序如何构建该按钮。 <Window x:Class"howto_download_button.Window1"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/…

Unity Burst详解

【简介】 Burst是Unity的编译优化技术&#xff0c;优化了从C#代码编译成Native代码的过程&#xff0c;经过编译优化后代码有更高的运行效率。 在Unity中使用Burst很简单&#xff0c;在方法或类前加上[BurstCompile]特性即可。在构建时编译代码的步骤&#xff0c;Burst编译器会…

Redis 数据库源码分析

Redis 数据库源码分析 我们都知道Redis是一个 <key,value> 的键值数据库&#xff0c;其实也就是一个 Map。如果让我来实现这样一个 Map&#xff0c;我肯定是用数组&#xff0c;当一个 key 来的时候&#xff0c;首先进行 hash 运算&#xff0c;接着对数据的 length 取余&…

基于YOLO11的无人机视角下羊群检测系统

基于YOLO11的无人机视角下羊群检测系统 (价格90) 包含 [sheep] 【羊】 1个类 通过PYQT构建UI界面&#xff0c;包含图片检测&#xff0c;视频检测&#xff0c;摄像头实时检测。 &#xff08;该系统可以根据数据训练出的yolo11的权重文件&#xff0c;运用在其他检测系统上…

WebRTC 在视频联网平台中的应用:开启实时通信新篇章

在当今这个以数字化为显著特征的时代浪潮之下&#xff0c;实时通信已然稳稳扎根于人们生活与工作的方方面面&#xff0c;成为了其中不可或缺的关键一环。回首日常生活&#xff0c;远程办公场景中的视频会议让分散各地的团队成员能够跨越地理距离的鸿沟&#xff0c;齐聚一堂共商…

【Go学习】-02-1-标准库:fmt、os、time

【Go学习】-02-1-标准库&#xff1a;fmt、os、time 1 fmt标准库1.1 输出1.1.1 fmt.Print1.1.2 格式化占位符1.1.2.1 通用占位符1.1.2.2 布尔型1.1.2.3 整型1.1.2.4 浮点数与复数1.1.2.5 字符串和[]byte1.1.2.6 指针1.1.2.7 宽度标识符1.1.2.8 其他flag 1.1.3 Fprint1.1.4 Sprin…

快速入门Spring Cloud Alibaba,轻松玩转微服务

​ 1 快速入门Spring Cloud Alibaba&#xff0c;轻松玩转微服务 1.1 架构 架构图&#xff1a; 1.2 项目结构 1.2.1 系统框架版本 版本适配查看&#xff1a;https://sca.aliyun.com/docs/2023/overview/version-explain/ Spring Boot Version &#xff1a;3.2.4 Spring Clo…