three.js 安装方法、基础简介、创建基础场景

threejs简介

Three.js是一个基于JavaScript编写的开源3D图形库,‌利用WebGL技术在网页上渲染3D图形。‌ 它提供了许多高级功能,‌如几何体、‌纹理、‌光照、‌阴影等,‌使得开发者能够快速创建复杂且逼真的3D场景。‌
threejs提供了丰富的功能和工具,让开发者能够轻松的创建3D对象、设置灯光、添加动画、处理用户交互等。它支持多种3D格式的导入,如OBJ、GLTF等,也支持自定义的材质和着色器。
threejs相关文档:

  • 官网:https://threejs.org/
  • 官方文档:https://threejs.org/docs/index.html#manual/zh/

threejs安装

在项目中引入threejs,比如你采用的是Vue + threejs或React + threejs技术栈,这很简单,threejs就是一个js库,直接通过npm命令安装即可。

npm install three

注意:很多基于threejs的库开发的三方库(比如ThreeBSP)对于threejs的版本有要求。可以指定版本安装(注意使用哪个版本,查看文档就对应的版本)。

// 比如安装124版本
npm install three@0.124.0

npm安装后,如何引入three.js

执行import * as THREE from 'three';,ES6语法引入three.js核心。

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

npm安装后,如何引入threejs其他扩展库

除了three.js核心库以外,在threejs文件包中example/js目录下,你还可以看到各种不同功能的扩展库。
一般来说,你项目用到那个扩展库,就引入哪个,用不到就不需要引入。

// 引入扩展库OrbitControls.js
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// 引入扩展库GLTFLoader.js
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

three.js基础

入门three.js的第一步就是认识场景Scene、相机Camera、渲染器**Renderer**三个基本概念。
在这里插入图片描述

场景Scene

场景能够让你在什么地方、摆放什么东西来交给three.js来渲染,这是你放置物体、灯光和摄像机的地方。场景本身不包含几何形状或材质,但是它可以包含多个三维对象,你可以把它理解成放置物体的容器

// 创建场景
const scene = new THREE.Scene();

场景对象还提供了一些方法和属性,用于控制场景的行为和外观。例如,可以设置场景的背景颜色、雾化效果等。

// 设置背景为黑色
scene.background = new THREE.Color(0x000000); 
// 创建雾化效果
scene.fog = new THREE.Fog(0xffffff, 100, 200);

相机Camera

three.js中相机是一个重要的组件,它决定了场景如何被观察。three.js支持多种相机类型,如透视相机(PerspectiveCamera)和正交相机(OrthographicCamera)。
在这里插入图片描述

相机位置.position

生活中用相机拍照,你相机位置不同,拍照结果也不同,threejs中虚拟相机同样如此。
比如有一间房子,你拿着相机站在房间里面,看到的是房间内部,站在房子外面看到的是房子外面效果。
相机对象Camera具有位置属性.position,通过位置属性.position可以设置相机的位置。

// 根据需要设置相机位置具体值
camera.position.set(200, 200, 200);

相机观察目标.lookAt()

你用相机拍照你需要控制相机的拍照目标,具体说相机镜头对准哪个物体或说哪个坐标。对于threejs相机而言,就是设置.lookAt()方法的参数,指定一个3D坐标。

//坐标原点
camera.lookAt(0, 0, 0);
// y轴上位置10
camera.lookAt(0, 10, 0);
// 指向mesh对应的位置
camera.lookAt(mesh.position);

在这里插入图片描述
如何判断相机相对于场景中长方体的位置?根据相机位置和长方体位置尺寸对比,判断两者相对位置。

// 长方体尺寸100, 100, 100
const geometry = new THREE.BoxGeometry( 100, 100, 100 );
const mesh = new THREE.Mesh(geometry, material);
// 网格模型位置xyz坐标
mesh.position.set(0,10,0);
// 相机位置xyz坐标
camera.position.set(200, 200, 200);

定义相机渲染输出画布尺寸

生活中相机拍照的照片是有大小的,对于threejs而言一样,需要定义相机在网页上输出的Canvas画布(照片)尺寸,大小可以根据需要定义。

const width = window.innerWidth; // canvas画布宽度
const height = window.innerHeight; // canvas画布高度

透视投影相机

透视投影相机PerspectiveCamera本质上就是在模拟人眼观察这个世界的规律。可调位置、角度等信息,展示不同画面。
在这里插入图片描述
透视投影相机的四个参数fov, aspect, near, far构成一个四棱台3D空间,被称为视锥体,只有视锥体之内的物体,才会渲染出来,视锥体范围之外的物体不会显示在Canvas画布上。

