Three.js入门以及案例(全方位解析)

news2024/11/24 22:25:32

下载three.js

压缩包

github链接查看所有版本

threejs:https://github.com/mrdoob/three.js/releases

在这里插入图片描述
下载即可

常用的文件目录

three.js-文件包
└───build——three.js相关库,可以引入你的.html文件中。
    │
└───docs——Three.js API文档文件
    │───index.html——打开该文件,本地离线方式预览threejs文档
└───examples——大量的3D案例,是你平时开发参考学习的最佳资源
    │───jsm——threejs各种功能扩展库
└───src——Three.js引擎的源码,有兴趣可以阅读。
    │
└───editor——Three.js的可视化编辑器,可以编辑3D场景
    │───index.html——打开应用程序  

three.js中文官网

https://threejs.org/docs/index.html#manual/zh/

CDN引入

在这里插入图片描述
在上面的中文文档中是有说到的,也有相应的解释,所以这里不CV了

npm

比如安装149版本

npm install three@0.149.0 --save

引入

npm引入

// 引入three.js
import * as THREE from ‘three’;

压缩包引入

<script src="./build/three.js"></script>

测试是否引入成功

//随便输入一个API,测试下是否已经正常引入three.js
console.log(THREE.Scene); 

在这里插入图片描述
引入成功

官网的模型案例

我们看下面的这段代码,是官网给我们的一个最基础的例子和模型

<html>
	<head>
		<meta charset="utf-8">
		<title>My first three.js app</title>
		<style>
			body { margin: 0; }
		</style>
	</head>
	<body>
		<script src="js/three.js"></script>
		<script>
			const scene = new THREE.Scene();
			const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

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

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

			camera.position.z = 5;

			function animate() {
				requestAnimationFrame( animate );

				cube.rotation.x += 0.01;
				cube.rotation.y += 0.01;

				renderer.render( scene, camera );
			};

			animate();
		</script>
	</body>
</html>

在这里插入图片描述
其中大概的意思官网也有给我们解释了
在这里插入图片描述
下面,我们也围绕这个例子来剖析一下,究竟是怎么做到的

创建3D场景、建立模型

为了真正能够让你的场景借助three.js来进行显示,我们需要以下几个对象:场景、相机和渲染器,这样我们就能透过摄像机渲染出场景。

场景创建

我们既然要去做3D的模型,就会需要一个展示3D的场景(也可以说是容器)

用来模拟我们生活中的3D世界

        const scene = new THREE.Scene()

我们利用three.js就创建了一个3D的场景对象scene,我们可以输出看一下

在这里插入图片描述
可以发现我们成功创建了一个场景,关于这些都是什么,现在先不着急了解

物体的形状(几何体)

很容易理解,不管是模型还是什么的东西,总归要有一个宏观的形状,所以就有它对应的api

几何体Geometry

  • 长方体:BoxGeometry
  • 圆柱体:CylinderGeometry
  • 球体:SphereGeometry
  • 圆锥:ConeGeometry
  • 矩形平面:PlaneGeometry
  • 圆平面:CircleGeometry

等等
这就对应了文档中的这部分
在这里插入图片描述
也推荐大家去官网看一看,因为有具体的API解释
这里我们创建一个长方体对象

        //创建一个长方体几何对象Geometry
        const geometry = new THREE.BoxGeometry(100, 100, 100);

在这里插入图片描述
这是我们属性的含义

物体的材质

材质很容易理解,大白话来说:光面啦,磨砂面的啊…等等
在这里插入图片描述
在这里插入图片描述
这里我们就创建一个网格基础材质

        //创建一个材质对象Material
        const material = new THREE.MeshBasicMaterial({
            color: 0xff0000,//这里可以设置颜色
        });

网格(Mesh)

在这里插入图片描述
怎么理解这个东西呢

其实就是我们在创建的虚拟的3D场景中,创建了一个虚拟的3D模型,那么,我们这个3D模型应该在哪里呢,或者说,放在哪呢,具体位置在哪呢

网格包含一个几何体以及作用在此几何体上的材质,我们可以直接将网格对象放入到我们的场景中,并让它在场景中自由移动。

这里一定要区别开Scene和Mesh

// 两个参数分别为几何体geometry、材质material
const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh

