Babylon.js 程序化建模简明教程

Babylon.js 中的每个形状都是由三角形或小面的网格构建而成,如题图所示。

NSDT工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜索引擎 - Three.js虚拟轴心开发包 - 3D模型在线减面 - STL模型在线切割

每个面都由三个顶点组成,每个顶点都分配有数据,这些数据不仅会影响面的位置,还会影响其颜色、纹理及其照明方式。 应用着色器将这些数据转换为可视网格的复杂过程全部由Babylon.js 执行。

1、位置和索引

创建具有两个面的网格,一个面的顶点位于 (-5, 2, -3)、(-7, -2, -3)、(-3, -2, -3),另一个面的顶点位于 (5) , 2, 3), (7, -2, 3), (3, -2, 3),要求每个顶点都有唯一的索引。 索引应从 0 开始并连续增加。

indexposition
0(-5, 2, -3)
1(-7, -2, -3)
2(-3, -2, -3)
3(5, 2, 3)
4(7, -2, 3)
5(3, -2, 3)

请注意,分配索引时顺序并不重要。

位置数据存储在数字数组中。 索引为 0 的顶点的 x 坐标放置在 array[0] 中,y 坐标放置在 array[1] 中,z 坐标放置在 array[2] 中。 一般来说,索引为 i 的顶点的 x 坐标位于 array[3i],y 位于 array[3i + 1],z 位于 array[3i +2]。

形成面的索引以三元组的形式放置在一起,如上例中的 (0, 1, 2) 和 (3, 4, 5)。 索引数据也存储在数字数组中,每个三元组保存在一起。

在上面的示例中,位置数组为 [-5, 2, -3, -7, -2, -3, -3, -2, -3, 5, 2, 3, 7, -2, 3, 3, -2, 3],索引数组为 [0, 1, 2, 3, 4, 5]。

JavaScript代码如下:

var customMesh = new BABYLON.Mesh("custom", scene);

var positions = [-5, 2, -3, -7, -2, -3, -3, -2, -3, 5, 2, 3, 7, -2, 3, 3, -2, 3];
var indices = [0, 1, 2, 3, 4, 5];

var vertexData = new BABYLON.VertexData();

vertexData.positions = positions;
vertexData.indices = indices;

vertexData.applyToMesh(customMesh);

Playground演示

2、法线

通常,平面的法线是与平面成直角的向量,对于本例来说,这是正确的。 BabylonJS 将计算一个面的法线,对于不与另一个面共享任何顶点的独立面,法线将是数学法线。 有关法线如何影响光照的更多信息,请参阅法线。

  • 法线计算

使用 ComputeNormal 方法在 vertexData 对象上计算法线,该方法将位置、索引和法线的数组作为参数。

代码补充:

var customMesh = new BABYLON.Mesh("custom", scene);

var positions = [-5, 2, -3, -7, -2, -3, -3, -2, -3, 5, 2, 3, 7, -2, 3, 3, -2, 3];
var indices = [0, 1, 2, 3, 4, 5];

//Empty array to contain calculated values or normals added
var normals = [];

//Calculations of normals added
BABYLON.VertexData.ComputeNormals(positions, indices, normals);

var vertexData = new BABYLON.VertexData();

vertexData.positions = positions;
vertexData.indices = indices;
vertexData.normals = normals; //Assignment of normal to vertexData added

vertexData.applyToMesh(customMesh);

注意:要使自定义网格体可更新,需要在将网格体应用于顶点数据时添加值为 true 的第二个参数。

vertexData.applyToMesh(customMesh, true);

假设数组法线 = [ 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1]。

法线存储在数字数组中,索引 i 引用向量(法线[3i]、法线[3i + 1]、法线[3i + 2]),因此:

indexnormal
0(0, 0, -1)
1(0, 0, -1)
2(0, 0, -1)
3(0, 0, 1)
4(0, 0, 1)
5(0, 0, 1)
  • 法线方向

显然,每个面的法线都指向相反的方向。 它们都指向远离原点的方向。

从原点看向面 3、4、5,则面周围的索引数组 3、4、5 中的顺序是顺时针方向。

从原点向面 0, 1, 2 观察,则面周围的索引数组 0, 1, 2 中的顺序也是顺时针的。

Playground演示

反转操场中一组或两组面索引的顺序将显示法线如何改变方向。

  • 对灯光的影响