PerspectiveCamera( fov, aspect, near, far )
参数介绍
  • fov:相机视锥体竖直方向视野角度,默认值50。
  • aspect:相机视锥体水平方向和竖直方向长度比,一般设置为Canvas画布宽高比width / height,默认值1。
  • near:相机视锥体近裁截面相对相机距离,默认值0.1。
  • far:相机视锥体远裁截面相对相机距离,far-near构成了视锥体高度方向,默认值2000。
// width和height用来设置Three.js输出的Canvas画布尺寸(像素px)
const width = window.innerWidth; // canvas画布宽度
const height = window.innerHeight; // canvas画布高度
// 实例化一个透视投影相机对象 30:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000:远裁截面
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);

注意:1. 相机位置拉远可以看到更大的观察范围。
2. 超出视锥体远裁界面的范围的会被剪裁掉。

正投影相机

在正投影相机的投影模式下,无论物体距离相机距离远或者近,在最终渲染的图片中物体的大小都保持不变。这意味着所有物体在渲染时保持相同的尺寸,不受距离的影响。对于渲染2D场景或者UI元素是非常有用的。
在这里插入图片描述
正投影相机的六个参数left, right, top, bottom, near, far构成一个长方体可视化空间,和透视投影相机PerspectiveCamera视锥体相似,只是形状不同,两者的区别是透视投影可以模拟人眼观察世界的视觉效果,正投影相机不会。

OrthographicCamera( left, right, top, bottom, near, far )
参数介绍
  • left:渲染空间的左边界。
  • right:渲染空间的右边界。
  • top:渲染空间的上边界。
  • bottom:渲染空间的下边界。
  • near:属性表示的是从距离相机多远的位置开始渲染,一般情况会设置一个很小的值,默认值0.1。
  • far:属性表示的是距离相机多远的位置截止渲染,如果设置的值偏小小,会有部分场景看不到,默认值2000。
// width和height用来设置Three.js输出的Canvas画布尺寸(像素px)
const width = window.innerWidth; // canvas画布宽度
const height = window.innerHeight; // canvas画布高度
const k = width / height; // canvas画布宽高比
const s = 600; // 控制left, right, top, bottom范围大小
const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 8000);

相机参数更新

透视投影相机PerspectiveCamera.aspect属性受到canvas画布宽高度影响,当canvas画布尺寸发生变化的时候,需要更新透视投影相机的.aspect属性。

window.onresize = function () {// width、height表示canvas画布宽高度camera.aspect = width / height;// 相机的aspect属性变化了,通知threejs系统camera.updateProjectionMatrix();
};

正投影相机OrthographicCameraleftright属性受到canvas画布宽高比影响,所以需要随着canvas画布更新。

window.onresize = function () {// 更新相机参数const k = width / height; //canvas画布宽高比camera.left = -s*k;camera.right = s*k;// 相机的left, right, top, bottom属性变化了,通知threejs系统camera.updateProjectionMatrix();
};

相机选择

对于大部分需要模拟人眼观察效果的场景,需要使用透视投影相机,比如人在场景中漫游,或是在高处俯瞰整个园区或工厂。
正投影没有透视效果,也就是不会模拟人眼观察世界的效果。在一些不需要透视的场景你可以选择使用正投影相机,比如整体预览一个中国地图的效果,或者一个2D可视化的效果。

渲染器

生活中如果有了景物和相机,那么如果想获得一张照片,就需要你拿着相机,按一下,咔,完成拍照。对于threejs而言,如果完成“咔”这个拍照动作,就需要一个新的对象,也就是WebGL渲染器WebGLRenderer。

WebGL渲染器

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

设置canvas画布尺寸.setSize

// 定义threejs输出画布的尺寸(单位:像素px)
const width = window.innerWidth; // canvas画布宽度
const height = window.innerHeight; // canvas画布高度
renderer.setSize(width, height); //设置three.js渲染区域的尺寸(像素px)

渲染器渲染方法.render()

渲染器WebGLRenderer执行渲染方法.render()就可以生成一个Canvas画布(照片),并把三维场景Scene呈现在canvas画布上面,你可以把.render()理解为相机的拍照动作“咔”。

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

渲染循环,更新场景渲染,根据当前计算机浏览器刷新帧率(默认 60 次/秒),不断递归调用此函数渲染最新的画面状态,当前页面切换到后台后暂停递归。

// 渲染循环
function render() {camera.position.z -= 0.3;//相机直线运动动画renderer.render(scene, camera);requestAnimationFrame(render);
}
render();

渲染器Canvas画布属性.domElement