模型位置

很简单,就是这个几何体应该在哪,给个具体的方位

//设置网格模型在三维空间中的位置坐标,默认是坐标原点
mesh.position.set(0,10,0);

把模型添加到场景中

.add()方法

在threejs中你创建了一个表示物体的虚拟对象Mesh,需要通过.add()方法,把网格模型mesh添加到三维场景scene中。

scene.add(mesh); 

完整代码

        const scene = new THREE.Scene()
        //创建一个长方体几何对象Geometry
        const geometry = new THREE.BoxGeometry(50, 50, 50);
        //创建一个材质对象Material
        const material = new THREE.MeshBasicMaterial({
            color: 0x00ff00 ,//这里设置颜色
        });

        // 两个参数分别为几何体geometry、材质material
        const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
        //设置网格模型在三维空间中的位置坐标,默认是坐标原点
        mesh.position.set(0, 10, 0);
        // 把网格模型mesh添加到三维场景scene中
        scene.add(mesh);
        console.log(mesh);

我们打印一下看看
在这里插入图片描述

相机

我们现在已经创建模型了,并且也添加到了场景之中,但是我们光这样是无法显示的,现在就会有另一个重要的知识点-相机

这里我们采用最简单的

透视相机(PerspectiveCamera)

在这里插入图片描述

// 创建一个一个透视投影相机对象
const camera = new THREE.PerspectiveCamera();

相机位置

//相机在Three.js三维坐标系中的位置
// 根据需要设置相机位置具体值
camera.position.set(200, 200, 200); 

相机观察目标.lookAt()

就是控制我们的相机看哪里

camera.lookAt(mesh.position);//指向mesh对应的位置

在这里插入图片描述

画布(照片)

我们既然有相机了,那么肯定是有照片的,要不光有相机没有意义

而我们这个照片,就是基于canvas画布实现的

// 定义相机输出画布的尺寸(单位:像素px)
const width = 800; //宽度
const height = 500; //高度

PerspectiveCamera的四个参数

  • fov:视野角度,视野角度就是无论在什么时候,你所能在显示器上看到的场景的范围,它的单位是角度(与弧度区分开)。
  • aspect ratio:长宽比,也就是你用一个物体的宽除以它的高的值。比如说,当你在一个宽屏电视上播放老电影时,可以看到图像仿佛是被压扁的。
  • near:近截面,相机视锥体近裁截面相对相机距离
  • far:远截面,相机视锥体远裁截面相对相机距离,far-near构成了视锥体高度方向

在这里插入图片描述

// 30:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000:远裁截面
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);

渲染器

我们现在,有物体,有相机,有胶卷,还差什么
就差最后咔嚓茄子的那一下了对不对

完成这最后咔嚓的一步,我们还需要一个WebGL的渲染器对象

// 创建渲染器对象
const renderer = new THREE.WebGLRenderer();

设置Canvas画布尺寸

setSize()

renderer.setSize( window.innerWidth, window.innerHeight );

渲染

render()

renderer.render(scene, camera); //执行渲染操作

完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            margin: 0;
            padding: 0;
        }
    </style>
</head>

<body>
    <script src="./three.js-r148/build/three.js">
    </script>
    <script>
        const scene = new THREE.Scene()
        // 定义相机输出画布的尺寸(单位:像素px)
        const width = 800; //宽度
        const height = 500; //高度
        // 实例化一个透视投影相机对象
        const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
        // 创建渲染器对象
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(width, height);
        document.body.appendChild(renderer.domElement);
        //创建一个长方体几何对象Geometry
        const geometry = new THREE.BoxGeometry(50, 50, 50);
        //创建一个材质对象Material
        const material = new THREE.MeshBasicMaterial({
            color: 0x00ff00,
        });

        // 两个参数分别为几何体geometry、材质material
        const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
        //设置网格模型在三维空间中的位置坐标,默认是坐标原点
        mesh.position.set(0, 10, 0);
        //相机在Three.js三维坐标系中的位置
        // 根据需要设置相机位置具体值
        camera.position.set(200, 200, 200);
        camera.lookAt(mesh.position);//指向mesh对应的位置

        // 把网格模型mesh添加到三维场景scene中
        scene.add(mesh);
        renderer.render(scene, camera); //执行渲染操作
        console.log(renderer);
    </script>
