首页 > 其他分享 >Three.js进阶之旅:基础介绍(二)

Three.js进阶之旅:基础介绍(二)

时间:2022-09-23 13:01:13浏览次数:88  
标签:网格 场景 进阶 Three 默认 js 几何 默认值

本文为稀土金块技术社区的第一篇署名文章。 14日内禁止转载,14日后禁止擅自转载。侵权必究!

概括

专栏 上一篇 《Three.js 进阶之旅:基础介绍(上)》 主要解释 三.js 环境建设与项目建设及基本发展过程。本文将继续通过一个简单的 3D 创意页面的开发,简要总结必要的 三.js 基础知识,梳理要点,为后续页面的开发打下坚实的基础。通过本文的内容,您将获得包括: 轨道控制 使用镜头跟踪控制器, 场景.雾 场景雾, 三.js 灯光、几何、材质、模型、纹理、动画等。

影响

下面我们来看看本节示例的实现效果。整个页面很简单 宇宙背景,可通过鼠标访问 操纵星空,包括行星、轨道、卫星和遥远的恒星 它们都按照既定的动画规则继续旋转。

掘金代码

完成

页面结构

这个页面也没有额外的元素,只是在 身体 添加一个名为的类 .webgl 帆布 容器可用于渲染 3D 场景。

 <画布类=“webgl”></ canvas >  
 复制代码

资源介绍

介绍 样式表 三.js ,除此之外,本页还介绍了 轨道控制 ,即镜头轨道控制器。

 导入'./style.css';  
 从'三'导入*作为三;  
 从“三个/examples/jsm/controls/OrbitControls”导入{ OrbitControls };  
 复制代码

渲染场景初始化

场景渲染初始化与之前的内容基本相同。值得注意的是,在本文中, 场景.背景 为场景设置深黑色背景,通过 场景.雾 给场景设置雾效果, 当场景缩小到一定程度时,页面会叠加雾状效果,场景中的物体会逐渐变得模糊 .

 // 定义渲染大小  
 常量大小 = {  
 宽度:窗口。内宽,  
 高度:窗户。内部高度  
 }  
  
 // 初始化渲染器  
 常量画布 = 文档。 querySelector('canvas.webgl');  
 常量渲染器 = 新的三个。 WebGLRenderer({ canvas: canvas });  
 渲染器。 setSize(大小。宽度,大小。高度);  
 渲染器。 setPixelRatio(Math.min(window.devicePixelRatio, 2));  
  
 // 初始化场景  
 const 场景 = 新的三个。场景();  
 场景。背景=新的三。颜色(0x1A1A1A);  
 场景。雾=新三。雾(0x1A1A1A,1,1000);  
  
 //初始化相机  
 常量相机 = 新的三个。 PerspectiveCamera(40,尺寸。宽度/尺寸。高度)  
 场景。添加(相机);  
 相机。位置。设置(20、100、450);  
  
 // 页面缩放事件监听  
 窗户。 addEventListener('resize', () => {  
 尺寸。宽度 = 窗口。内宽;  
 尺寸。高度 = 窗口。内部高度;  
 // 更新渲染  
 渲染器。 setSize(大小。宽度,大小。高度);  
 渲染器。 setPixelRatio(Math.min(window.devicePixelRatio, 2))  
 //更新相机  
 相机。方面=大小。宽度/尺寸。高度;  
 相机。更新投影矩阵();  
 });  
 复制代码

知识点 Scene.Fog 场景雾

多雾路段 该类定义了线性雾,雾的密度随距离线性增加,即场景中物体的雾效果随距离线性变化。

构造函数

 雾(颜色,近,远)  
 复制代码
  • 颜色 :表示雾的颜色。比如设置为白色,场景中远处的物体是蓝色的,场景中最近的物体是自己的颜色,最远和最近的物体的颜色是物体自己的颜色和雾的混合颜色。
  • 靠近 :表示应用雾效果的最小距离,与活动相机的距离小于 靠近 物体不会受到雾的影响。
  • 远的 :表示应用雾效果的最大距离,与活动相机的距离大于 远的 物体不会受到雾的影响。