渲染器WebGLRenderer通过属性.domElement可以获得渲染方法.render()生成的Canvas画布,.domElement本质上就是一个HTML元素:Canvas画布。

document.body.appendChild(renderer.domElement);

可以把threejs的渲染结果renderer.domElement,插入到web页面上任何一个HTML元素中,只要符合你的项目布局规则即可。

<div id="canvas"></div>
document.getElementById('webgl').appendChild(renderer.domElement);

canvas画布宽高度动态变化

window.onresize = function () {// 重置渲染器输出画布canvas尺寸renderer.setSize(window.innerWidth, window.innerHeight);
};

渲染器其他属性设置

const renderer = new THREE.WebGLRenderer({antialias:true, // 锯齿属性alpha: true, // 背景透明preserveDrawingBuffer:true,//想把canvas画布上内容下载到本地
});

创建基础场景

// 创建场景
const scene = new THREE.Scene();
// 创建透视投影相机,视角45度,画幅比例 宽比高,近平面距离0.1,远平面1000
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
const width = window.innerWidth; // canvas画布宽度
const height = window.innerHeight; // canvas画布高度
// 渲染器canvas宽高设为与窗口一致
renderer.setSize(width, height);
// 将渲染器对应的dom元素添加到body中
document.body.appendChild(renderer.domElement);
// 移动相机位置
camera.position.set(0, 200, 300);
renderer.render(scene, camera);

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

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

相关文章

【Linux系列】known_hosts详解

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

通过Go示例理解函数式编程思维

一个孩子要尝试10次、20次才肯接受一种新的食物&#xff0c;我们接受一种新的范式&#xff0c;大概不会比这个简单。-- 郭晓刚 《函数式编程思维》译者 函数式编程(Functional Programming, 简称fp)是一种编程范式&#xff0c;与命令式编程(Imperative Programming)、面向对象编…

【网络ping】无法ping通电脑 服务器失败是什么原因

【网络ping】无法ping通电脑 服务器失败是什么原因 转载&#xff1a; https://www.lsjlt.com/ask/show/show.php?id80772631782 点击此处 查看博文《无法ping通的原因》 一、无法ping 通的原因 网络连接问题&#xff1a;首先需要检查网络连接是否正常。可以尝试通过ping其他…

模型部署 - docker

docker简介 Docker 是一种开源的容器化平台&#xff0c;允许开发者将应用程序及其依赖项打包到一个标准化的单元中&#xff0c;称为“容器”。这些容器可以在任何支持 Docker 的系统上运行&#xff0c;无需担心环境差异。 为什么需要 Docker&#xff1f; 在传统的开发中&…

MySQL 5.7 DDL 与 GH-OST 对比分析

作者&#xff1a;来自 vivo 互联网存储研发团队- Xia Qianyong 本文首先介绍MySQL 5.7 DDL以及GH-OST的原理&#xff0c;然后从效率、空间占用、锁阻塞、binlog日志产生量、主备延时等方面&#xff0c;对比GH-OST和MySQL5.7 DDL的差异。 一、背景介绍 在 MySQL 数据库中&…

MyBatis--XML映射文件

MyBatis–XML映射文件 lombok工具包 为了解决声明实体类的get()和set()函数臃肿的问题&#xff0c;我们使用lombok工具包。 我们看一下lombok工具包为我们提供的注解&#xff1a; XML映射文件 我们需要遵守下面的规则&#xff1a; 首先XML映射文件和Mapper接口包应该在同…

wps怎么找回未保存的文件?分享三个文件恢复方法

在编辑WPS文档时&#xff0c;偶尔会遇到未保存就意外关闭的情况&#xff0c;这不仅令人沮丧&#xff0c;还可能导致重要信息的丢失。但幸运的是&#xff0c;WPS提供了多种途径来帮助用户找回这些未保存的宝贵文件。从利用WPS的自动备份与恢复功能&#xff0c;到检查最近文档列表…

树形结构查找(B树、B+树)

平衡树结构的树高为 O(logn) &#xff0c;平衡树结构包括两种平衡二叉树结构&#xff08;分别为 AVL 树和 RBT&#xff09;以及一种树结构&#xff08;B-Tree&#xff0c;又称 B 树&#xff0c;它的度大于 2 &#xff09;。AVL 树和 RBT 适合内部存储的应用&#xff0c;而 B 树…

堆(数据结构)

堆的概念与结构 堆的底层逻辑是一个完全二叉树&#xff08;或满二叉树&#xff09;。 堆的分类 大根堆和小根堆 大根堆 所谓大根堆就是每一个父节点都要大于等于子结点 小根堆 所谓小根堆就是每一个父节点都要小于等于子结点 堆的实现 (未完待续 待续......)

