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

three.js 零基础到入门

three.js 零基础到入门

    • 什么是 three.js
    • 为什么使用 three.js
    • 使用 Three.js
      • 1. 创建场景
        • 示例
      • 2.创建相机
      • 3. 创建立方体并添加网格地面
        • 示例
      • 5. 创建渲染器
        • 示例
      • 6. 添加效果(移动/雾/相机跟随物体/背景)
        • 自动旋转
          • 示例
          • 效果
      • 相机自动旋转
          • 示例
        • 展示效果
      • 实现由远到近的雾
        • 示例
        • 展示效果
      • Three.js 环境贴图应用
        • 示例
        • 展示效果
      • 实现物体反光和阴影(点光源,环境光源)
        • 光源
      • 接受光源/投射效果(阴影)
        • 示例
        • 效果
      • 7. 总结练习
        • 控制移动思想
        • 示例
        • 效果
      • 8. 总结知识点

什么是 three.js

Three.js 是一个用于在网页上创建和展示 3D 图形的 JavaScript 库。它简化了 WebGL 的复杂性,为开发者提供了一组易于使用的 API,使得创建、显示和操控 3D 对象变得更加方便。以下是对 Three.js 的更详细解释:

为什么使用 three.js

解决了在前端开发中实现 3d 效果的繁琐问题

  • 封装 WebGL:WebGL 是一个用于在浏览器内呈现 3D 图形的低级 API,它提供了强大的功能,但学习曲线陡峭。Three.js 封装了 WebGL 的许多复杂性,提供了更简单的接口。
  • 易于使用的 API:开发者可以使用简单的函数和对象来创建和操控 3D 场景,而不需要深入理解 WebGL 的细节。
  • 快速原型:由于其易用性,开发者能够快速创建和测试 3D 原型,缩短了开发周期。

使用 Three.js

1. 创建场景

Three.js 中,Scene 类是构建 3D 环境的基础组件。它充当所有 3D 对象(例立方体、球体、灯光、相机等)的容器,并管理这些对象的渲染。

示例
const scene = new THREE.Scene();

2.创建相机

  • Three.js 中,PerspectiveCamera 类用于创建透视相机,它能够模拟人眼的视角,让场景中的物体在视觉上具有深度感。透视相机是 3D 图形中常用的一种相机类型,尤其适用于展示真实世界中的场景。
  • 在 Three.js 的所有类中,position 属性用于修改物体在三维空间中的坐标。通过设置 position,我们可以控制相机或其他对象在 X、Y 和 Z 轴上的位置。这使得我们能够灵活地决定视角和观察点,进而影响最终的渲染效果。通过调整相机的位置,我们可以改变观察者的视角,以便获得不同的视觉体验。

示例

const camera = new THREE.PerspectiveCamera();
camera.position.z = 10;
camera.position.y = 2;

3. 创建立方体并添加网格地面

  • BoxGeometryThree.js 中用于创建立方体的一个类。构造函数接受三个参数,分别表示立方体的宽度、高度和深度。
  • MeshBasicMaterial 是一种材质类型,它用于定义 3D 对象的外观。与其他材质不同,MeshBasicMaterial不受光照影响,因此它总是以定义的颜色显示,无论场景中的光照条件如何。
  • MeshThree.js 中用于创建网格的一个类。Mesh 对象结合了几何体(如 BoxGeometry)和材质(如 MeshBasicMaterial)来构建可视的 3D 物体。通过将几何体和材质结合,Mesh 表示一个具有具体形状和视觉外观的三维对象,可以在场景中进行操作和渲染。
示例
//创建立方体
const geometry = new THREE.BoxGeometry(1, 1, 1);
//设置立方体的颜色
const material = new THREE.MeshBasicMaterial({ color: 0x888 });
//创建网格并把立方体放进去
const cube = new THREE.Mesh(geometry, material);
//设置立方体的位置在可视范围内
cube.position.set(0, 3, 0);
//添加网格地面
const gridHelper = new THREE.GridHelper(10, 10);
//把立方体和网格地面加入场景中
scene.add(cube);
scene.add(gridHelper);