初始化控制器

初始化镜头轨迹控制器 轨道控制 , 通过它您可以使用鼠标 在进行缩放、平移、旋转等操作时,本质上改变的不是场景,而是相机的位置参数。可以通过设置选择 控制.启用阻尼 为了 真的 打开控制器 移动惯性 ,使与鼠标的交互感觉更加流畅和逼真。

 const controls = new OrbitControls(camera, renderer.domElement);  
 控制。启用阻尼=真;  
 复制代码

添加光源

就像现实世界一样,没有光 如果你什么都看不到。在添加光源之前,场景中的所有网格元素都是黑色的,无法显示其颜色和材质表面的物理属性。这时候就需要在场景中添加一个光源,才能看到场景中的物体。

此示例中仅添加了一个光源 环境光 环境光,它是整个场景中的对象将接收其颜色的基本光源。其中两个参数分别代表光的颜色和强度。

 常量灯 = 新的三个。环境光(0xdeedff,1.5);  
 场景。添加(光);  
 复制代码

知识点 光源

三.js 中提供了多种光源,可以模拟现实世界中大部分场景的灯光效果。使用光源的方法也与本文示例中的大致相同。下表列出了几种常用的光源,您可以根据自己的需要和场景选择不同的光源。你可以把这个例子中的环境光放在实践中 环境光 切换到其他效果灯,看看它们会产生什么不同。

光源名称描述 环境光 环境光,一种基础光源,其颜色添加到整个场景和所有对象的当前颜色 点光源 点光源,空间中向各个方向发光的点 聚光灯 具有聚光灯效果的聚光灯源,类似于台灯、天花板上的吊灯或手电筒 方向灯 定向光,也称为无限光。可以看到来自这种光源的光线是平行的。例如,阳光 HemishpereLight 半球灯,一种特殊的光源,可用于创造更自然的户外照明,模拟闪亮的表面和昏暗的天空 区域光 区域光,它允许您指定一个发射光的平面,而不是空间中的一个点 镜头光晕 镜头光晕,不是光源,但可以通过 镜头光晕 为场景中的光源添加镜头光晕效果

光源的一些常见特性:

  • 颜色 :光源颜色。
  • 强度 : 光强度。默认值为 1 .
  • 可见的 : 如果设置为 真的 ,光源显示;如果设置为 错误的 ,光源会消失。

创建一个星球

示例页面中的所有模型元素都是 三.js 内置基础网格模型生成,所以和 上一篇文章创建立方体的过程 也是一样,先创建立方体和材质,然后用​​它们生成网格模型,最后添加到场景中。行星模型使用无光泽的表面材料 网状Lambert材料 ,立方体采用 球体几何 产生。

 const SphereMaterial = 新的三。 MeshLambert材料({  
 颜色:0x03c03c,  
 线框:真实,  
 });  
 const SphereGeometry = 新三。球体几何(80、32、32);  
 常量星球 = 新的三。网格(SphereGeometry,SphereMaterial);  
 场景。添加(行星);  
 复制代码

为材料设置 线框:真 属性可以得到几何模型的线框结构,是不是看起来更有技术含量。

知识点 几何学

总结如下 三.js 常用几何的分类及构造函数的参数在后续使用过程中可通过该表查询。由于本文篇幅和内容有限,具体的造型就不一一展示了。在学习过程中,您必须亲身体验各种几何体创建后的样子。你也可以多看看。 threejs.org 官网文档。