力扣高频SQL 50题(基础版)第四十四题之626. 换座位

文章目录 力扣高频SQL 50题&#xff08;基础版&#xff09;第四十四题之626. 换座位626. 换座位题目说明思路分析实现过程准备数据实现方式结果截图 力扣高频SQL 50题&#xff08;基础版&#xff09;第四十四题之626. 换座位 626. 换座位 题目说明 表: Seat --------------…

【网络】IP-VPN技术概述

目录 引言 核心协议 封装与加密 工作流程 IP-VPN的应用场景 MPLS-VPN 个人主页&#xff1a;东洛的克莱斯韦克-CSDN博客 引言 IP-VPN&#xff08;Internet Protocol - Virtual Private Network&#xff09;是一种通过公共网络实现私密、安全通信的技术。它主要依赖于互联网…

力扣系统刷题-树(一)

放松了一周,也一周都没写题了,接下来,我做题的方式可能会更趋向于成体系的学习,今天就先从树的章节开始学起,主要参考的学习资料还是博客,知乎等网上较为系统的教材,涉及到的参考内容我都会进行标注,并以力扣题目作为导向来学习. 一.树 1. 什么是树 根据维基百科的定义:在计…

InfluxDB Studio 下载,时序数据库Windows图形界面操作

下载地址&#xff1a; https://github.com/CymaticLabs/InfluxDBStudio/releases解压缩后&#xff0c;双击 InfluxDBStudio.exe 运行。 参考 windows下 influxDB 操作工具 InfluxDBStudio 吐槽 现在 CSDN 太恶心了&#xff0c;动不动就让订阅或者积分下载资源。诚然&#…

主机组装笔记

参考资源&#xff1a;B站【装机教程】全网最好的装机教程&#xff0c;没有之一&#xff0c;仅供探讨学习 9大部件一览 其中得到固态和机械&#xff0c;是硬盘&#xff0c;存储空间&#xff0c;可以只选固态 CPU&#xff0c;主要有 AMD 和 Intel (AMD&#xff0c;基板的背面布…

nvm的下载和使用(Windows)

NVM&#xff08;Node Version Manager&#xff09;是一个用于管理多个Node.js版本的工具&#xff0c;它允许用户在同一台机器上安装和使用多个Node.js版本。 一、NVM的基本功能 多版本支持&#xff1a;NVM允许用户在同一台机器上安装多个Node.js版本&#xff0c;方便处理不同…

docker:在官方停止国内服务的情况下安装使用docker

前言 很烦,前段时间docker官方已经全面停止国内网络访问了,但业务又依赖docker,所以这里只能通过科学的方案来处理这件事: 系统:ubuntu 22.04 desktop 目的:在官方停止国内服务的情况下,安装使用docker 关键技术:科学工具(小猫猫) 安装科学工具 没有安装包的,可以自…

Re常见简单密码

Re常见简单密码 起码没有Crypto专项那么柜物。。。 文章目录 Re常见简单密码1. RC4算法2. TEA算法3. XTEA算法4. XXTEA算法5. DASCTF strangeprograme参考 C语言stdint.h提供如下类型 int8_t 八位有符号整数 uint8_t 八位无符号整数 int16_t int32_t int64_t 64为有符号整数c…

定时器介绍

定时器介绍 STM32F103C8T6微控制器内部集成了多种类型的定时器&#xff0c;这些定时器在嵌入式系统中扮演着重要角色&#xff0c;用 于计时、延时、事件触发以及PWM波形生成、脉冲捕获等应用。下面是对STM32F103C8T6中几个定时器的 简单介绍&#xff1a;TIM1&#xff1a;这是一…

细数那些令人瞩目的内网穿透工具

在日常工作场景中&#xff0c;我们时常面临需要将本地网络中的特定端口&#xff08;如80、3306等&#xff09;对外开放&#xff0c;以便让远程用户或设备跨越局域网界限进行访问的需求。为实现这一目标&#xff0c;端口映射&#xff08;又称内网穿透&#xff09;技术显得尤为重…

Qt项目【上位机十字屏开发】

效果图 说明 重写 QWidget 中的 paintEvent() 处理绘图事件&#xff0c;废话不多说&#xff0c;上代码 源码 #ifndef MYWIDGETFORM_H #define MYWIDGETFORM_H#include <QWidget>namespace Ui { class myWidgetForm; }enum MYTYPE{SIZEWIDTH,SIZEHEIGHT,TOPWIDTH,TOPHE…