Three.js 官方文档学习笔记

news2024/9/25 7:16:14

Address:Three.js中文网 (webgl3d.cn)

Author:方越 50041588

Date:2024-07-19

img

第一个3D案例—创建3D场景

创建3D场景对象Scene:

const scene = new THREE.Scene();

创建一个长方体几何对象Geometry:

const geometry = new THREE.BoxGeometry(100, 100, 100); 

常见几何体对象如下:

创建一个材质对象Material:

const material = new THREE.MeshBasicMaterial({
    color: 0xff0000,//0xff0000设置材质颜色为红色
}); 

常见材质对象如下:

创建一个网格模型对象Mesh,两个参数分别为几何体geometry、材质material:

const mesh = new THREE.Mesh(geometry, material);

设置网格模型在三维空间中的位置坐标,默认是坐标原点:

mesh.position.set(0,10,0);

把网格模型mesh添加到三维场景scene中:

scene.add(mesh); 

第一个3D案例—透视投影相机

实例化一个透视投影相机对象:

const camera = new THREE.PerspectiveCamera();

相机在Three.js三维坐标系中的位置,根据需要设置相机位置具体值:

camera.position.set(200, 200, 200); 

相机观察目标指向Threejs 3D空间中某个位置:

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

img

透视投影相机的四个参数fov, aspect, near, far构成一个四棱台3D空间,被称为视锥体,只有视锥体之内的物体,才会渲染出来,视锥体范围之外的物体不会显示在Canvas画布上:

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

视锥体

第一个3D案例—渲染器

创建渲染器对象:

const renderer = new THREE.WebGLRenderer();

定义threejs输出画布的尺寸(单位:像素px):

const width = 800; //宽度
const height = 500; //高度
renderer.setSize(width, height); //设置three.js渲染区域的尺寸

执行渲染操作:

renderer.render(scene, camera);

Canvas画布插入到任意HTML元素中:

<div id="webgl" style="margin-top: 200px;margin-left: 100px;"></div>
document.getElementById('webgl').appendChild(renderer.domElement);

三维坐标系-加强三维空间认识

辅助观察的坐标系AxesHelper:

const axesHelper = new THREE.AxesHelper(150);
scene.add(axesHelper);

设置材质半透明,这样可以看到坐标系的坐标原点:

const material = new THREE.MeshBasicMaterial({
    color: 0x0000ff, //设置材质颜色
    transparent:true,//开启透明
    opacity:0.5,//设置透明度
});

光源对物体表面影响

MeshBasicMaterial不受光照影响:

const material = new THREE.MeshBasicMaterial(); 

MeshLambertMaterial受光照影响:

const material = new THREE.MeshLambertMaterial(); 

光源对物体表面影响关系如下:

常见光源分类如下:

点光源:两个参数分别表示光源颜色和光照强度:

// 参数1:0xffffff是纯白光,表示光源颜色
// 参数2:1.0,表示光照强度,可以根据需要调整
const pointLight = new THREE.PointLight(0xffffff, 1.0);

光源衰减属性decay默认值是2.0,如果不希望衰减可以设置为0.0:

pointLight.decay = 0.0;//设置光源不随距离衰减

设置点光源位置:

pointLight.position.set(400, 0, 0);//点光源放在x轴上

点光源添加到场景中:

scene.add(pointLight); 

相机控件OrbitControls

引入轨道控制器扩展库OrbitControls.js:

import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

设置相机控件轨道控制器OrbitControls:

const controls = new OrbitControls(camera, renderer.domElement);
// 如果OrbitControls改变了相机参数,重新调用渲染器渲染三维场景
controls.addEventListener('change', function () {
	renderer.render(scene, camera); //执行渲染操作
});//监听鼠标、键盘事件

平行光与环境光

点光源辅助观察:

const pointLightHelper = new THREE.PointLightHelper(pointLight, 10);
scene.add(pointLightHelper);

环境光:没有特定方向,整体改变场景的光照明暗:

const ambient = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambient);

平行光:沿着特定方向发射:

const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
// 设置光源的方向:通过光源position属性和目标指向对象的position属性计算
directionalLight.position.set(80, 100, 50);
// 方向光指向对象网格模型mesh,可以不设置,默认的位置是0,0,0
directionalLight.target = mesh;
scene.add(directionalLight);