名称构造函数参数 平面几何 【平面几何】 宽度 — 平面沿 X 轴的宽度。默认值为 1 . 高度 - 沿着飞机 Y轴 的高度。默认值为 1 . 宽度段 — 可选,平面的宽度段数,默认值为 1 . 高度段 — 可选,平面的高度段数,默认为 1 . 圆几何 【圆形几何】 半径 — 圆的半径,默认为 1 . 细分市场 — 段数,最少为 3 , 默认值为 8 . theta开始 — 第一段的起始角度,默认为 0 . θ长度 — 圆弧的圆心角,通常称为 一世 .默认值为 2*Pi ,这使它成为一个完整的圆。 环形几何 【环几何】 内半径 — 内半径,默认为 0.5 . 外半径 — 外半径,默认为 1 . θSegments — 环的段数。值越高,环越圆。最小值是 3 , 默认值为 8 . phiSegments — 最小值是 1 , 默认值为 8 . theta开始 — 起始角度,默认为 0 . θ长度 — 圆心角,默认值为 数学.PI * 2 . 形状几何 【形状几何】 形状 ——一个孤独 形状 , 或包含形状 大批 . 曲线段 - 整数 - 每个形状的段数,默认为 12 . 箱形几何 【立方体几何】 宽度 — X 轴上方的宽度,默认值为 1 . 高度 轴上方的高度,默认为 1 . 深度 Z 轴上方的深度,默认为 1 . 宽度段 — 可选,宽度的段数,默认为 1 . 高度段 — 可选,宽度的段数,默认为 1 . 深度段 — 可选,宽度的段数,默认为 1 . 球体几何 【球体几何】 半径 — 球体半径,默认为 1 . 宽度段 — 水平段数,最小值为 3 , 默认值为 8 . 高度段 — 垂直段数,最小值为 2 , 默认值为 6 . phiStart — 指定水平起始角度,默认值为 0 . phi长度 — 指定水平扫描角度的大小,默认值为 数学.PI * 2 . theta开始 — 指定垂直起始角度,默认为 0 . θ长度 — 指定垂直扫描角度大小,默认值为 数学.PI . 圆柱几何 【圆柱几何】 半径顶部 — 圆柱体的顶部半径,默认值为 1 . 半径底部 — 圆柱体的底半径,默认值为 1 . 高度 — 圆柱体的高度,默认值为 1 . 径向段 — 围绕圆柱体侧面的段数,默认为 8 . 高度段 — 沿圆柱高度的边的段数,默认为 1 . 开放式 - 一 布尔值 一个值,指示此圆锥的底部是开放的还是封闭的。默认为 错误的 ,即默认情况下它的底面是封闭的。 theta开始 — 第一段的起始角度,默认为 0 . θ长度 ——圆柱体底面圆弧的圆心角,通常称为 “θ” .默认值为 2*Pi ,这使它成为一个完整的圆柱体。 圆锥几何 【圆锥几何】 半径 — 锥底半径,默认为 1 . height — 圆锥的高度,默认值为 1。 径向段 - 围绕圆锥体侧面的段数,默认为 8 . 高度段 — 沿锥体高度的段数,默认为 1 . 开放式 — 一个布尔值,指示圆锥体的底部是开放的还是封闭的。默认为 错误的 ,即默认情况下它的底面是封闭的。 ·thetaStart· — 第一段的起始角度,默认为 0 . θ长度 — 圆锥底面的圆心角,通常称为 “θ” .默认值为 2*Pi ,这使它成为一个完整的圆锥体。 圆环几何 【环几何】 半径 - 圆环的半径,从圆环中心到管道中心。默认值为 1 . 管子 — 管道半径,默认为 0.4 . 径向段 — 环的段数,默认为 8 . 管状段 — 管道中的段数,默认为 6 . — 圆环的中心角,默认值为 数学.PI * 2 . 文本几何 【文字几何】 字体 三.字体 实例。 尺寸 漂浮 .字体大小,默认为 100 . 高度 漂浮 .突出文本的粗细。默认为 50 . 曲线段 整数 .曲线上的点数。默认为 12 . 斜面启用 布尔值 .是否开启斜角,默认为 错误的 . 斜面厚度 漂浮 .文字上斜面的深度,默认值为 20 . 斜角尺寸 漂浮 .斜角与原始文本轮廓之间的延伸距离。默认为 8 . 斜面段 整数 .斜角的段数。默认为 3 . 四面体几何 【四面几何】 半径 — 四面体的半径,默认为 1 . 细节 — 默认为 0 .将此值设置为大于 0 将为其添加一些顶点,使其不再是四面体。 八面体几何 【八面体几何】 半径 — 八面体的半径,默认为 1 . 细节 — 默认为 0 , 将此值设置为大于 0 将为其添加一些顶点,使其不再是八面体。 十二面体几何 【十二面体几何】 半径 — 十二面体的半径,默认为 1 . 细节 — 默认为 0 .将此值设置为大于 0 将为其添加一些顶点,使其不再是十二面体。 二十面体几何 【二十面体几何】 半径 — 二十面体的半径,默认为 1 . 细节 — 默认为 0 .将此值设置为大于 0 将为其添加一些顶点,使其不再是二十面体。当这个值大于 1 ,它实际上会变成一个球体。 圆环结几何 【环扭结几何】 半径 - 圆环的半径,默认为 1 . 管子 — 管道半径,默认为 0.4 . 管状段 — 管道中的段数,默认为 64 . 径向段 — 横截面段数,默认为 8 . p — 该值决定几何图形将围绕其旋转对称轴旋转多少次,默认值为 2 . q — 该值决定几何图形围绕其内部圆环旋转多少次,默认值为 3 . 多面体几何 【多面体几何】 顶点 - 一个顶点 大批 [1,1,1, -1,-1,-1, ... ] . 指数 — 组成面的索引 大批 , [0,1,2, 2,3,0, ... ] . 半径 漂浮 - 最终形状的半径。 细节 整数 - 细分此几何图形的级别。细节越多,形状越平滑。 管几何 【管道几何】 小路 曲线 - 一个基类 曲线 继承路径。 管状段 整数 - 组成此管道的段数,默认为 64 . 半径 漂浮 - 管道的半径,默认为 1 . 径向段 整数 - 管道横截面的段数,默认为 8 . 关闭 布尔值 管道两端是否闭合,默认值为 错误的 .

