Threejs 三维开发系列之Threejs基础概念

news2024/11/21 0:24:38

  • Threejs简介
  • (是什么)Threejs是一个web端的3D图形引擎,能利用js创建和控制各种三维模型和场景
  • (能用来做什么)可以用js开发各种复杂的三维场景、空间模型动画展示、各种三维小游戏(比如微信跳一跳就是Threejs开发)。
  • (优势) 传统三维开发一般是c++ openGl,开发成本大效率低,threejs封装了大量底层图形计算,在js应用层能以很高的效率完成各种三维产品开发。
  • (劣势) 学习曲线比较陡峭,需要掌握一定图形和数学知识,大模型3D场景对设备性能有一定的要求,小型场景问题不大。


基础坐标系概念

  • 不同于常规前端开发只有xy两个坐标系,threejs多了一个z坐标轴,因此开发场景从二维的平面转换为了三维的立体空间,z轴是往屏幕外面朝向
  • Threejs坐标系采用的是右手坐标系

Threejs安装

  • npm模式安装:npm install three
// 方式 1: 导入整个 three.js核心库
import * as THREE from 'three';

const scene = new THREE.Scene();


// 方式 2: 仅导入你所需要的部分
import { Scene } from 'three';

const scene = new Scene();
  • cdn模式安装,由于 three.js 依赖于ES module,因此任何引用它的script标签必须使用type="module"。如下所示:
<script type="importmap">
	{
	"imports": {
		"three": "https://unpkg.com/three@<version>/build/three.module.js"
	}
	}
</script>

<script type="module">

	import * as THREE from 'three';

	const scene = new THREE.Scene();

</script>

基础结构搭建

  • html 中 引入canvas组件
<canvas class="webgl"></canvas>

<style>
.webgl {
  position: fixed;
  top: 0;
  left: 0;
  outline: none;
}
</style>

渲染器 WebGLRenderer

  • 渲染器是用来将Threejs的各种三维元素,通过canvas展示出来的一种渲染引擎。
  • 设置好渲染器各种参数后,通过调用render方法来进行界面渲染
//先定义渲染器尺寸,下面是浏览器全屏
const size = {
  width: window.innerWidth,
  height: window.innerHeight,
}

//获取canvas Dom元素
const canvas = document.querySelector('canvas.webgl')
//将dom引入传入渲染器,用来创建渲染器
const renderer = new THREE.WebGLRenderer({ canvas })
//设置渲染器尺寸
renderer.setSize(size.width, size.height)
//设置渲染器像素比 避免有些高分辨率的设备把屏幕弄得太模糊,设置像素比最大2X
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))

场景 Scene

  • 场景就是整个三维空间所有虚拟元素容器,有点类似于前端的虚拟Dom
  • 主要常用的方法是 add(),用来给场景添加各种元素
  • 真正让场景生效的是渲染器的render方法会传入场景参数
//创建场景
const scene = new THREE.Scene()

网格对象 Mesh

  • Mesh是一种三维网格对象,也就是放在三维空间种的实物,Mesh由2种东西合成:
    1. Geometry 几何体,用来定义是三维物体的形状大小和网格分段密度,比如BoxGeometry是长方体,可以传入长宽高参数。
    2. Material 附着在几何体上的材质,用来定义颜色、透明度等等
  • 可以通过 mesh.position.set(0,0,0) 用来调整网格对象中心点的坐标
  • 最后把网格对象加入场景中 scene.add(mesh)
//创建mesh模型(由几何体+材质)  正方体
//长宽高为1的立方体 长宽高的线条分段是5条,用来调整网格密度
const geometry = new THREE.BoxGeometry(1, 1, 1, 5, 5, 5)   
const material = new THREE.MeshBasicMaterial({
  color: 0x03c03c, // 材质的颜色
  transparent:true,// 开启透明
  opacity:0.5,// 设置透明度
  wireframe: true, //显示网格虚线
})
const mesh = new THREE.Mesh(geometry, material)
mesh.position.set(0,0,0)
scene.add(mesh)

相机 Camera

  • 横看成岭侧成峰,不同于二维平面,在三维世界中从不角度看同一样东西,会有完全不同的呈现,所以在Threejs中引入Camera的概念,也就是不同的观察视角
  • PerspectiveCamera(fov, aspect, near, far) 相机有四个参数
    • fov 视线观察角度 比如45就是以45度角来观察
    • aspect 渲染器的宽高比
    • near 从多近的距离才开始渲染,就是相机能看到的最近的距离
    • far 最多渲染多远的距离,就是相机能看到的最远的距离

如图所示

//初始化相机 透视相机 
//这里是以45度观察 不设最远最近距离
const camera = new THREE.PerspectiveCamera(45, size.width/size.height)
//相机的位置放在在 x=3 y=3 z=3的位置
camera.position.set(3, 3, 3)
//然后相机看向 x=0 y=0 z=0的位置
camera.lookAt(0, 0, 0)
//场景添加相机
scene.add(camera) 

渲染

已经完成所有场景布置了, 可以调用渲染器的render渲染方法,需要传入参数场景Scene和相机camera

