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

news2024/11/25 20:19:47

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.coloradmin.cn/o/2035754.html

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

相关文章

云原生日志Loki

1. Loki简介 1.1 Loki介绍 Loki是 Grafana Labs 团队最新的开源项目&#xff0c;是一个水平可扩展&#xff0c;高可用性&#xff0c;多租户的日志聚合系统。它的设计非常经济高效且易于操作&#xff0c;因为它不会为日志内容编制索引&#xff0c;而是为每个日志流编制一组标签…

关于Vue项目npm快捷键,点击run启动报错,及npm i也报错的解决办法

1.配置idea的npm 2.点击运行按钮 3.结果 分析原因及问题&#xff1a; npm i npm run dev 由于是刚刚从gitlab新拉的前端代码&#xff0c;可能没有用命令install过类似于没有编译过&#xff0c;所以执行一下上面的命令 结果报错如下&#xff1a; F:\tbyf\qjyy\hip-manager-ui&…

SpringBoot整合MyBatis-Plus完整详细版(提供Gitee源码)

前言&#xff1a;本篇文章完整详细介绍了SpringBoot整合MyBatis-Plus的完整过程&#xff0c;这边我的SpringBoot版本是2.4版本、JDK1.8和Maven3.8.1版本&#xff0c;跟着文章一步步走就可以了&#xff0c;MyBatis-Plus整合非常方便&#xff0c;也是现在企业开发中经常会用的一个…

学习笔记第二十四天

1.exec族函数的区别 int exec l(const char *path, const char *arg, ...); int exec l p(const char *file, const char *arg, ...); int exec l e(const char *path, const char *arg,..., char * const envp[]); int exec v(const char *path, char *const argv[]); …

1011 World Cup Betting

题目 解释 题目讲的就是&#xff0c;给你三行数&#xff0c;每一行包含3个浮点小数&#xff0c;让你找到最大的那个小数&#xff0c;然后如果最后的小数是第一个&#xff0c;输出W&#xff0c;是第二个&#xff0c;输出T&#xff0c;是第三个&#xff0c;输出L&#xff0c;最后…

Day37 | 188.买卖股票的最佳时机IV 309.最佳买卖股票时机含冷冻期 714.买卖股票的最佳时机含手续费

语言 Java 188.买卖股票的最佳时机IV 买卖股票的最佳时机IV 题目 给你一个整数数组 prices 和一个整数 k &#xff0c;其中 prices[i] 是某支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。也就是说&#xff0c;你最多…

Broken: Gallery靶机复现

靶机设置 靶机设置为NAT模式 靶机IP发现 nmap 192.168.112.0/24 靶机IP为192.168.112.142 目录扫描 dirsearch 192.168.112.142 访问浏览器 发现文件页面 查看后发现都没什么用 getshell hydra -L rockyou.txt -P rockyou.txt 192.168.112.142 ssh 尝试爆破ssh账号密码…

互联网应用主流框架整合【Redis常用技术】

和其他大部分NoSQL不同&#xff0c;Redis是支持事务的&#xff0c;尽管没有数据库那么强大&#xff0c;但非常有用&#xff0c;在某些高并发但又要保证高度一致性的场景下&#xff0c;代替数据库事务非常有效&#xff1b;在Redis的机制中&#xff0c;允许通过流水线一次性发给R…

DATAX自定义KafkaWriter

因为datax目前不支持写入数据到kafka中&#xff0c;因此本文主要介绍如何基于DataX自定义KafkaWriter&#xff0c;用来同步数据到kafka中。本文偏向实战&#xff0c;datax插件开发理论宝典请参考官方文档&#xff1a; https://github.com/alibaba/DataX/blob/master/dataxPlug…

2024年TI杯E题-三子棋游戏装置方案分享-jdk123团队-第二弹 手搓机械臂