提示
GridHelperThree.js 提供的一个辅助类,用于在场景中生成一个可视化的网格。它的主要功能是帮助开发者和设计师在 3D 空间中定位和对齐对象。GridHelper 的网格通常由线条构成,便于快速判断场景的坐标和对象的位置。

数字代表的含义:

  • 第一个参数定义了网格的边长,即网格范围的大小。
  • 第二个参数决定了每个维度上将网格细分为多少个单元,影响网格的密度和视觉清晰度。

5. 创建渲染器

Three.js 中,WebGLRenderer 是主要的渲染器,它利用 WebGL 技术来在浏览器中绘制高效的 3D 图形。

示例
const renderer = new THEE.WebGLRenderer();
//渲染到id名为container的容器里面
document.getElemnetById("container").appendChild(renderer.domElement);
//调整窗口的大小
renderer.setSize(window.innerWidth, window.innerHeight);
//刚才创建的场景和立方体放进来
renderer.render(scene, camera);

6. 添加效果(移动/雾/相机跟随物体/背景)

自动旋转
  • 让立方体自动旋转,可以通过调整 Mesh 对象的 rotation 属性来实现。在 onMounted 中定义一个名为 animate 的函数,该函数内使用 requestAnimationFrame(animate) 实现持续的动画循环,并在每帧中更新
示例
const animate = () => {requestAnimationFrame(animate);cube.rotation.x += 0.01;cube.rotation.y += 0.01;//重新放进来renderer.render(scene, camera);
};animate();
效果

Alt

相机自动旋转

  • 为了实现相机的自动旋转,可以使用 OrbitControls 类。该类提供了 autoRotate 属性,启用此属性后,相机将自动旋转。此外,可以通过 autoRotateSpeed 属性设置旋转的速度,以控制相机自转的快慢。
示例
const controls = new OrbitControls(camera, renderer.domElement);
// 对轨道控制器改变时候进行监听
controls.addEventListener("change", function () {console.log("触发change");
});// 添加阻尼
controls.enableDamping = true;
controls.dampingFactor = 0.01;// 自动旋转
controls.autoRotate = true;
controls.autoRotateSpeed = 0.5;// 进行渲染
// renderer.render(scene, camera);// 让立方体动起来
function animate() {// 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。requestAnimationFrame(animate);cube.rotation.x += 0.01;cube.rotation.y += 0.01;// 轨道控制器更新controls.update();renderer.render(scene, camera);
}
animate();
展示效果

Alt

实现由远到近的雾

  • 为了实现 场景由远到近的雾 可以使用 Three.js 中的 Fog 类来添加
示例
scene.fog = new THREE.Fog(0xcccccc, 10, 15);
展示效果

Three.js 环境贴图应用

  • 使用THREE.CubeTextureLoader加载 6 面环境贴图
  • 同时应用于场景背景和球体材质
  • 实现全景天空盒+环境反射效果
示例
/*** 立方体贴图加载* 图片顺序:右(x+)、左(x-)、上(y+)、下(y-)、后(z+)、前(z-)* 注意:路径需要替换为实际资源目录*/
const cubleTExture = new THREE.CubeTextureLoader().setPath("/") // 纹理资源目录路径.load(["04.jpg","01.jpg", // 右/左"05.jpg","02.jpg", // 上/下"06.jpg","03.jpg", // 后/前]);// 将立方体贴图设置为场景背景(全景天空盒效果)
scene.background = cubleTExture;/*** 创建带环境贴图的球体* 参数说明:*   SphereGeometry(半径, 宽度分段, 高度分段)*   MeshBasicMaterial 基础材质支持环境贴图*/
const sphere = new THREE.SphereGeometry(1); // 单位半径的球体
const material = new THREE.MeshBasicMaterial({envMap: cubleTExture, // 材质反射环境贴图
});
scene.add(sphere); // 注:原代码中的cube应为sphere
展示效果

实现物体反光和阴影(点光源,环境光源)

受光材质

  • Three.js 中,有一个材质类叫 MeshPhongMaterial。该材质能够通过光源影响其外观,这意味着它适合于需要呈现高光和材质细节的场景。使用 MeshPhongMaterial 时,必须为场景添加光源,以便正确地渲染出材质的反射效果和光影变化。