距相机最近的面现在为白色,距相机最远的面为黑色。 这是因为法线的添加会影响面上光线的使用。

场景中的光线沿 z 轴正方向传播。

var light = new BABYLON.DirectionalLight("direct", new BABYLON.Vector3(0, 0, 1), scene);

以与法线方向相反的方向传播的白光被反射回来,并且小面被视为白色,而以与法线相同的方向传播的白光被吸收,并且小面被视为黑色。

  • 能见度

然后去除线框效果:

相机朝 z 轴正方向看

黑色面看不到。

相机朝负 z 方向看

白色面看不到。

为什么是这样? 每个面有两个面; 法线所指向的面是正面,另一个面是背面。 默认情况下Babylon.js 不会渲染背面。

因此,许多绘制实体的网格体的面不会有可见的背面。

要绘制网格体的背面,请将应用于网格体的材质的 backFaceCulling 设置为 false。

mat.backFaceCulling = false;

注释下面的第 41 行可以看到背面剔除的情况。

Playground演示

3、颜色

为自定义网格指定颜色的最简单方法是将标准材质应用于网格,然后让 Babylon.js 完成所有工作。 但是,可以为顶点数据中的面设置颜色。 有关构建网格时使用的面的排列如何影响颜色显示方式的信息,请参阅将材质应用于面。

每个顶点的颜色以四个一组的形式放置在一个数组中,顺序为红色、绿色、蓝色和透明度透明度。 对于将面 0、1、2 着色为红色,将面 3、4、5 着色为绿色,每个面上的每个顶点都被赋予相同的颜色。

indexcolor
0(1, 0, 0, 1)
1(1, 0, 0, 1)
2(1, 0, 0, 1)
3(0, 1, 0, 1)
4(0, 1, 0, 1)
5(0, 1, 0, 1)

数组为 [1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0 ,1]。

添加到代码中:

var customMesh = new BABYLON.Mesh("custom", scene);

var positions = [-5, 2, -3, -7, -2, -3, -3, -2, -3, 5, 2, 3, 7, -2, 3, 3, -2, 3];
var indices = [0, 1, 2, 3, 4, 5];
var colors = [1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1]; //color array added

var normals = [];

var vertexData = new BABYLON.VertexData();
BABYLON.VertexData.ComputeNormals(positions, indices, normals);

vertexData.positions = positions;
vertexData.indices = indices;
vertexData.colors = colors; //Assignment of colors to vertexData
vertexData.normals = normals; //Assignment of normal to vertexData added

vertexData.applyToMesh(customMesh);

在Playground中,尝试将红色面上的顶点设置为不同颜色,看看会发生什么。

Playground注意事项

- 由于不再使用材质,因此无法设置 backFaceCulling,因此必须旋转相机才能看到远处的面。 无论应用什么颜色,远端面都将保持黑色,因为所有光仍然被该面吸收。
- 当场景开始时,相机几乎完全面对小面并指向光线传播的方向。 当相机处于此位置时,大部分白光作为高光反射回相机,并且刻面看起来几乎是白色的。
- 当相机围绕小平面旋转时,随着高光效果的消失,小平面将从白色变为红色。
- 为了获得更受控制的光照效果,请使用材质以及设置顶点颜色,或者代替设置顶点颜色。
- 添加一盏方向与当前灯方向相反的灯将照亮两侧。

4、纹理

最简单的方法是仅使用材质并让 Babylon.js 将给定图像应用为纹理。 但是,如果希望更多地控制如何将纹理应用于构面,那么你需要创建并设置 uv 数组。

将任何要用作纹理的图像视为在图像的底部和左侧设置一对轴; 分别为 u 轴和 v 轴。 (u、v 作为 x 和 y 用于位置轴)。 原点是图像的左下角,顶部位于 v = 1 处,右侧边缘位于 u = 1 处,如下图所示。

为了简单起见,下面仅使用构面 0、1、2。

面的每个顶点都分配有图像中的一个 uv 坐标对。

indexcolor
0(0, 1)
1(0, 0)
2(1, 0)

形成uv数组[0,1,0,0,1,0];。

使用以下代码:

var customMesh = new BABYLON.Mesh("custom", scene);

var positions = [-5, 2, -3, -7, -2, -3, -3, -2, -3];
var indices = [0, 1, 2];
var uvs = [0, 1, 0, 0, 1, 0];

var normals = [];
BABYLON.VertexData.ComputeNormals(positions, indices, normals);