知识点 材质Material

材料可以模拟现实世界中物体表面的物理特性, 三.js 它还提供了丰富的材料。我们在创建不同的对象时可以选择不同的材料,比如在创建木制桌面的时候。 MeshPhysicalMaterial 物理网格材质 ,在创建卡通风格模型时可以选择 MeshToonMaterial 卡通网格材质 .下表列出了几种常用的材料类型及其说明。

名称描述 MeshBasicMaterial 基础网格基础材料,用于为几何体提供简单的颜色,或显示几何体的线框。 MeshDepthMaterial 网格深度材质,该材质使用相机到网格的距离来决定如何为网格着色。 网格标准材料 标准网格材质,一种基于物理的标准材质,使用 金属粗糙度 工作过程 MeshPhysicalMaterial 物理网格材料, 网格标准材料 扩展以更好地控制反射率。 MeshNormalMaterial 网格法线材质,这是一种简单的材质,根据法线向量计算物体表面的颜色。 网状Lambert材料 网格 兰伯特 一种材质,一种考虑到光照效果的材质,用于创建暗淡无光的物体。 MeshPhong材料 网格 类型材质,这是一种将光照考虑在内的材质,用于创建有光泽的物体。 MeshToonMaterial 网格 类型材料, MeshPhong材料 卡通着色的扩展。 着色器材质 着色器材质,允许使用自定义着色器程序,直接控制顶点的放置方式和像素的着色方式。 线基本材料 线基材,此材料可用于 三线 线几何,用于创建阴影线。

创建一个行星轨道环

使用与上述相同的方法,选择 圆环几何 通过调整行星轨道将其添加到场景中 回转 属性来设置倾斜角度。

 const TorusGeometry = 新三。圆环几何(150、8、2、120);  
 const TorusMaterial = 新的三个。 MeshLambert材料({  
 颜色:0x40a9ff,  
 线框:真  
 });  
 常量环 = 新三。网格(TorusGeometry,TorusMaterial);  
 戒指。回转。 x = 数学。 PI / 2;  
 戒指。回转。 y = - 0.1 * (数学. PI / 2);  
 场景。添加(环);  
 复制代码