可视化平行光DirectionalLightHelper:

const dirLightHelper = new THREE.DirectionalLightHelper(directionalLight, 5, 0xff0000);
scene.add(dirLightHelper);

动作渲染循环

requestAnimationFrame实现周期性循环执行,用其实现threejs旋转动画:

const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);

function render() {
    renderer.render(scene, camera); //执行渲染操作
    mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
    requestAnimationFrame(render);//请求再次执行渲染函数render,渲染下一帧
}
render();

Canvas画布布局和全屏

全屏渲染canvas:

// width和height用来设置Three.js输出的Canvas画布尺寸(像素px)
const width = window.innerWidth; //窗口文档显示区的宽度作为画布宽度
const height = window.innerHeight; //窗口文档显示区的高度作为画布高度
const renderer = new THREE.WebGLRenderer();
document.body.appendChild(renderer.domElement);

onresize 事件会在窗口被调整大小时发生,实现宽高度动态变化:

window.onresize = function () {
	// 重置渲染器输出画布canvas尺寸
    renderer.setSize(window.innerWidth, window.innerHeight);
    // 全屏情况下:设置观察范围长宽比aspect为窗口宽高比
    camera.aspect = window.innerWidth / window.innerHeight;
    // 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix
    // 但是不会每渲染一帧,就通过相机的属性计算投影矩阵(节约计算资源)
    // 如果相机的一些属性发生了变化,需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
    camera.updateProjectionMatrix();
};

stats查看threejs渲染帧率

引入性能监视器stats.js:

import Stats from 'three/addons/libs/stats.module.js';

创建stats对象:

const stats = new Stats();
//stats.domElement:web页面上输出计算结果,一个div元素,
document.body.appendChild(stats.domElement);
function render() {
//requestAnimationFrame循环调用的函数中调用方法update(),来刷新时间
stats.update();
renderer.render(scene, camera); //执行渲染操作
requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧
}
render();

通过setMode()方法的参数mode的数值设置首次打开页面,测试结果的显示模式:

//stats.domElement显示:渲染帧率 刷新频率,一秒渲染次数 
stats.setMode(0);//默认模式
//stats.domElement显示:渲染周期 渲染一帧多长时间(单位:毫秒ms)
stats.setMode(1);

阵列立方体和相机适配体验

相机控件OrbitControls会影响lookAt设置,注意手动设置OrbitControls的目标参数:

const controls = new OrbitControls(camera, renderer.domElement);
// 相机控件.target属性在OrbitControls.js内部表示相机目标观察点,默认0,0,0
// console.log('controls.target', controls.target);
controls.target.set(1000, 0, 1000);
controls.update();//update()函数内会执行camera.lookAt(controls.target)

Threejs常见几何体简介

常见几何体对象:

//BoxGeometry:长方体
const geometry = new THREE.BoxGeometry(100, 100, 100);
// SphereGeometry:球体
const geometry = new THREE.SphereGeometry(50);
// CylinderGeometry:圆柱
const geometry = new THREE.CylinderGeometry(50,50,100);
// PlaneGeometry:矩形平面
const geometry = new THREE.PlaneGeometry(100,50);
// CircleGeometry:圆形平面
const geometry = new THREE.CircleGeometry(50);

Three.js的材质默认正面可见,反面不可见,对于矩形平面、圆形平面如果你想看到两面,可以设置side:

new THREE.MeshBasicMaterial({
	side: THREE.FrontSide, //默认只有正面可见
});
new THREE.MeshBasicMaterial({
 	side: THREE.DoubleSide, //两面可见
});

高光网格材质Phong

MeshPhongMaterial 可以提供一个镜面反射效果,可以类比你生活中拿一面镜子,放在太阳光下,调整角度,可以把太阳光反射到其它地方,如果反射光对着眼睛,也就是反射光线和视线平行的时候,会非常刺眼。

MeshLambertMaterial 对应的Mesh受到光线照射,没有镜面反射的效果,只是一个漫反射,也就是光线向四周反射。