光源
  • AmbientLight 是环境光,它接受两个参数:第一个是光的颜色,第二个是光的强度。
  • PointLight 是点光源,它接受三个参数:第一个是光的颜色,第二个是光的强度,第三个是光的衰减距离(或范围)。

接受光源/投射效果(阴影)

  • Mesh 中 有 receiveshadowcastshadow 分别是 接受光源和投射阴影
示例
const meterial = new THREE.MeshPhongMaterial({color: 0x00ff00,shininess: 1000,
});// 创建MESH
const cubezft = new THREE.Mesh(zft, meterial);
cubezft.position.set(0, 0.5, 0);
//让物体接受光源
cubezft.receiveShadow = true;
//物体投射效果
cubezft.castShadow = true;const light = new THREE.AmbientLight(0xffffff, 1);
const lightD = new THREE.PointLight(0xffffff, 1000, 100);
lightD.position.set(5, 3, 5);
lightD.castShadow = true;
scene.add(light);
scene.add(cubezft);
//添加点光源
scene.add(lightD);
//创建地面
const meshFloor = new THREE.Mesh(//创建地面接受两个参数长宽new THREE.PlaneGeometry(20, 20),new THREE.MeshPhongMaterial({color: 0x1b5e20,side: THREE.DoubleSide, //双面都显示})
);
//设置位置
meshFloor.position.set(0, 0, -1);
//设置旋转90%
meshFloor.rotation.x -= Math.PI / 2;
//地面也要接受光源
meshFloor.receiveShadow = true;
scene.add(meshFloor);
效果

7. 总结练习

新知识

  • 平移属性 translate 有三个值 X Y Z 接受一个参数 表示平移的单位
控制移动思想
  • 使用键盘侦听事件 @keyDOwn 在此事件中有一个参数 里面包含 keykeyCode 两个对象 key 输出你所点击的键盘 比如我点击 a 它的值为a keyCode 的是以 ASCll码 来存储的 比如 我点击的是 a 则输出 65
  • 使用if判断(也可以使用switch) 判断 你点击的键盘COde值 我使用 wasd来控制前后左右移动 只要判断它对应的code值 然后 使用平移属性 translate 进行一系列的操作

如何让场景跟着移动
首先要让相机看向物体 camera.lookAt 接受三个参数 这里 我直接使用 物体的坐标传入 position
然后 让相机跟随物体 设置 相机位置实时 跟着物体 的坐标 这里我使用的是第三人称的效果 在原有物体的y轴+1 还有x轴加4 可以获得第三视角

示例
  const up = (event) => {console.log(event.keyCode);console.log(event.key);if (event.key === "ArrowUp") {cubezft.translateY(0.1);} else if (event.key == "ArrowDown") {cubezft.translateY(-0.1);}else if(event.key === 'ArrowLeft'){cubezft.rotation.y +=0.1}if (event.keyCode === 65) {cubezft.translateX(-0.1);} else if (event.keyCode === 87) {cubezft.translateZ(-0.1);} else if (event.keyCode === 68) {cubezft.translateX(0.1);} else if (event.keyCode === 83) {cubezft.translateZ(0.1);}else{return}camera.lookAt(cubezft.position);camera.position.set(cubezft.position.x,cubezft.position.y + 1,cubezft.position.z + 4);
};
效果

8. 总结知识点