</body>

</html>

效果图
在这里插入图片描述
当然,我这里没加旋转哈,这个很简单,重点还是上面说的各种知识点

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

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

相关文章

【机器学习算法】模型评估 “神经网络,聚类,向量机,关联规则”算法模型的评估。

模型评估* 数据集的切割 训练-测试数据的方式、交叉验证的方式 我们通常会把数据集切割为训练数据集或者测试数据集&#xff0c;训练数据集用来训练模型用&#xff0c;测试数据集我们一般用来测试模式的实际效能怎么样。 我们在将数据分为训练和测试数据集的时候我们会使用…

go-zero使用consul作为注册中心

目录 在rpc服务中添加配置 导入包&#xff1a; 在rpc服务中添加配置&#xff1a; 引入 Consul config 配置项 user.yml 文件 修改 user.go,将 rpc注册到consul rpc的发现 在api服务中添加配置&#xff1a; 修改api/etc/user.yam 文件 修改 user.yml 修改api/user.go …

@Import的用法

官方定义: https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#spring-core Using the ImportAnnotation Much as the <import/> element is used within Spring XML files to aid in modularizing configurations, the Import annotat…

一文详解ARP报文格式及工作原理

ARP&#xff08;地址解析协议&#xff09;作用&#xff1a;将目的IP解析为目的MAC&#xff0c;用于二层帧结构的目标MAC封装&#xff0c;数据必须封装为帧才能够被网卡发送出去&#xff0c;帧中必须包含MAC。报文格式&#xff1a;ARP报文不能穿越路由器&#xff0c;不能被转发到…

基于飞桨实现钢铁企业废钢判级迈入智能化道路

目前&#xff0c;国家“双碳”战略与“数据智能”环境正驱动着钢铁企业废钢判级迈入智能化道路。针对生产过程中带来高能耗和高污染问题&#xff0c;企业通过使用飞桨用友废钢智能判级系统&#xff0c;助力提升自身经济效益和安全生产水平。 建设背景 目前&#xff0c;国家“双…

如何在IDEA中创建Web项目

&#x1f44c; 棒棒有言&#xff1a;也许我一直照着别人的方向飞&#xff0c;可是这次&#xff0c;我想要用我的方式飞翔一次&#xff01;人生&#xff0c;既要淡&#xff0c;又要有味。凡事不必太在意&#xff0c;一切随缘&#xff0c;缘深多聚聚&#xff0c;缘浅随它去。凡事…

QT入门Buttons之QToolButton

目录 一、界面布局介绍 1、布局器中的位置及使用 2、控件的界面属性 2.1对象名称和大小设置 2.2对象文本设置和鼠标箭头更改 2.3、扁平化样式 二、属性功能介绍 1、显示箭头属性 2、按钮风格 3、添加默认action属性 三、Demo展示 此文为作者原创&#xff0c;转载请标…

Web前端:提高React Native应用程序性能的技巧

不可否认&#xff0c;React Native是开发混合应用的未来。它提供了可扩展性、灵活性、速度、敏捷性、成本效益和卓越的性能。难怪这么多成功的公司依赖React Native来构建他们的应用程序。毕竟&#xff0c;在互联网时代&#xff0c;每个企业都需要一个高性能的应用程序来满足客…

PCB如何进行阻抗设计经验总结

&#x1f3e1;《总目录》 目录1&#xff0c; 什么是阻抗匹配2&#xff0c;为何要阻抗匹配3&#xff0c;阻抗设计经验1&#xff0c; 什么是阻抗匹配 阻抗是指电路中两点间电阻&#xff0c;电感和电容的总称。而阻抗匹配是指&#xff0c;传输线及传输线两端的电子元器件的输入或输…

Canvas(HTML 5 元素)之绘制曲线图形

文章目录参考描述模板圆形圆形半圆形互补弧形arc()arcTo()二次贝塞尔曲线三次贝塞尔曲线参考 项目描述搜索引擎BingCanvas 中文网CanvasRenderingContext2DW3schoolHTML Canvas 参考手册从 0 到 1&#xff1a;HTML 5 Canvas 动画开发莫振杰 描述 项目描述Edge109.0.1518.70 (…