// 模拟镜面反射,产生一个高光效果
const material = new THREE.MeshPhongMaterial({
	color: 0xff0000,
	shininess: 20, //高光部分的亮度,默认30
	specular: 0x444444, //高光部分的颜色
});

WebGL渲染器设置(锯齿模糊)

设置锯齿属性:

renderer.antialias = true; 

获取你屏幕对应的设备像素比devicePixelRatio,告诉threejs,以免渲染模糊问题:

renderer.setPixelRatio(window.devicePixelRatio);

设置背景颜色:

renderer.setClearColor(0x444444, 1); 

gui.js库(可视化改变三维场景)

引入dat.gui.js的一个类GUI:

import { GUI } from 'three/addons/libs/lil-gui.module.min.js';

实例化一个gui对象:

const gui = new GUI();

改变交互界面style属性:

gui.domElement.style.right = '0px';
gui.domElement.style.width = '300px';

执行gui的add()方法可以快速创建一个UI交互界面:

//创建一个对象,对象属性的值可以被GUI库创建的交互界面改变
const obj = {
	x: 30,
};
// gui增加交互界面,用来改变obj对应属性
gui.add(obj, 'x', 0, 100);

gui调试界面2-颜色命名等

通过name()方法改变gui生成交互界面显示的内容:

gui.add(ambient, 'intensity', 0, 2.0).name('环境光强度');
gui.add(directionalLight, 'intensity', 0, 2.0).name('平行光强度');

通过step()方法设置步长:

gui.add(ambient, 'intensity', 0, 2.0).name('环境光强度').step(0.1);

当gui界面某个值的时候,onChange()方法就会执行,可以根据需要通过onChange()执行某些代码:

const obj = {
x: 30,
};
// 当obj的x属性变化的时候,就把此时obj.x的值value赋值给mesh的x坐标
gui.add(obj, 'x', 0, 180).onChange(function(value){
mesh.position.x = value;
// 你可以写任何你想跟着obj.x同步变化的代码
// 比如mesh.position.y = value;
});

通过addColor()方法生成颜色值改变的交互界面:

const obj = {
    color:0x00ffff,
};
// .addColor()生成颜色值改变的交互界面
gui.addColor(obj, 'color').onChange(function(value){
    mesh.material.color.set(value);
});

gui调试3-下拉菜单、单选框

参数3和参数4,分别是一个数字,交互界面是一个鼠标可以拖动的拖动条,可以在一个区间改变属性的值:

// 参数3、参数4数据类型:数字(拖动条)
gui.add(obj, 'x', 0, 180).onChange(function (value) {
	mesh.position.x = value;
});

参数3是一个数组,生成交互界面是下拉菜单:

const obj = {
    scale: 0,
};
// 参数3数据类型:数组(下拉菜单)
gui.add(obj, 'scale', [-100, 0, 100]).name('y坐标').onChange(function (value) {
    mesh.position.y = value;
});

参数3是一个对象,生成交互界面是下拉菜单:

const obj = {
    scale: 0,
};
// 参数3数据类型:对象(下拉菜单)
gui.add(obj, 'scale', {
    left: -100,
    center: 0,
    right: 100
}).name('位置选择').onChange(function (value) {
    mesh.position.x = value;
});

参数3是布尔值,生成交互界面是单选框

const obj3 = {
	bool: false,
};
// 改变的obj属性数据类型是布尔值,交互界面是单选框
gui.add(obj3, 'bool').name('是否旋转').onChange(function (value) {
	// 点击单选框,控制台打印obj.bool变化
	console.log('obj.bool',value);
});

gui.js库(分组)

new GUI() 实例化一个gui对象,默认创建一个总的菜单,通过gui对象的addFolder()方法可以创建一个子菜单,当你通过GUI控制的属性比较多的时候,可以使用addFolder()进行分组。addFolder()返回的子文件夹对象,同样具有gui对象的add()、onChange()、addColor()等等属性。

// 创建材质子菜单
const matFolder = gui.addFolder('材质');
matFolder.close();
// 材质颜色color
matFolder.addColor(obj, 'color').onChange(function(value){
    material.color.set(value);
});

gui对象创建的总菜单或gui.addFolder()创建的子菜单都可以用代码控制交互界面关闭或开展状态:

