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启用渲染器的阴影渲染功能

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

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

相关文章

Elasticsearch的写入性能优化

优化Elasticsearch的写入性能需要从多维度入手,包括集群配置、索引设计、数据处理流程和硬件资源等。以下是一些关键优化策略和最佳实践: 一、索引配置优化 合理设置分片数与副本数分片数(Shards):过少会导致写入瓶颈(无法并行),过多会增加集群管理开销。公式参考:分…

FMC STM32H7 SDRAM

如何无痛使用片外SDRAM? stm32 已经成功初始化了 STM32H7 上的外部 SDRAM(32MB) 如何在开发中无痛使用SDRAM 使它像普通 RAM 一样“自然地”使用? [todo] 重要 MMT(Memory Management Tool) of STM32CubeMx The Memory Management Tool (MMT) disp…

【AIGC】RAGAS评估原理及实践

【AIGC】RAGAS评估原理及实践 (1)准备评估数据集(2)开始评估2.1 加载数据集2.2 评估忠实性2.3 评估答案相关性2.4 上下文精度2.5 上下文召回率2.6 计算上下文实体召回率 RAGas(RAG Assessment)RAG 评估的缩写&#xff…

VuePress完美整合Toast消息提示

VuePress 整合 Vue-Toastification 插件笔记 记录如何在 VuePress 项目中整合使用 vue-toastification 插件,实现优雅的消息提示。 一、安装依赖 npm install vue-toastification或者使用 yarn: yarn add vue-toastification二、配置 VuePress 客户端增…

C#学习12——预处理

一、预处理指令: 解释:是在编译前由预处理器执行的命令,用于控制编译过程。这些命令以 # 开头,每行只能有一个预处理指令,且不能包含在方法或类中。 个人理解:就是游戏里面的备战阶段(不同对局…

开疆智能Profinet转Profibus网关连接CMDF5-8ADe分布式IO配置案例

本案例是客户通过开疆智能研发的Profinet转Profibus网关将PLC的Profinet协议数据转换成IO使用的Profibus协议,操作步骤如下。 配置过程: Profinet一侧设置 1. 打开西门子组态软件进行组态,导入网关在Profinet一侧的GSD文件。 2. 新建项目并…

(三)Linux性能优化-CPU-CPU 使用率

CPU使用率 user(通常缩写为 us),代表用户态 CPU 时间。注意,它不包括下面的 nice 时间,但包括了 guest 时间。nice(通常缩写为 ni),代表低优先级用户态 CPU 时间,也就是进…

Digital IC Design Flow

Flow介绍 1.设计规格 架构师根据市场需求制作算法模型(Algorithm emulation)及芯片架构(Chip architecture),确定芯片设计规格书(Chip design specification) 原型验证 原型验证(Prototype Validation)通常位于产品开发流程的前期阶段,主要是在设计和开发的初步阶…

算法打卡第18天

从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7…

LangChain工具集成实战:构建智能问答系统完整指南

导读:在人工智能快速发展的今天,如何构建一个既能理解自然语言又能调用外部工具的智能问答系统,成为许多开发者面临的核心挑战。本文将为您提供一套完整的解决方案,从LangChain内置工具包的基础架构到复杂系统的工程实践。 文章深…

P3156 【深基15.例1】询问学号

P3156 【深基15.例1】询问学号 - 洛谷 数据结构-线性表 #include<bits/stdc.h> using namespace std; int n,m,a[2000005]; int main(){cin>>n>>m;for(int i1;i<n;i)cin>>a[i];//使用数组模拟线性表while(m--){int k;cin>>k;cout<<a[…

衡量嵌入向量的相似性的方法

衡量嵌入向量的相似性的方法 一、常见相似性计算方法对比 方法核心原理公式优点缺点适用场景余弦相似度计算向量夹角的余弦值,衡量方向相似性,与向量长度无关。$\text{cos}\theta = \frac{\mathbf{a} \cdot \mathbf{b}}{\mathbf{a}\mathbf{b}欧氏距离计算向量空间中的直线距离…

小番茄C盘清理:专业高效的电脑磁盘清理工具

在使用电脑的过程中&#xff0c;我们常常会遇到系统盘空间不足、磁盘碎片过多、垃圾文件堆积等问题&#xff0c;这些问题不仅会导致电脑运行缓慢&#xff0c;还可能引发系统崩溃。为了解决这些问题&#xff0c;小番茄C盘清理应运而生。它是一款专业的C盘清理软件&#xff0c;能…

【版本控制】Git 和 GitHub 入门教程

目录 0 引言1 Git与GitHub的诞生1.1 Git&#xff1a;Linus的“两周奇迹”&#xff0c;拯救Linux内核1.2 GitHub&#xff1a;为Git插上协作的翅膀1.3 协同进化&#xff1a;从工具到生态的质变1.4 关键历程时间轴&#xff08;2005–2008&#xff09; 2 Git与GitHub入门指南2.1 Gi…

Dify源码教程:账户和密码传递分析

概述 Dify系统中账户创建过程中的密码处理是Web应用安全的重要环节。本教程详细分析了从前端表单到后端存储的完整流程&#xff0c;展示了Dify如何安全地处理用户凭据。 前端部分 在 dify/web/app/install/installForm.tsx 文件中&#xff0c;当用户填写完表单并点击安装按钮…

window查看SVN账号密码

背景 公司的SVN地址发生迁移&#xff0c;想迁移一下本地SVN地址&#xff0c;后来发现SVN账号密码忘记了。写此文章纯记录。 迁移SVN地址&#xff1a; 找到svn目录点击relocate&#xff0c;输入新的svn地址&#xff0c;如需输入账号密码&#xff0c;输入账号密码即完成svn地址…

Read View在MVCC里如何工作

Read View的结构 Read View中有四个重要的字段&#xff1a; m_ids&#xff1a;创建 Read View 时&#xff0c;数据库中启动但未提交的「活跃事务」的事务 id 列表 。min_trx_id&#xff1a;创建 Read View 时&#xff0c;「活跃事务」中事务 id 最小的值&#xff0c;即 m_ids …

如何在mac上安装podman

安装 Podman 在 macOS 上 在 macOS 上安装 Podman 需要使用 Podman 的桌面客户端工具 Podman Desktop 或通过 Homebrew 安装命令行工具。 使用 Homebrew 安装 Podman&#xff1a; (base) ninjamacninjamacdeMacBook-Air shell % brew install podman > Auto-updating Hom…

QGraphicsView中鼠标点击与移动事件传递给MainWindow

在Qt图形应用程序开发中,QGraphicsView和QGraphicsScene框架提供了强大的2D图形显示功能。然而,当我们需要在主窗口(MainWindow)中处理这些视图中的鼠标事件。 问题背景 在典型的Qt图形应用程序架构中: MainWindow └── QGraphicsView└── QGraphicsScene└── QGra…

Spring Boot 缓存注解详解:@Cacheable、@CachePut、@CacheEvict(超详细实战版)

&#x1f4a1; 前言 在高并发、高性能的系统开发中&#xff0c;缓存是提升接口响应速度和降低数据库压力的重要手段。Spring Boot 提供了强大的缓存抽象层 —— spring-context-support&#xff0c;并结合 JSR-107 标准&#xff0c;提供了多个缓存注解&#xff0c;如&#xff…