Three.js 官方文档学习笔记

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, //高光部分的亮度,默认30specular: 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.mzph.cn/diannao/49311.shtml

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

相关文章

实验八: 彩色图像处理

目录 一、实验目的 二、实验原理 1. 常见彩色图像格式 2. 伪彩色图像 3. 彩色图像滤波 三、实验内容 四、源程序和结果 (1) 主程序(matlab (2) 函数FalseRgbTransf (3) 函数hsi2rgb (4) 函数rgb2hsi (5) 函数GrayscaleFilter (6) 函数RgbFilter 五、结果分析 1. …

某数据泄露防护(DLP)系统NetSecConfigAjax接口SQL注入漏洞复现 [附POC]

文章目录 某数据泄露防护(DLP)系统NetSecConfigAjax接口SQL注入漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现某数据泄露防护(DLP)系统NetSecConfigAjax接口SQL注入漏洞复现 [附POC] 0x01 前言 免责声明:请…

【Emacs有什么优点,用Emacs写程序真的比IDE更方便吗?】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

springcloud接入skywalking作为应用监控

下载安装包 需要下载SkyWalking APM 和 Java Agent 链接: skywalking 安装 下载JDK17&#xff08;可不配置环境变量&#xff09; 目前skywalking 9.0及以上版本基本都不支持JDK8&#xff0c;需要JDK11-21&#xff0c;具体版本要求在官网查看。 我这里使用的是skywalking9.…

Unity UGUI 之 图集

本文仅作学习笔记与交流&#xff0c;不作任何商业用途 本文包括但不限于unity官方手册&#xff0c;唐老狮&#xff0c;麦扣教程知识&#xff0c;引用会标记&#xff0c;如有不足还请斧正 本文在发布时间选用unity 2022.3.8稳定版本&#xff0c;请注意分别 1.什么是图集 精灵图…

google 浏览器插件开发简单学习案例:TodoList;打包成crx离线包

参考&#xff1a; google插件支持&#xff1a; https://blog.csdn.net/weixin_42357472/article/details/140412993 这里是把前面做的TodoList做成google插件&#xff0c;具体网页可以参考下面链接 TodoList网页&#xff1a; https://blog.csdn.net/weixin_42357472/article/de…

phpstorm配置xdebug3

查看php路径相关信息 php --ini安装xdebug https://www.jetbrains.com/help/phpstorm/2024.1/configuring-xdebug.html?php.debugging.xdebug.configure php.ini 配置 在最后添加&#xff0c;以下是我的配置 [xdebug] zend_extension/opt/homebrew/Cellar/php8.1/8.1.29/p…

React 学习——行内样式、外部样式、动态样式

三种样式的写法 import "./index.css"; //同级目录下的样式文件 function App() {const styleCol {color: green,fontSize: 40px}// 动态样式const isBlock false;return (<div className"App">{/* 行内样式 */}<span style{{color:red,fontSiz…

工程视角:数据结构驱动的应用开发--字典(dictionary),列表(list)与实体

这里写目录标题 业务业务场景流程分析 实现数据访问层&#xff08;DAL&#xff09;业务逻辑层&#xff08;BLL&#xff09;用户界面层&#xff08;UI&#xff09;工具类 设计思路为什么抽出工具类关于U层使用字典的好处工程视角 业务 业务场景 在一个金融应用系统中&#xff0c…

.netcore TSC打印机打印

此文章给出两种打印案例&#xff0c; 第一种是单列打印&#xff0c;第二种是双列打印 需要注意打印机名称的设置&#xff0c;程序中使用的打印机名称为999&#xff0c;电脑中安装打印机时名称也要为999。 以下是我在使用过程中总结的一些问题&#xff1a; 一 TSC打印机使用使…

【Node.js基础02】fs、path模块

目录 一&#xff1a;fs模块-读写文件 1 加载fs模块对象 2 读制定文件内容文件 3 向文件中写入内容 二&#xff1a;path模块-路径处理 1 问题引入 2 __dirname内置变量 使用方法 一&#xff1a;fs模块-读写文件 fs模块封装了与本机文件系统交互方法和属性 1 加载fs模块…

弹性布局 flex layout HTML CSS

文章目录 效果图参考文档代码 效果图 其实弹性布局的好处是&#xff1a;当网页大小变化&#xff08;如窗口resize&#xff09;时&#xff0c;处于弹性容器(flex container)中的弹性元素(flex item) 之间的距离也会变化。 需要特别注意的是&#xff1a; 弹性布局的主要CSS如下。…

开源邮箱套件介绍系列2:Roundcube webmail

1. 项目介绍 项目网站&#xff1a;Roundcube – Free and Open Source Webmail Software Roundcube 项目是一个免费的开源网络邮件解决方案&#xff0c;具有类似桌面的用户界面&#xff08;Webmail&#xff09;&#xff0c;易于安装/配置&#xff0c;并且可以在标准的LAMPP服…

PostgreSQL 中如何处理数据的唯一性约束?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 PostgreSQL 中如何处理数据的唯一性约束&#xff1f;一、什么是唯一性约束二、为什么要设置唯一性约束…

SAP第二季度财报和进一步裁员计划

7月22日公布了截至 2024 年 6 月 30 日的第二季度财务报告。以下位总体指标 当前云计算在手订单达 148 亿欧元&#xff0c;按名义货币和固定汇率计算均增长 28%云收入增长 25%&#xff0c;其中云 ERP 套件收入增长 33%&#xff0c;均按名义货币和固定汇率计算总收入增长 10%&a…

mysql 先子查询过滤再联合 和 先联合再过滤 执行效率问题

执行顺序 先子查询过滤再联合 SELECT XXX FROM(select * from edw_data_dyd.overrun_offsite_info WHERELENGTH( VEHICLE_ID ) > 12 AND CREATED_TIME > DATE_ADD(NOW(),INTERVAL -1 HOUR)AND CREATED_TIME < NOW()AND VEHICLE_ID not like %无车牌%AND VEHICLE_I…

Mac中maven配置安装路径

Mac中maven配置安装路径 没有下载maven的可以先下载&#xff1a;&#xff08;这里建议maven版本不要下高了&#xff09; 如果你的bash_profile中没有配置JAVA_HOME路径&#xff0c;可以按照下面的命令配置一下 获取JAVA的安装路径&#xff1a; /usr/libexec/java_home -V …

Pycharm2024最新版community社区版下载安装配置,快速上手

第一步&#xff1a;下载 方法1&#xff1a;官网链接 https://www.jetbrains.com/pycharm/download/?sectionwindows .方法2&#xff1a;百度网盘 链接&#xff1a;https://pan.baidu.com/s/1ic2N5hUQ2m1Kmyr5nK9Jxw?pwd76dt 提取码&#xff1a;76dt --来自百度网盘超级…

接口自动化测试框架实战-2-项目接口文档

上一小节我们完成了项目开发环境的搭建&#xff0c;本小结我们具体介绍一下项目中使用到的接口文档。 本次我们以钉钉开放接口作为项目接口测试的示例&#xff0c;方便大家都能统一学习和调用&#xff0c;具体接口如下&#xff1a; 1、获取企业内部应用的access_token 在获取…

poi库简单使用(java如何实现动态替换模板Word内容)

目录 Blue留言&#xff1a; Blue的推荐&#xff1a; 什么是poi库&#xff1f; 实现动态替换 第一步&#xff1a;依赖 第二步&#xff1a;实现word模板中替换文字 模板word&#xff1a; 通过以下代码&#xff1a;&#xff08;自己建一个类&#xff0c;随意取名&#xf…