gui.open(); // 展开菜单
gui.close(); // 关闭菜单

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

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

相关文章

【C++】:AVL树的深度解析及其实现

目录 前言一&#xff0c;AVL树的概念二&#xff0c;AVL树节点的定义三&#xff0c;AVL树的插入3.1 第一步3.2 第二步 四&#xff0c;AVL树的旋转4.1 右单旋4.2 左单旋4.3 右左双旋4.4 左右双旋4.5 插入代码的完整实现4.6 旋转总结 五&#xff0c;AVL树的验证六&#xff0c;实现…

详细讲解vue3 watch回调的触发时机

目录 Vue 3 watch 基本用法 副作用刷新时机 flush 选项 flush: pre flush: post flush: sync Vue 3 watch 基本用法 计算属性允许我们声明性地计算衍生值。然而在有些情况下&#xff0c;我们需要在状态变化时执行一些“副作用”&#xff1a;例如更改 DOM&#xff0c;或是…

数字图像处理笔记(一)---- 图像数字化与显示

系列文章目录 数字图像处理学习笔记&#xff08;一&#xff09;---- 图像数字化与显示 数字图像处理笔记&#xff08;二&#xff09;---- 像素加图像统计特征 数字图像处理笔记&#xff08;三) ---- 傅里叶变换的基本原理 文章目录 系列文章目录前言一、数字图像处理二、图像数…

文件I/O基础

一、传统I/O数据传输过程 用户进程调用 read() 函数,发送上下文切换,用户进程由用户态切换成内核态,CPU向磁盘发起数据读取IO请求,然后返回;磁盘控制器收到请求,就开始准备数据,把数据放入磁盘控制器的内存缓冲区中,然后产生一个中断;CPU收到中断信号,停下手头工作,…

linux系统查历史cpu使用数据(使用sar 查询cpu和网络占用最近1个月历史数据)。

一 sar 指令介绍 在 Linux 系统中&#xff0c;sar 是 System Activity Reporter 的缩写&#xff0c;是一个用于收集、报告和保存系统活动信息的工具。它是 sysstat 软件包的一部分&#xff0c;提供了丰富的系统性能数据&#xff0c;包括 CPU、内存、网络、磁盘等使用情况&am…

802.11 Omnipeek 抓包

802.11 Omnipeek 抓包 前言Omnipeek安装软件配置 前言 设备准备环节和前面一样&#xff0c;本文不再赘述&#xff0c;参考前面的文章&#xff1a;https://blog.csdn.net/m0_55334946/article/details/140671901 采用 Omnipeek 抓包分析&#xff0c;我可以说比起 wireshark 已…

计算一段英文句子的最后一个单词的长度,单词间以空格隔开。

# 计算一段英文句子的最后一个单词的长度&#xff0c;单词间以空格隔开。 # 例如&#xff1a;输入”how are you“&#xff0c;输出&#xff1a;3EnglishStr:str str(input("请输入你的英文句子:")) EnglishList:list EnglishStr.split( ) strLength len(EnglishL…

走难而正确的路并持之以恒

走难而正确的路并持之以恒 接近八月&#xff0c;台风频繁。气象台说台风“格美”今夜将至&#xff0c;往粤北走&#xff0c;而留在粤东的将是持续的高温。高温的广州&#xff0c;这几晚的天空惊喜不断&#xff0c;成片的火烧云&#xff0c;站在猎德大桥观望&#xff0c;丹红的凤…

ModelArts中sinh算子的开发

一、环境配置 1、创建notebook并连接 使用ModelArts新建一个notebook,我这里镜像选择第一个,里面含有cann和Ascend910处理器,我这里环境只能使用ssh连接,创建一个密钥对,保存到C盘中的user/Administrator/目录下。 在网页中选择使用vscode接入,等待vscode打开后,选择密…

LangChain的数据增强

吾名爱妃&#xff0c;性好静亦好动。好编程&#xff0c;常沉浸于代码之世界&#xff0c;思维纵横&#xff0c;力求逻辑之严密&#xff0c;算法之精妙。亦爱篮球&#xff0c;驰骋球场&#xff0c;尽享挥洒汗水之乐。且喜跑步&#xff0c;尤钟马拉松&#xff0c;长途奔袭&#xf…