名称属性用法
场景THREE.Scene()用于添加和管理3D物体
相机THREE.PerspectiveCamera()控制视图视角,实现物体观察或第一人称效果
坐标位置position设置物体位置,接受x、y、z三个坐标参数
物体旋转rotation控制物体旋转,包含x、y、z三个轴向,可接受具体角度或Math.PI值
立方体THREE.BoxGeometry()创建立方体,接受长、宽、高三个参数
圆柱体THREE.CylinderGeometry()创建圆柱体,接受四个参数依次为:顶部半径、底部半径、高度、分段数
圆锥THREE.ConeGeometry();创建圆锥体。接受三个参数依次为:底部半径,高度,分段数
胶囊体THREE.CapsuleGeometry()创建胶囊体。接受四个参数依次为:半径、柱体长度、帽部分段数、径向分段数
球体THREE.SphereGeometry创建球体。接受一个参数:半径
纹理THREE.TextureLoader().load()加载普通纹理贴图。参数:图片路径
背景纹理THREE.CubeTextureLoader().setPath("/").load();加载立方体贴图作为全景背景。参数(setPath):图片路径 、参数(load):6张图片路径数组(顺序:右左上下后前)
自定义矩形THREE.PlaneGeometry()创建平面,接受四个参数依次为:宽度、高度、宽度分段、高度分段
网格THREE.Mesh()创建3D物体,参数:几何体、材质
Phong材质THREE.MeshPhongMaterial()创建高光材质,参数:color(颜色)、shininess(高光度)
基础材质THREE.MeshBasicMaterial()创建不受光照影响的材质,参数:color(颜色)
标准材质THREE.MeshStandardMaterial()创建PBR标准材质,参数:roughness(粗糙度)、metalness(金属度)
物理材质THREE.MeshPhysicalMaterial()创建高级PBR材质,参数:clearcoat(清漆层)、transmission(透光率)
Lambert材质THREE.MeshLambertMaterial()创建无高光的漫反射材质,参数:color(颜色)
环境光THREE.AmbientLight()创建环境光,接受两个参数依次为:颜色、强度
点光源THREE.PointLight()创建点光源,接受四个参数依次为:颜色、强度、距离、衰减
平行光THREE.DirectionalLight()创建平行光,接受两个参数依次为:颜色、强度
聚光灯THREE.SpotLight()创建聚光灯,接受六个参数依次为:颜色、强度、距离、角度、衰减、半影
接受光源Mesh.receiveShadow设置物体是否接收阴影,布尔值
投射阴影Mesh.castShadow设置物体是否投射阴影,布尔值
使用纹理THREE.MeshStandardMaterial({map: texture})将纹理应用到材质,参数:纹理对象
阴影贴图renderer.shadowMap.enabled = true启用渲染器的阴影渲染功能

相关文章:

three.js 零基础到入门

three.js 零基础到入门 什么是 three.js为什么使用 three.js使用 Three.js1. 创建场景示例 2.创建相机3. 创建立方体并添加网格地面示例 5. 创建渲染器示例 6. 添加效果(移动/雾/相机跟随物体/背景)自动旋转示例效果 相机自动旋转示例 展示效果 实现由远到近的雾示例展示效果 T…...

PublishSubject、ReplaySubject、BehaviorSubject、AsyncSubject的区别

python容易编辑,因此用pyrx代替rxjava3做演示会比较快捷。 pyrx安装命令: pip install rx 一、Subject(相当于 RxJava 的 PublishSubject) PublishSubject PublishSubject 将对观察者发送订阅后产生的元素,而在订阅前…...

在Ubuntu22.04 系统中安装Docker详细教程

1.更新系统软件包 #确保您的系统软件包是最新的。这有助于避免安装过程中可能遇到的问题 sudo apt update sudo apt upgrade -y2.安装必要的依赖 sudo apt install apt-transport-https ca-certificates curl software-properties-common -y3.替换软件源 echo "deb htt…...

解决transformers.adapters import AdapterConfig 报错的问题

需要安装 Adapter-Hub 的 transformers 分支,不是官方 transformers 库! pip install githttps://github.com/Adapter-Hub/transformers.git✅ 注意:这个命令会从 GitHub 下载源码并安装。你需要确保你的网络可以访问 GitHub,并且…...

AUTOSAR实战教程--DoIP_01_配置项解释

配置项 解释 备注 DoIPChannelSARef 引用DoIP Tester的源地址,就是你在DoIP Tester这个Containter中配置的Tester实例。 DoIPChannelTARef 引用目标地址。就是你在DoIPTargetAddress这个Container中的配置。 DoIPPduRRxPduId 为该pdu设置一个ID用于DoIP…...

湖北理元理律师事务所:法律视角下的债务优化与生活平衡之道

一、债务优化的本质:法律与生活的平衡艺术 债务问题常被视为单纯的财务危机,实则牵涉法律权责界定、还款能力评估、生活保障等多重维度。作为法律服务机构,我们观察到:真正的债务优化需同时满足两个条件: 法律合规性…...

机器人/智能车纯视觉巡线经典策略—滑动窗口+直方图法