var vertexData = new BABYLON.VertexData();

vertexData.positions = positions;
vertexData.indices = indices;
vertexData.normals = normals;
vertexData.uvs = uvs;

vertexData.applyToMesh(customMesh);

结果如下:

请注意,图像是倾斜的,因为三角形面的形状与图像上的形状不匹配。

在适当的点添加这些行:

var colors = [1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1];

var vertexData.colors = colors;

结果如下:

在Playground中,单击“下一步”将使你循环浏览 uv 坐标的各种值。

关于Playground的注意事项:上述Playground的摄像头已被禁用。 在纹理图像上显示 uv 值和相对索引。 后续这个Playground可能会有所改善。 你将了解如何在面上实现纹理的反射和旋转。 然而,对于网格来说,当尝试在网格上实现特定的纹理映射时,必须考虑面的排列。
  • 计算 UV

计算自定义网格的 uv 显然取决于网格的形状以及你想要将纹理的哪些部分投影到网格的哪个位置。 这是一个相对简单的网格的示例,它基本上是一个带有几个突起的平坦表面。

这个 Playground 将左下角视为与纹理图像的左下角匹配,并从每个顶点的 x、z 位置计算 uv 值,作为 (x, z) 距左下角的分数距离。

一般来说,如果左下角位于 (a, b) 且网格的边界宽度和高度分别为 w 和 h,则对于每个 (x, z):

u = (x - a) / w and v = (z - b) / h

原文链接:Babylon.js程序化建模 - BimAnt

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

(二十九)加油站:面向对象重难点深入讲解【重点是元类】

目录: 每篇前言:0. Python中的元类:1. 本文引子:2. Python中的mro机制:3. Python中类的魔法属性dict:注意事项: 拓展——内建函数dir() 4. 正式谈一谈元类(metaclass):&a…

IIR滤波器的设计与实现(内含设计IIR滤波器的高效方法)

写在前面:初学者学习这部分内容,要直接上手写代码可能会感到比较困难,我这里推荐一种高效快速的设计IIR,FIR滤波器的方法——MATLAB工具箱:filterDesigner。打开的方法很简单,就是在命令行键入:filterDesig…

virtio-wayland

CrosVM是Chrome操作系统中,用于创建虚拟机的应用。是一个Rust编写的轻量级的虚拟机。借助于CrosVM 用户可以很容易的在ChromeOS中运行Linux、Android以及Windows应用程序 概述 目前crosvm实现了virtio wayland协议,实现了对linux虚拟机wayland协议支持 …

动态规划——斐波那契数列模型:面试题08.01.三步问题

文章目录 题目描述算法原理1.状态表示2.状态转移方程3.初始化4.填表顺序5.返回值 代码实现CJava 题目描述 题目链接:面试题08.01.三步问题 如果n是0走法可能是1也可能是0,所以本题范围并不需要考虑直接从1开始即可 因为以3为结尾有直接从0到3的方式&a…

Kafka 3.x.x 入门到精通(04)——对标尚硅谷Kafka教程

Kafka 3.x.x 入门到精通(04)——对标尚硅谷Kafka教程 2. Kafka基础2.1 集群部署2.2 集群启动2.3 创建主题2.4 生产消息2.5 存储消息2.5.1 存储组件2.5.2 数据存储2.5.2.1 ACKS校验2.5.2.2 内部主题校验2.5.2.3 ACKS应答及副本数量关系校验2.5.2.4 日志文…

从哪些角度优化数据资产管理?详解如何将数据转化为企业持续竞争力

在上一篇文章中我们介绍了数据资产管理的诸多保障措施,上篇文章指路👉如何保障数据资产管理有效开展?做好这几点就够了! 本文重点将转向数据资产管理的实践。在当今这个数据驱动的时代,数据已成为企业最宝贵的资产之一…

使用Excel生成sql脚本(insert/update/delete)

目录 前言 一、Excel文件脚本变量 二、操作示例 前言 在系统使用初期,存在某种原因,需要对数据库数据进行批量处理操作。往往都是通过制定Excel表格,通过Excel导入到数据库中,所以就弄一个excel生成sql的导入脚本,希…

呼叫中心常用名词解释

ACD Automatic Call Distribution 自动呼叫分配,即排队。一般是用于呼叫中心的功能。在一个呼叫中心中,会有很多的座席来应答用户的来话,但是每个座席所具有的技能或者所承担的工作负荷是 不同的,如何根据一定的算法来保证所有的座…