renderer.render(scene, camera)

这个时候就可以看到一个网格立方体了

辅助观察坐标系

但是这种太模糊,没有位置概念,可以引入辅助坐标系,以方便更好观察

💡 Tips:以下代码需要在render渲染调用之前加,render执行过后渲染就完毕了

//添加坐标轴 辅助查看 
const axesHelper = new THREE.AxesHelper(150)
scene.add(axesHelper)

可以看到多了三个线,其中红色的是x轴、绿色是 y轴、蓝色的是z轴,xyz交汇处就是0,0,0原点

动态渲染

目前我们上面看到的渲染是静态渲染,只渲染了一次,可以利用requestAnimationFrame浏览器自带的刷新器,动态的去改变网格对象的参数,达到视线动态渲染旋转的效果

在最后面加上如下代码

// 动态渲染
const tick = () => {
  renderer.render(scene, camera)
  mesh && (mesh.rotation.x += 0.02)     //以x轴旋转
  // mesh && (mesh.rotation.y += 0.02)     //以y轴旋转
  // mesh && (mesh.rotation.z += 0.02)     //以z轴旋转
  window.requestAnimationFrame(tick)
}
tick()

就能看到立方体开始旋转了

调整观察视角

目前相机观察视角是固定的,利用OrbitControls可以利用鼠标或者手势拖拽调整相机的观察视角

//在代码最前面import 轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

//在渲染前创建轨道控制器 用来用鼠标控制相机
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true

// 动态渲染 更新控制器update
const tick = () => {
  renderer.render(scene, camera)
  mesh && (mesh.rotation.x += 0.02)     //以x轴旋转
  // mesh && (mesh.rotation.y += 0.02)     //以y轴旋转
  // mesh && (mesh.rotation.z += 0.02)     //以z轴旋转
  controls.update()  // 更新控制器
  window.requestAnimationFrame(tick)
}
tick()

附 gitte源码: ThreeJsDemo: ThreeJs Demo

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机考研 | 2014年 | 计算机组成原理真题

文章目录 【计算机组成原理2014年真题44题-12分】【第一步&#xff1a;信息提取】【第二步&#xff1a;具体解答】 【计算机组成原理2014年真题45题-8分】【第一步&#xff1a;信息提取】【第二步&#xff1a;具体解答】 【计算机组成原理2014年真题44题-12分】 &#xff08;1&…

SAML- 安全断言标记语言

一、概念 安全断言标记语言&#xff08;SAML&#xff09;是一种开放标准&#xff0c;用于在各方之间&#xff08;特别是身份提供商和服务提供商之间&#xff09;交换身份验证和授权数据。SAML 是一种基于XML的安全断言标记语言&#xff08;服务提供商用来做出访问控制决策的语句…

OpenCV—自动驾驶实时道路车道检测(完整代码)

自动驾驶汽车是人工智能领域最具颠覆性的创新之一。在深度学习算法的推动下,它们不断推动我们的社会向前发展,并在移动领域创造新的机遇。自动驾驶汽车可以去传统汽车可以去的任何地方,并且可以完成经验丰富的人类驾驶员所做的一切。但正确地训练它是非常重要的。自动驾驶汽…

MaxQuant的安装和使用(linux)

安装 conda create -n maxquant conda activate maxquant conda install -c bioconda maxquantmaxquant --help # 查看命令行参数用法 MaxQuant goes Linux 2018年&#xff0c;作者发布了MaxQuant的linux版本&#xff08;1.6.1.0&#xff09;。该版本主要依赖mono。

这三个视频解析工具,谁看了不说好用?

在这个自媒体时代&#xff0c;很多小伙伴都有下载视频的需求&#xff0c;今天就来给大家分享三个视频下载解析工具&#xff0c;不仅操作简单&#xff0c;而且十分高效&#xff0c;谁用谁知道&#xff01; 一、WeDown 一个在线视频下载网站&#xff0c;支持直接复制视频地址链接…

使用Python编写多因子量化策略详解

概要 多因子量化策略是一种基于股票市场因子进行量化分析的投资策略。该策略基于多个因子模型并结合市场数据&#xff0c;通过计算每支股票的综合得分并以此为基础进行股票的选取和权重分配。在本篇文章中&#xff0c;我们将介绍如何使用Python编写多因子量化策略。 数据收集…

【年终特惠】基于最新导则下生态环评报告编制技术暨报告篇、制图篇、指数篇、综合应用篇系统性实践技能提升

根据生态环评内容庞杂、综合性强的特点&#xff0c;依据生态环评最新导则&#xff0c;将内容分为4大篇章(报告篇、制图篇、指数篇、综合篇)、10大专题(生态环评报告编制、土地利用图的制作、植被类型及植被覆盖度图的制作、物种适宜生境分布图的制作、生物多样性测定、生物量及…

php yield定义生成器,加快foreach、for等循环速度

yield关键字用于定义生成器函数。生成器函数可以一次生成一个值&#xff0c;并在每次生成值后暂停其执行&#xff0c;直到请求下一个值。这使得生成器可以有效地处理大量数据或无限数据流 不使用yield使用yield执行方式函数会立即执行&#xff0c;并一次性返回所有结果。函数执…