给Windows系统中注入服务,即windwos守护进程

最近总是在windwos环境下测试nginx&#xff0c;总是需要频繁重启nginx服务。于是考虑有没有可能把nginx加入到系统服务的操作。在网上找了一大堆资料&#xff0c;现在来总结一下&#xff01; 方法1&#xff1a;利用nssm工具实现 这是一个守护进程的软件&#xff0c;可以在win…

初阶数据结构——二叉树大汇总

这篇博客将会讲到二叉树的部分内容及堆的相关知识~ 这里将会涉及到大量的递归&#xff08;头大&#xff09; 目录 1.树 1.1树的概念 1.2树的相关概念 1.3树的表示 1.4树的实际应用 2.二叉树 2.1二叉树的概念 2.2特殊的二叉树 2.2.1 满二叉树 2.2.2 完全二叉树 2.2…

【昇腾AI创新大赛集训营南京站学习笔记】-Ascend算子开发课程

昇腾AI创新大赛训练营 14:00-14:30 基础知识-理论课 一、CANN 、达芬奇架构和算子 1.AI Core逻辑架构 达芬奇架构包含三部分&#xff1a; 1&#xff09;计算类&#xff1a;矩阵计算单元&#xff08;两个矩阵扔进去相乘&#xff09;、向量计算单元、标量计算单元 2&#xff09;控…

一天搞定React(4)——Redux

Hello&#xff01;大家好&#xff0c;今天带来的是React前端JS库的学习&#xff0c;课程来自黑马的往期课程&#xff0c;具体连接地址我也没有找到&#xff0c;大家可以广搜巡查一下&#xff0c;但是总体来说&#xff0c;这套课程教学质量非常高&#xff0c;每个知识点都有一个…

鸿蒙OpenHarmony Native API【drawing_path.h】 头文件

drawing_path.h Overview Related Modules: [Drawing] Description: 文件中定义了与自定义路径相关的功能函数 Since: 8 Version: 1.0 Summary Functions FunctionDescription[OH_Drawing_PathCreate] (void)[OH_Drawing_Path] * 函数用于创建一个路径对象OH_Drawin…

前端页面:用户交互持续时间跟踪(duration)user-interaction-tracker

引言 在用户至上的时代&#xff0c;精准把握用户行为已成为产品优化的关键。本文将详细介绍 user-interaction-tracker 库&#xff0c;它提供了一种高效的解决方案&#xff0c;用于跟踪用户交互的持续时间&#xff0c;并提升项目埋点的效率。通过本文&#xff0c;你将了解到如…

EXO-chatgpt_api 解释

目录 chatgpt_api 解释 resolve_tinygrad_tokenizer 函数 resolve_tokenizer 函数 调试和日志记录​​​​​​​ 参数 返回值 初始化方法 __init__ 异步方法 注意事项 chatgpt_api 解释 展示了如何在一个项目中组织和导入各种库、模块和类,以及如何进行一些基本的We…

双向链表(C语言版)

1. 双向链表的结构 注意&#xff1a;这里的“带头”跟单链表的“头结点”是两个概念&#xff0c;实际上在单链表阶段称呼不太严谨&#xff0c;但是为了更好地理解就直接称为单链表的头结点。带头链表里的头结点&#xff0c;实际为“哨兵位”&#xff0c;哨兵位结点不存储任何有…

rsync文件远程同步

目录 一、什么是rsync远程同步 二、实操rsync远程文件同步 1、配置rsync同步源 2、客户端部署 3、增量备份​编辑 4、删除文件 5、如何实现免交互登录 6、crontab rsync 实现定时同步 7、使用ssh实现rsync数据同步【☆】 如何使用ssh免交互实现数据同步&#xff1f;…

C++ Map Set的模拟实现

C Map Set的模拟实现 文章目录 前言一、Map 和 Set是什么&#xff1f;1.Set2.Map 二、困难点困难一、set和map中值的类型不同困难二、Map和Set中值不可修改困难三、红黑树中迭代器的和--1.2.- - 困难四、map中[ ] 运算符重载的实现1.修改红黑树以及Map和Set中insert的返回值1.修…