创建卫星

应用 二十面体几何 创建卫星。

 const IcoGeometry = 新的三。二十面体几何(16, 0);  
 const IcoMaterial = 新的三个。 MeshToonMaterial({ 颜色: 0xfffc00 });  
 常量卫星 = 新的三。网格(IcoGeometry,IcoMaterial);  
 场景。添加(卫星);  
 复制代码

创建星星

我们计划创建 500 星星 ,由于数量众多,单独将它们单独放置在场景中,不仅会导致页面性能问题,还会使星星的整体管理变得困难。为了解决这个问题,我们可以先创建一个 团体 ,然后添加一颗星到 团体 组,最后将整个组添加到场景中。存在 for 循环 在 中创建单星时,还使用 二十面体几何 二十面体几何,使用的材料 MeshToonMaterial 香椿网状材料并设置它们 在限度内 随机位置和角度。

 常量星 = 新的三个。团体();  
 for ( 让 i = 0; i < 500; i++) {  
 常量几何 = 新的三个。二十面体几何(数学。随机()* 2, 0);  
 常量材料 = 新的三。 MeshToonMaterial({ 颜色: 0xeeeeee });  
 常量网格 = 新的三个。网格(几何,材料);  
 网。位置。 x = ( Math.random() - 0.5) * 700;  
 网。位置。 y = ( Math.random() - 0.5) * 700;  
 网。位置。 z = ( Math.random() - 0.5) * 700;  
 网。回转。 x = 数学。随机() * 2 * 数学。 PI;  
 网。回转。 y = 数学。随机() * 2 * 数学。 PI;  
 网。回转。 z = 数学。随机() * 2 * 数学。 PI;  
 星星。添加(网格);  
 }  
 场景。添加(星​​星);  
 复制代码

动画更新

最后,除了在页面重绘动画中更新相机和渲染器外,我们还为场景中的其他对象添加了一些动画效果。 行星和轨道以两个相反的方向旋转,卫星 围绕着他们转。整颗星 团体 也在同时进行 Y轴 Z轴 的旋转。

 让腐烂= 0;  
 // 动画  
 常量轴 = 新三。向量3(0,0,1);  
 常量刻度 = () => {  
 // 更新渲染器  
 渲染器。渲染(场景,相机);  
 // 为网格模型添加旋转动画  
 腐烂+=数学。随机()* 0.8;  
 const 弧度 = (rot * Math. PI) / 180;  
 // 行星位置动画  
 行星 && (行星。自转。y += .005);  
 // 行星轨道环位置动画  
 环&&环。 rotateOnAxis(轴,数学。PI / 400);  
 // 卫星位置动画  
 卫星。位置。 x = 250 * 数学。罪(弧度);  
 卫星。位置。 y = 100 * 数学。 cos(弧度);  
 卫星。位置。 z = - 100 * 数学。 cos(弧度);  
 卫星。回转。 x += 0.005;  
 卫星。回转。 y += 0.005;  
 卫星。回转。 z -= 0.005;  
 // 星星动画  
 星星。回转。 y += 0.0009;  
 星星。回转。 z -= 0.0003;  
 // 更新控制器  
 控制。更新();  
 // 当页面重绘时调用自身  
 窗户。 requestAnimationFrame(tick);  
 }  
 打钩();  
 复制代码

至此,该页面的所有功能都已经完成。 三.js 而如果你对本文内容实现的页面效果感兴趣的话,一定要亲自试一试。

其他必备知识

下面列出了一些在本文的示例中没有涉及但非常重要的内容 三.js 后续开发中几乎都会用到的基础知识,也需要牢牢掌握。

模型