作者:SkyXZ CSDN:SkyXZ~-CSDN博客 博客园:SkyXZ - 博客园 在机器人或智能车的自主导航任务中,视觉巡线是一项最为基础且关键的能力之一。通过摄像头实时获取道路图像,并基于图像信息判断行驶路径&#xff0…...

附加模块--Qt OpenGL模块功能及架构

一、模块功能: 主要变化 Qt OpenGL 模块的分离: 在 Qt 6 中,原来的 Qt OpenGL 功能被拆分为多个模块 传统的 Qt OpenGL 模块 (QGL*) 已被标记为废弃 新的图形架构: Qt 6 引入了基于 QRhi (Qt Rendering Hardware Interface) 的…...

503 Service Unavailable:服务器暂时无法处理请求,可能是超载或维护中如何处理?

处理 "503 Service Unavailable" 错误是服务器管理者面临的常见挑战之一。这种错误通常表示服务器暂时无法处理请求,可能是由于服务器超载、维护中或其他临时性问题导致的。在本文中,我将介绍如何处理 "503 Service Unavailable" 错…...

抖音怎么下载没有水印的视频?

你是不是经常在抖音上刷到喜欢的视频,想保存下来却总是带着烦人的水印?无论是想收藏精彩片段,还是二次创作,水印都成了“拦路虎”。别急!今天就来教你3种超简单方法,轻松下载无水印抖音视频,高清…...

虚拟机时间同步

一、常见同步方式 常见的虚拟机同步方式有给虚拟机配置ntp、或者用平台提供的agent对时与虚拟机所在的宿主机。第一种依赖网络、第二种依赖平台的agent这个三方工具。 二、利用ptp_kvm.ko来直接和宿主机同步时间 关键组件 ptp_kvm驱动、chrony。 PTP_KVM同步原理 |--------…...

三级流水线是什么?

三级流水线是什么? “三级流水线” 英文名:Three-Stage Pipeline 或 Basic 3-Stage Pipeline,是计算机处理器(CPU)设计中一种基本的指令流水线技术,它将指令的执行过程划分为三个主要阶段,使得…...

软件更新机制的测试要点与稳定性提升

💗博主介绍💗:✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示:文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…...

自定义protoc-gen-go生成Go结构体,统一字段命名与JSON标签风格

背景 在日常的 Go 微服务开发中,Protocol Buffers(protobuf) 是广泛使用的数据交换格式。其配套工具 protoc-gen-go 会根据 .proto 文件生成 Go 结构体代码,但默认生成的字段名、JSON tag 命名风格往往不能满足所有团队或项目的代…...

Context API 应用与局限性

核心概念 React 的 Context API 是为了解决组件间数据共享而设计的一种机制,其核心价值在于提供了一种不通过 props 层层传递就能在组件树中共享数据的方法。在 React 应用中,数据通常是自上而下(从父组件到子组件)通过 props 传…...

LLMs 系列科普文(11)

目前我们已经介绍了大语言模型训练的两个主要阶段。第一阶段被称为预训练阶段,主要是基于互联网文档进行训练。当你用互联网文档训练一个语言模型时,得到的就是所谓的 base 模型,它本质上就是一个互联网文档模拟器,我们发现这是个…...

DQN算法(详细注释版)

DQN算法 DQN算法使用的常见问题 Q1: 为什么用目标网络而非Q网络直接计算? 答案:避免“移动目标”问题(训练中Q网络频繁变化导致目标不稳定),提高收敛性。 Q2: 为什么用 max 而不是像SARSA那样采样动作?…...

sizeof 与strlen的区别

sizeof 和 strlen 是C和C 中用于处理数据大小和字符串长度的两个不同的操作符/函数,它们的区别如下: 概念和用途 - sizeof 是一个操作符,用于计算数据类型或变量在内存中所占的字节数,它是在编译时确定的,与数据的…...

论文阅读:HySCDG生成式数据处理流程

论文地址: The Change You Want To Detect: Semantic Change Detection In Earth Observation With Hybrid Data Generation Abstract 摘要内容介绍 📌 问题背景 “Bi-temporal change detection at scale based on Very High Resolution (VHR) images is crucia…...