1.Java基础入门

目录 一.java概述 1.1 java语言发展史 1.2 为什么用Java 1.3 Java能做什么 1.4 Java技术体系 二.Java快速入门 2.1 如何使用Java 2.2 JVM&#xff0c;JRE&#xff0c;JDK 2.2.1 JVM 2.2.2 JRE 2.2.3 JDK 2.3 JDK的下载和安装 2.3.1 JDK的下载 2.3.2 JDK的安装 2.3.3 如何验证JD…

git版本回滚详解

写在前面&#xff1a;本文图片中出现的git st, git co分别是git status和git checkout的简写&#xff0c;使用中可以自行设置git config --global alias.st statusgit config --global alias.co checkout查看git配置文件 vim ~/.gitconfig1 工作区内的回滚操作当工作区的文件发…

Android 传感器概述(二)

Android 传感器概述&#xff08;二&#xff09;Android 传感器概述&#xff08;二&#xff09;运动传感器使用重力传感器使用线性加速度计使用旋转矢量传感器使用有效运动传感器使用计步器传感器使用步测器传感器使用原始数据使用加速度计使用陀螺仪使用未经校准的陀螺仪Androi…

【数据结构】动图详解单向链表

目录 1.什么是链表 1.问题引入 2. 链表的概念及结构 3. 问题解决 2.单向链表接口的实现 1.接口1&#xff0c;2---头插&#xff0c;尾插 2. 接口3&#xff0c;4---头删&#xff0c;尾删 3. 接口5---查找 4. 接口6&#xff0c;7---插入&#xff0c;删除 5. 接口8---打印 6. 注意…

CVE-2021-36934提权复现

CVE-2021-369342021年7 月 20 日&#xff0c;微软确认了一个新的本地提权漏洞(CVE-2021-36934)&#xff0c;被称为HiveNightmare。该漏洞由于Windows中多个系统文件的访问控制表(ACL)过于宽松&#xff0c;使得任何标准用户都可以从系统卷影副本中读取包括SAM、SYSETM、SECURITY…

Windows系统运行iOS设备管理软件iMazing2023

iMazing2023免费版是一款运行在Windows系统上的iOS设备管理软件&#xff0c;软件功能非常强大&#xff0c;界面简洁清晰&#xff0c;操作方便快捷&#xff0c;设计的非常有人性化&#xff0c;iMazing官方版为用户提供了多种设备管理功能&#xff0c;每一位用户都能以自己的形式…

MyISAM和InnoDB存储引擎的区别

目录前言存储引擎区别事务外键表单的存储数据查询效率数据更新效率如何选择前言 MyISAM和InnoDB是使用MySQL最常用的两种存储引擎&#xff0c;在5.5版本之前默认采用MyISAM存储引擎&#xff0c;从5.5开始采用InnoDB存储引擎。 存储引擎 存储引擎是&#xff1a;数据库管理系统…

小白如何快速入门Verilog HDL ?一文为你讲解清楚

在学习的过程中&#xff0c;无论学什么都不可能一蹴而就。都是从一个初步认识到慢慢了解再到精通掌握的过程&#xff0c;学习Verilog HDL语法也是一样的道理&#xff0c;首先你要清楚什么是Verilog HDL&#xff0c;然后结合实践再遵从理论&#xff0c;这样后面的学习才能理解的…

P1359 租用游艇

# 租用游艇 ## 题目描述 长江游艇俱乐部在长江上设置了 $n$ 个游艇出租站 $1,2,\cdots,n$。游客可在这些游艇出租站租用游艇&#xff0c;并在下游的任何一个游艇出租站归还游艇。游艇出租站 $i$ 到游艇出租站 $j$ 之间的租金为 $r(i,j)$&#xff08;$1\le i\lt j\le n$&#xf…

MPLS实验(1.31)

目标&#xff1a; 一、首先为公网的每个路由器配置对应的ip和环回并且用OSPF进行动态选路 r2&#xff1a; [r2]int gi 0/0/2 [r2-GigabitEthernet0/0/2]ip add 23.1.1.1 24 [r2-GigabitEthernet0/0/2]int lo0 [r2-LoopBack0]ip add 2.2.2.2 24 r3&#xff1a; [r3]int gi 0…