在实际开发中,除了用代码创建模型外,大部分场景都需要加载设计人员提供的模型,并使用设计软件导出。此时,您需要使用模型加载器来加载模型。不同格式的模型需要导入对应的模型加载器。 loader虽然不同,但用法基本相同。以下是使用 OBJLoader 加载 .obj 格式化模型的过程。

 var loader = 新的三个。 OBJLoader();  
 装载机。加载(模型,函数(对象){  
 目的。遍历(函数(子){  
 如果(孩子。isMesh){  
 // 对模型子网格的一些操作  
 }  
 });  
 场景。添加(对象);  
 });  
 复制代码

Three.js 支持的模型格式:3ds (.3ds)、amf (.amf)、3mf (.3mf)、assimp & assimp2json (.assimp |.json)、awd (.awd)、Babylon (.babylon)、BVH (.bvh)、Collada(.dae|.xml)、OpenCTM (.ctm)、draco(.drc)、FBX(.fbx)、GCode (.gcode)、glTF (.gltf)、Clara(.json)、 KMZ(.kmz)、LDraw(.mpd)、LightWave(.lwo)、MD2 (.md2)、MMD(.pmd | .vmd)、nrrd (.nrrd)、obj/obj2 (.obj)、pcd (. pcd)、PDB(.pdb)、PlayCanvas(.json)、ply(.ply)、prwm(.prwm)、sea3d(.sea3d)、stl(.stl)、vrm(.vrm)、vrml(.vrml) , vtk, x 等。

质地

为了模拟更真实的效果,需要给模型材质添加纹理。纹理就像模型的皮肤,使其更具立体感。添加贴图的原理是通过纹理贴图加载器 纹理加载器() 去新建一个纹理对象,然后调用里面 加载() 加载图片的方法,会返回一个纹理对象,可以作为模型材质颜色图 地图 属性的值,材质的colormap属性 地图 设置后,模型从纹理图中捕获像素值。下面列出了几种常用的纹理类型以及加载纹理的基本过程。

  • 地图 : 材质贴图
  • 法线贴图 :法线贴图
  • 凹凸贴图 :凹凸贴图
  • 环境地图 : 环境图
  • 高光贴图 : 高光贴图
  • 光照贴图 : 光照贴图

代码示例:

 const texLoader = 新的三个。纹理加载器();  
 装载机。负载('资产/模型/meta.fbx',功能(网格){  
 网。遍历(函数(子){  
 如果(孩子。isMesh){  
 if (child.name === '需要添加纹理的模型') {  
 孩子。材料=新的三。 MeshPhysicalMaterial({  
 地图:texLoader。加载(“./assets/images/metal.png”),  
 });  
 }  
 }  
 });  
 })  
 复制代码

动画

将动画添加到 3D 场景可以使页面更加生动,例如在此示例中为模型添加简单的基本动画和相机控制动画。 三.js 本文中的动画基本可以分为以下几类,在本专栏后续内容中会详细讲解。 三.js 中的动画。

  • 基本动画
  • 相机控制
  • 变形动画
  • 用骨骼和蒙皮制作动画
  • 使用外部模型创建动画

其他

最后,还有着色器和后期渲染、媒体交互和对象特征等高级功能。专栏后续文章会具体讲解这些比较复杂的内容。

源码仓库地址: github.com/dragonir/th…

总结

本文包含的主要知识点包括:

  • 轨道控制 :使用镜头跟踪控制器
  • 场景.雾 现场雾
  • 三.js 光源在
  • 三.js 几何在
  • 三.js 材料在
  • 三.js 模型在
  • 三.js 中的纹理
  • 三.js 动画中

想了解其他前端知识或者其他本文没有详细介绍的东西 网页 3D 开发技术相关知识,可以阅读我之前的文章。如果您有任何问题,您可以在评论中留下 信息 ,如果你觉得文章对你有帮助,别忘了 一键三连 .

附录

参考

版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议。转载请附上原文出处链接和本声明。

这篇文章的链接: https://homecpp.art/5023/10337/1020

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/38878/53032312

标签:网格,场景,进阶,Three,默认,js,几何,默认值
From: https://www.cnblogs.com/amboke/p/16722344.html

相关文章