【CPP】类和对象

1- Classes and Objects Structures A struct in C is a type consisting of a sequence of data membersSome functions/Statements are needed to operate the data members of an object of a struct type 不不小心操作错误&#xff0c;不小心越界 Classes You should b…

五分钟理解Java跨平台原理(适合小白)

JVM通俗的理解 Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机&#xff0c;即JVM&#xff08;Java Virtual Machine&#xff09;是实现这一特点的关键。JVM是一种用于计算设备的规范&#xff0c;它是一个虚构出来的计算机&#xff0c;是通过在实际的计算机…

SMART PLC梯形速度曲线轨迹规划(追剪从轴控制)

在介绍本专栏之前,大家可以参考另一篇博图PLC的梯形加减速点动功能块介绍文章 梯形加减速点动功能块(博途SCL)_RXXW_Dor的博客-CSDN博客文章浏览阅读184次。SMART PLC斜坡函数SMART PLC斜坡函数功能块(梯形图代码)_RXXW_Dor的博客-CSDN博客斜坡函数Ramp的具体应用可以参看下…

vue3+element-plus 表格全选和跨页勾选,以及全选全部功能

目录 背景描述 实现效果 详细开发 1.模拟数据和页面布局 2.跨页勾选和点击勾选功能 3.表头全选 4. 全选全部 &#xff08;1&#xff09;全选后禁用表格勾选&#xff08;简单&#xff09; &#xff08;2&#xff09;真正意义上的全选全部&#xff08;难&#xff09; 总…

「Eolink Apikit 教程」如何快速创建有效的API监控任务?

API 监控能够确保 API 的稳定性。如果一个 API 出现故障或崩溃&#xff0c;它可能会导致整个应用程序无法正常工作。这对用户和业务来说可能是灾难性的。通过监控 API&#xff0c;开发团队可以及时发现问题并采取措施来修复它们&#xff0c;从而降低应用程序中断的风险。 作为…

(免费领源码)PHP#mysql高校学生考证资源共享小程序35055-计算机毕业设计项目选题推荐

摘要 大学生“考证”已经成为大学生的一门必修课&#xff0c;越来越多的大学生加入考证的行列&#xff0c;他们认为毕业找工作的时候&#xff0c;证书是多多益善。大学生“考证热”应该引起学生&#xff0c;学校、以及社会用人单位等多方面的高度重视。大学生考证热潮的形成&am…

拉普拉斯噪声

拉普拉斯噪声是指从拉普拉斯分布中抽取的随机变量。拉普拉斯分布是一种连续型概率分布&#xff0c;其概率密度函数为&#xff1a; 拉普拉斯噪声在差分隐私&#xff08;Differential Privacy&#xff09;领域中被广泛使用&#xff0c;原因有以下几点&#xff1a; 灵活性&#xf…

学习笔记|单样本t检验|P值|两独立样本均数T检验|规范表达|《小白爱上SPSS》课程:SPSS第五讲 | 两独立样本均数T检验,你会了吗?

目录 学习目的软件版本原始文档P值是假设检验的终极者两独立样本均数T检验一、实战案例二、案例解析三、统计策略四、SPSS操作1、正态性检验2、T检验&#xff08;独立样本T检验&#xff09;结果 五、结果解读Tips&#xff1a;补充知识 六、规范报告1、规范表格2、规范文字 注意…

2.基于Jetson Nano的嵌入式小车避障项目

英伟达jetbot智能小车 一.数据采集 数据采集的时候&#xff0c;一定要不用的光线&#xff0c;不同的方向&#xff0c;不同的环境。 一般500-600张 二.AI训练 三.AI部署 import torch import torchvision3.1 加载预训练模型 第一步&#xff1a;载入模型 model torchvisi…

gitlab添加ssh秘钥

安装git 右击&#xff1a;git bash here 1.首先用如下命令&#xff08;如未特别说明&#xff0c;所有命令均默认在Git Bash工具下执行&#xff09;检查一下用户名和邮箱是否配置&#xff08;gitlab支持我们用用户名或邮箱登录&#xff09;&#xff1a; git config --global --…

『赠书第 2 期』- 『Django+Vue.js商城项目实战』

文章目录 1024 程序员节学习新技术关于作者内容介绍抽奖评论区抽三位小伙伴送书活动时间&#xff1a;截止到 2023-11-05 20:00:00 获奖名单 ps. 文末有抽奖&#xff0c;抽奖为 Swift社区 额外福利 1024 程序员节 受邀参加了 CSDN 举办的 1024 程序员节上海站的活动&#xff0…

【贝叶斯回归】【第 2 部分】--推理算法

一、说明 在第一部分中&#xff0c;我们研究了如何使用 SVI 对简单的贝叶斯线性回归模型进行推理。在本教程中&#xff0c;我们将探索更具表现力的指南以及精确的推理技术。我们将使用与之前相同的数据集。 二、模块导入 [1]:%reset -sf[2]:import logging import osimport tor…