10万QPS高并发请求,如何防止重复下单

1. 前端拦截 首先因为是10万QPS的高并发请求,我们要保护好系统,那就是尽可能减少用户无效请求。 1.1 按钮置灰 很多用户抢票、抢购、抢红包等时候,为了提高抢中的概率,都是疯狂点击按钮。会触发多次请求,导致重复下…...

Xilinx IP 解析之 Block Memory Generator v8.4 ——02-如何配置 IP(仅 Native 接口)

相关文章: Xilinx IP 解析之 Block Memory Generator v8.4 ——01-手册重点解读(仅Native RAM) – 徐晓康的博客 Xilinx IP 解析之 Block Memory Generator v8.4 ——02-如何配置 IP(仅 Native RAM) – 徐晓康的博客 V…...

什么是高考?高考的意义是啥?

能见到这个文章的群体,应该都经历过高考,突然想起“什么是高考?意义何在?” 一、高考的定义与核心功能 **高考(普通高等学校招生全国统一考试)**是中国教育体系的核心选拔性考试,旨在为高校选拔…...

RISC-V 开发板 + Ubuntu 23.04 部署 open_vins 过程

RISC-V 开发板 Ubuntu 23.04 部署 open_vins 过程 1. 背景介绍2. 问题描述3. 解决过程3.1 卸载旧版本3.2 安装 Suitesparse v5.8.03.3 安装 Ceres Solver v2.0.03.4 解决编译爆内存问题 同步发布在个人笔记RISC-V 开发板 Ubuntu 23.04 部署 open_vins 过程 1. 背景介绍 最近…...

量子计算突破:新型超导芯片重构计算范式

​​2024年IBM 1281量子比特超导芯片实现0.001%量子错误率,计算速度达经典超算2.5亿倍​​。本文解析: ​​物理突破​​:钽基超导材料使量子相干时间突破​​800μs​​(提升15倍)​​架构革命​​:十字形…...

Spring Cloud 多机部署与负载均衡实战详解

🧱 一、引言 为什么需要多机部署? 解决单节点性能瓶颈,提升系统可用性和吞吐量 在传统单机部署模式下,系统的所有服务或应用都运行在单一服务器上。这种模式在小型项目或低并发场景中可能足够,但随着业务规模扩大、用…...

基于定制开发开源AI智能名片S2B2C商城小程序的首屏组件优化策略研究

摘要:在数字化转型背景下,用户对首屏交互效率的诉求日益提升。本文以"定制开发开源AI智能名片S2B2C商城小程序"为技术载体,结合用户行为数据与认知心理学原理,提出首屏组件动态布局模型。通过分析搜索栏、扫码入口、个人…...

EasyRTC嵌入式音视频通信SDK音视频功能驱动视频业务多场景应用

一、方案背景​ 随着互联网技术快速发展,视频应用成为主流内容消费方式。用户需求已从高清流畅升级为实时互动,EasyRTC作为高性能实时音视频框架,凭借低延迟、跨平台等特性,有效满足市场对多元化视频服务的需求。 二、EasyRTC技术…...

Flink 失败重试策略 :restart-strategy.type

在 Apache Flink 中,restart-strategy.type 用于指定作业的重启策略(Restart Strategy),它决定了作业在失败后如何恢复。 Flink 提供了 4 种内置重启策略,可以通过 flink-conf.yaml 或代码动态配置。 1. 可配置的 rest…...

linux下gpio控制

linux下gpio控制 文章目录 linux下gpio控制1.中断命令控制/sys/class/gpio/export终端命令控制led 2.应用程序控制 3.驱动代码控制 1.中断命令控制 通用GPIO主要用于产生输出信号和捕捉输入信号。每组GPIO均可以配置为输出输入以及特定的复用功能。 当作为输入时,内…...

Spring Boot 从Socket 到Netty网络编程(下):Netty基本开发与改进【心跳、粘包与拆包、闲置连接】

上一篇:《Spring Boot 从Socket 到Netty网络编程(上):SOCKET 基本开发(BIO)与改进(NIO)》 前言 前文中我们简单介绍了基于Socket的BIO(阻塞式)与NIO(非阻塞式&#xff0…...