第一弹赛题的选择与前期方案的准备 opencv调用摄像头bug的解决 机械臂的组装 采用三个舵机&#xff0c;组成一个三自由度的机械臂。 并且利用电磁吸盘的方式&#xff0c;完成对棋子的抓取工作&#xff0c;后面的事实证明&#xff0c;在预算不足的情况下&#xff0c;队友手搓…

顺序表的实现——数据结构

线性表 文章目录 线性表线性表的定义和基本操作线性表的定义线性表的基本操作 线性表的顺序表示顺序表的定义顺序表的实现——静态分配顺序表的实现——动态分配顺序表的特点 线性表的定义和基本操作 线性表的定义 线性表&#xff08;Linear List&#xff09;的定义 ​ 线性…

多进程多线程

exec 系列函数 结束代码函数 atexec 函数 结束标志&#xff0c;从下往上 先出2再出1 void cleanup1() {printf("clean1"); }void cleanup2() {printf("clean2"); }atexec(cleanup1) atexec(cleanup2)

28. 找出字符串中第一个匹配项的下标【 力扣(LeetCode) 】

一、题目描述 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;则返回 -1 。 二、测试用例 示例 1&#xff1a; 输…

Cmake编译工程

Cmake目录结构&#xff1a;项目主目录中会放一个CmakeList.txt的文本文档&#xff0c;后期使用cmake指令时候&#xff0c;依赖的就是该文档 1.包含源文件的子文件夹包含Cmakelist.txt文件时&#xff0c;主目录的Cmakelists.txtx要通过add_subdirector添加子目录 2.包含源文件…

算法3:二分查找(下)

文章目录 寻找峰值寻找旋转数组最小值 寻找峰值 class Solution { public:int findPeakElement(vector<int>& nums) {int left 0, right nums.size() - 1;while(left < right){int mid left (right - left) / 2;if(nums[mid] < nums[mid 1])left mid 1;…

opencv-python图像增强三:图像清晰度增强

文章目录 一、简介&#xff1a;二、图像清晰度增强方案&#xff1a;三、算法实现步骤3.1高反差保留实现3.2. usm锐化3.3 Overlay叠加 四&#xff1a;整体代码实现五&#xff1a;效果 一、简介&#xff1a; 你是否有过这样的烦恼&#xff0c;拍出来的照片总是不够清晰&#xff…

视频汇聚/安防监控综合平台EasyCVR接入海康私有协议EHOME显示失败是什么原因?

安防监控/视频综合管理平台/视频集中存储/磁盘阵列EasyCVR视频汇聚平台&#xff0c;支持多种视频格式和编码方式&#xff08;H.264/H.265&#xff09;&#xff0c;能够轻松对接各类前端监控设备&#xff0c;实现视频流的统一接入与集中管理。安防监控EasyCVR平台支持多种流媒体…

Stable Diffusion【 ControlNet实战】OpenPose 轻松制作武侠动作

前言 hello&#xff0c;大家好** 好了&#xff0c;进入正题。如何通过Stable Diffusion ControlNet来进行姿态控制。来一起来看下老徐的简单示例&#xff1a; 老徐参数设置&#xff1a; **大模型&#xff1a;**墨幽人造人_v1080 所有的AI设计工具&#xff0c;模型和插件&…

25届秋招网络安全面试资料库

吉祥知识星球http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247485367&idx1&sn837891059c360ad60db7e9ac980a3321&chksmc0e47eebf793f7fdb8fcd7eed8ce29160cf79ba303b59858ba3a6660c6dac536774afb2a6330#rd 《网安面试指南》http://mp.weixin.qq.com/s?…

机器人中的wrench(力旋量)

在机器人领域&#xff0c;wrench&#xff08;力旋量&#xff09;是一个由力和力矩组成的6D空间向量&#xff0c;用于描述刚体在空间中受到的力和力矩的综合作用。具体来说&#xff0c;wrench可以看作是一个包含线性分量和旋转分量的矢量&#xff0c;其中线性分量代表作用在刚体…