C语言中浮点型存储方式

前言 这次是上次博客的续写哦,如果有小伙伴不了解,可以点击链接跳转 C语言中整数与浮点数在内存中的存储 我们在上次的博客中给大家留了一段代码,不知道大家现在有没有想明白呢,让我来为大家揭秘吧!! int m…

Azure AKS集群监控告警表达式配置

背景需求 Azure AKS集群中,需要对部署的服务进行监控和告警,需要创建并启用预警规则,而这里怎么去监控每个pod级别的CPU和内存,需要自己写搜索查询 解决方法 搜索和查询的语句如下,需要自己替换其中的部分信息,其中…

python爬虫 - 爬取html中的script数据(36kr.com新闻信息)

文章目录 1. 分析页面内容数据格式2. 使用re.findall方法,爬取新闻3. 使用re.search 方法,爬取新闻 1. 分析页面内容数据格式 打开 https://36kr.com/ 按F12(或 在网页上右键 --> 检查(Inspect)) 找…

开箱机选型攻略:如何挑选适合你的自动化设备?

在如今快节奏的生产环境中,自动化设备的运用已成为企业提升效率、降低成本的关键。开箱机作为自动化生产线上的重要一环,其选型对于企业来说至关重要。星派将为您提供一份开箱机选型攻略,帮助您挑选出最适合自己的自动化设备。 一、了解开箱…

18 JavaScript学习:错误

JavaScript错误 JavaScript错误通常指的是在编写JavaScript代码时发生的错误。这些错误可能是语法错误、运行时错误或逻辑错误。以下是对这些错误的一些常见分类和解释: 语法错误: 这类错误发生在代码编写阶段,通常是由于代码不符合JavaScrip…

Transformer模型详解01-Word Embedding

文章目录 前言Transformer 整体结构Transformer 的输入单词 Embedding原理CBOW 模型one-hot构建 CBOW 训练数据集构建 CBOW 神经网络训练 CBOW 神经网络 Skip-gram 模型one-hot构建 Skip-gram训练数据集训练 Skip-gram神经网络 Word2Vec实例数据训练保存和加载 前言 Transform…

JavaScript-Vue入门

本文主要测分享Vue的一些基础 Vue简介 Vue.js 是一个构建数据驱动的 web 界面的渐进式框架。它的主要目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。 下是一些 Vue 的主要特点和概念: 1. 响应式数据绑定:Vue 使用基于 HTML 的模板语法…

文本高效拆分内容,根据空行高效拆分文本内容,文本文档管理更轻松

文本文档是我们日常生活和工作中不可或缺的一部分。然而,随着文本内容的不断增加,如何高效、有序地管理这些文档成为了一个挑战。传统的文本编辑工具往往无法满足我们对于文档整理的需求,而手动整理又费时费力。现在,我们为您带来…

【智能算法】蜉蝣算法(MA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2020年,K Zervoudakis等人受到自然界蜉蝣交配繁殖行为启发,提出了蜉蝣算法(Mayfly Algorithm, MA)。 2.算法原理 2.1算法思想 MA灵感来自蜉蝣交配…

“天才程序员”拼起命来有多狠?

本周 第四届ATEC科技精英赛(ATEC2023)线下赛——“燃烧吧!天才程序员” 在杭州蚂蚁A空间落幕了 这个比赛同时挑战16名选手脑力和体力的上限 连续三天三夜独立答题,末尾淘汰、组团PK,吃住赛场,每天仅睡4…

超实用的电脑桌面便签+待办清单app

对于上班族来说,桌面便签加待办清单软件是提升工作效率的得力助手。想象一下,在繁忙的工作中,你能够快速记录重要事项,设置待办任务提醒,一切都能有条不紊地进行。这种便捷性,尤其在处理多项任务和紧急事务…

VMware17Pro虚拟机安装macOS教程(超详细)

目录 1. 前言2. 下载所需文件3. 安装VMware3.1 安装3.2 启动并查看版本信息3.3 虚拟机默认位置配置 4. 安装补丁4.1 解压补丁4.2 结束VMware相关进程4.3 运行补丁包 5. 安装macOS5.1 新建虚拟机5.2 修改虚拟机配置5.3 安装操作系统5.3.1 选择 ISO 映像文件5.3.2 开启虚拟机5.2.…