Babylon.js大规模场景优化实践

news2024/11/27 15:54:39

在本文中,我们将重点介绍用于优化 Babylon.js 海港场景的优化和架构技术。 我们的场景总共有超过 600 个网格和 1,000,000 个顶点。 在我们的 2018 Macbook Pro 上,它在 Google Chrome 中始终以 45+ FPS 的速度运行。 我们发现 Firefox 约为 40 FPS,而 Safari 则低得多,但仍可用,为 25 FPS,主要是因为它不支持 WebGL 2.0。

在这里插入图片描述

推荐:用 NSDT设计器 快速搭建可编程3D场景。

这里讨论的优化技术确实涵盖了 Babylon.js,但也侧重于改进我们使用的对性能有巨大影响的底层模型、材料和光照的方法。 我们所有的模型都是使用 Blender 构建的,因此,此处包含的示例通常参考 Blender 解决方案,但也可以使用任何其他 3d 计算机图形软件。

注意:可用的优化技术比这里描述的要多得多,有些可能不适用于你自己的环境(例如,我们的一些技术要求我们的模型在场景中是静态的)。 有关推荐技术的更多列表,请查看 Babylon 官方关于这个问题的文章。

1、单个与多个模型导入

在为场景设计资产时需要权衡取舍。 以我们的 Harbor 为例。

在这里插入图片描述

我们可以在单个 .blend 文件中对整个场景进行建模,然后通过单个 .gltf 文件将其传输到 Babylon。 或者,我们可以在独立的 .gltf 文件中设计每个建筑物、船只、树木和岩石,然后在 Babylon.js 脚本中导入和定位资产。

更少的模型和网格意味着 Babylon 渲染循环要循环的更少。 在 3d 软件中安排场景也更容易,并且可以由不熟练的 JavaScript 程序员的团队成员完成。 但是,如果你有一个特别大的模型,加载时间可能会很长(对于上下文,我们最终的 .glb 文件是 8MB)。

或者,我们可以在自己的 .gltf 文件中构建我们的个人资产(建筑物、树木等),然后导入这些文件并使用 JavaScript 来定位它们。 这在设计布局和空间方面不如在自己的 3d 软件中实用,但在加载时间方面有所收获,因为模型可以并行加载。 它还可以轻松利用 Babylon 自己的实例化功能,从而进一步优化树的放置。

在 MAS 数字体验中,我们选择了一种混合方式。 大多数情况下,我们依赖于在 Babylon.js 之外构建的资产,而是在 Blender 中。 我们发现让非开发人员自由编辑场景太有用了,不能牺牲。 我们对加载时间感到满意,因为体验总是预加载了介绍性动画,因此在后台发生的场景加载不太明显。 此外,我们知道我们想要在 Blender 中对我们的场景进行高质量渲染。 在那里构建完整场景意味着静态渲染完美地反映了基于浏览器的世界。

2、使用 Babylon.js 监控性能

为了进行优化,我们需要在整个开发过程中注意我们的表现。 虽然 Babylon.js 有自己出色的调试检查器,但我们发现在开发中有用的最简单的资源是创建我们自己的 FPS 计数器,它始终位于角落。 Babylon 引擎可以公开此值。
在这里插入图片描述

当我们向场景添加新资源时,当我们在做一些对性能有害的事情时就会变得非常清楚。 此外,在有意识地优化我们的场景时,这提供了一个非常易于阅读的改进指标。

不过,请务必在执行此操作时与你的场景进行交互。 仅仅因为你的场景在相机静止时以 60 FPS 运行,并不意味着它会保持这种状态。 四处走动,点击东西,做你的用户会做的事情!

如果你正在努力寻找性能影响发生的地方,我们在 Inspector 中发现了这些非常有用的 Babylon 功能,它们对你有所帮助:

2.1 线框和点渲染

在 Babylon 的 Inspector 中,我们可以选择更改渲染模式。 你可以通过在场景代码中包含以下行来查看检查器:

scene.debugLayer.show()

从现在显示的菜单中,单击左侧“场景资源管理器”中的“场景”对象。 在右侧的“渲染模式”下,你可以在“点”、“线框”和“实体”之间切换。 我们发现的这些替代视图提供了非常清晰的多边形密度图像。
在这里插入图片描述

在这种情况下,我们可以看到该图像中心的建筑物代表 IBM 的运营决策管理器,考虑到它包含的边数和多边形数量,优化仍然很差。

2.2 显示/隐藏网格和已启用切换

Inspector 的另一个最有用的功能是能够打开/关闭场景中的每个网格。 这提供了一种非常简单的方法来监控特定资源对场景性能的影响,这可能与多边形计数无关。

关于如何执行此操作有两种选择:

  • “场景资源管理器”中任何网格右侧的“眼睛”图标。
  • Babylon TransformNode 的“IsEnabled”开关。 单击场景资源管理器中的变换节点后,此选项将显示在右侧检查器的“常规”选项卡中。

在 Blender 中,我们发现将对象组父子化到单个 Empty 创建的变换节点。 这些在这里特别有用,因为当导入到 Babylon 时,可以打开/关闭每个节点的“isEnabled”选项,因此一次点击所有子节点,使得寻找潜在的性能改进变得更加容易。 Blender 集合在导出到 gltf 时丢失。

启用全场景后,我们达到了 48 FPS。
在这里插入图片描述

在我们的产品相关建筑物的 Inspector 中关闭“isEnabled”选项时,对 FPS 的影响很小——现在为 49 FPS。

在这里插入图片描述

但是,当关闭我们的“填充”建筑物时,我们注意到一个显着的改进,帧速率跃升至 59/60 FPS。 显然,这些网格是我们需要集中注意力并进一步优化的地方。

3、标准 3D 优化技术

我们应该在此处遵循适用于任何实时渲染场景的标准良好实践,无论是 Babylon.js 还是基于浏览器的场景。

3.1 多边形计数

要考虑的最简单的指标是多边形计数。 渲染 4 个顶点比渲染 4,000,000 个要快得多。 在可能的情况下,对你的模型要聪明,只在重要的地方添加细节。 如果你的相机缩小到永远看不到它,那么在角色模型上雕刻高清面部是没有意义的。

Ian Hubert 的 1 分钟“懒惰”Blender 教程是一个很好的例子,说明即使使用超低多边形网格也可以获得多少“细节”。 为 4k 渲染和高预算电影构建高清模型非常好,但如果你希望构建基于浏览器的体验,那么请灵活地确定你的模型在何处以及如何提供细节。
在这里插入图片描述

岩石模型重新拓扑的“前后”视图

如果你有一个高多边形模型并希望对其进行优化,那么重新拓扑是你的朋友。 这可能是一个乏味的过程,但性能改进是显着的。

如果你的建筑物有窗户或门等细节,那么你还可以烘焙法线贴图以提供细节外观,而不会减少顶点数。 法线贴图在不牺牲多边形计数的情况下添加高细节特别有效。
在这里插入图片描述

左:应用了法线贴图的模型; 中间:没有法线贴图的模型; 右:法线贴图

值得注意的是 .gltf 网格具有三角面,因此当你将模型移至 Babylon 时看到大量“面数”跳跃时不要感到惊讶。 在可能的情况下,在导入之前对面进行三角剖分,以确保你可以控制多边形和面数。

3.2 实例化

如上所述,渲染 4 个顶点比渲染 4,000,000 个要快。 我们可以“欺骗”我们的渲染器认为我们正在使用更少的顶点的一种方法是通过实例化。 这减少了 Babylon 在每次渲染中必须经历的绘制调用总数。

在我们完成的海港场景中,我们有 631 个活动网格和 73 个绘制调用。 在没有实例化的情况下,我们预计会有 631 次绘制调用,并且在我们的案例中渲染速度会慢 5-10 倍。
在这里插入图片描述

实例化是使用硬件加速渲染绘制大量相同网格(让我们想象一片森林或一支军队)的绝佳方式。 这可以在你选择的 3d 软件中完成(我们使用 Blender,可以使用链接副本实现),或者直接在 Babylon.js 中完成,如果你的场景适合从内部定位对象的用例 JavaScript。

在一个场景中多次实例化和重复使用同一个模型的一个负面后果是,很明显你一遍又一遍地冲洗和重复同一个网格。

在这里,我们分享了一些来自 Blender 的示例渲染,展示了如何利用实例化,同时保持模型的规模感和可变性。

在这里插入图片描述

左:16 个顶点(实例化); 16k 个顶点(无)——中间:48 个顶点(有); 48k 个顶点(无)——右:228 个顶点(有); 228k(不含)

在我们的第一张图片中,我们有一个实例化了 1,000 次的建筑物。 在第二次渲染中,我们使用建筑物的 3 种材质变体,平均分配给 1,000 个实例。 最后,在第三张图片中,我们修改了建筑物,使其不对称,并引入了围绕垂直轴的随机旋转。 这些微小的变化带来了可变性,同时保持了优化的几何形状。

4、WebGL 的额外注意事项—材质合并

使用 Babylon 时,通常使用 .gltf 格式导入文件。 不过你可能会注意到,当模型加载到 Babylon 时,它会将i的模型拆分为多个单独的对象。

这是在逐个材质的基础上发生的,这意味着在渲染循环中,Babylon 每次都会循环遍历每个新创建的对象,而不仅仅是单个原始网格——代价高昂!

理想的解决方法是尽可能少地使用材料,虽然你可能希望每个对象都具有漂亮的 4K 纹理和 PBR 材料,但如果可以并且符合想要的审美,你可以使用调色板。

在这里插入图片描述

左图:从 IBM Carbon Palette 创建的多种调色板。 右图:我们用于港口场景的调色板,其中包括渐变段。
使用调色板,你可以为所有对象定义单一材质。 将该材料的基础/反照率颜色设置为调色板纹理,并确保模型的 UV 面与你想要的颜色对齐。

为此,在你的 3d 软件中,UV 展开对象,将对象的 UV 缩小到零,然后将 UV 移动到与你希望该面的颜色相匹配的彩色方块中。 如果你使用的是 Blender,Imphenzia 会在他的 10 分钟 Blender 挑战中经常这样做,他在这里详细介绍了这项技术。

每个调色板只需 3x3 像素(9 种不同颜色)或 8x8 像素(64 种颜色)。 你也可以选择更大的调色板,这样你就可以选择将渐变添加到调色板中。 如上所示,我们在五月花号体验中将这种技术用于港口的调色板。

5、Babylon.js 技巧与技巧

如前所述,Babylon 的文档包含丰富的解决内存使用和性能问题的方法。 我们发现了两个特别有用的资源:

  • 优化场景:链接
  • 减少内存占用:链接

具体来说,我们在场景和适当的网格导入中使用了以下方法:

5.1 场景:禁用对象交互

如果在你的场景中,不需要直接与 3d 网格交互,那么我们发现禁用鼠标事件非常有效。

scene.pointerMovePredicate = () => false;
scene.pointerDownPredicate = () => false;
scene.pointerUpPredicate = () => false;

我们的 Harbor 和 Challenge 3 场景中使用了这种方法。 我们不能在挑战 1 中使用它,因为我们需要检测用户点击环境对象(岩石、浮标和船只)。

5.2 场景:移除缓存的顶点数据

所有顶点缓冲区都在 CPU 内存中保留其数据的副本,以支持碰撞、拾取、几何编辑或物理。 如果你不需要使用这些功能,你可以调用这个函数来释放相关内存:

scene.clearCachedVertexData();

5.3 网格导入:静态资产

如果有不会改变位置、旋转或大小的网格,那么通过调用“冻结”网格会变得非常有效:

mesh.freezeWorldMatrix();

即使它们确实发生变化,但会间歇性地发生变化,你也可以通过调用以下命令重新打开世界矩阵计算:

mesh.unfreezeWorldMatrix();

5.4 网格导入:无交互

如果不需要用户单击或拾取你的网格,则可以在导入网格时添加以下行以进一步提高性能:

mesh.isPickable = false;
mesh.doNotSyncBoundingInfo = true;

5.5 VueJS 和Babylon.js的组合问题

在我们的项目完成后,我们实际上发现了使用 BabylonJS 和 VueJS 的陷阱。 虽然我们对这里的 FPS/性能非常满意,但事实证明我们通过将 BabylonJS 引擎和场景绑定为 VueJS 中的反应变量导致了巨大的 FPS 不足。

我不会在这里详细介绍,但这篇论坛帖子中对此进行了非常详细的介绍。


原文链接:BabylonJS大规模场景优化— BimAnt

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

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

相关文章

公厕卫生间除臭杀菌空气净化解决方案

人每天平均大约有80%以上时间是在室内度过,室内空气同时面临着化学污染、物理污染和生物污染,据统计室内污染比室外高5~10倍,因此室内空气质量问题对人的伤害比室外污染更大。常见的空气污染有病毒、烟雾、甲醛、细菌、PM2.5等,如…

淘宝商品详情数据采集,支持高并发请求

一、如何通过手动方式查看阿里巴巴商品详情页面的数据 1.淘宝天猫商品详情 API 接口(item_get - 获得淘宝商品详情接口),淘宝API 接口代码对接可以获取到宝贝 ID,宝贝标题,价格,优惠价,掌…

C++优化方法

C优化方法 文章目录 C优化方法1.整数运算效率高于浮点2.除法和取余4.通过2的幂次进行除法和取余数5.使用数组下标6.全局变量->局部变量7.指针值不改变的->拷贝到局部变量8.变量类型9.局部变量10.指针11.指针链12.条件执行13.布尔表达式和范围检查14.布尔表达式和零值比较…

【UE4 像素流 WEBUI插件】部署像素流

目录 一、单实例本地像素流送 步骤 1. 勾选插件 2. 打包工程并启动信令服务器 3. 创建快捷方式并启动游戏 二、单实例局域网像素流送 步骤 1. 编辑cirrus.js 2. 编辑快捷方式属性 3. 启动 三、集成WEBUI插件 一、单实例本地像素流送 步骤 1. 勾选插件 勾选使用“Pix…

数字化时代下,企业如何利用数字化提升企业竞争力?

在数字化时代的今天,企业越来越意识到数字化的重要性。数字化已经成为企业竞争的关键。在数字化时代下,企业的竞争力也已经从传统的硬实力向软实力转变。企业需要利用数字化技术来提高竞争优势,从而在激烈的竞争中脱颖而出。 目前&#xff0c…

Mysql_行锁、临键锁、间隙锁的理解

目录 行锁间隙锁临键锁总结 行锁 行锁,也称为记录锁。 当我们针对主键或者唯一索引加锁的时候,Mysql默认会对查询的这一行数据加行锁,避免其他事务对这一行数据进行修改。 间隙锁 间隙锁,顾名思义,就是锁定一个索引…

浅谈作为程序员如何写好文档:结构化写作

我作为从一名懵懂的实习生转变为工程师的工作经历中,伴随着技术经验的成长,也逐渐意识到了编写文档是知识和经验传递给其他人的最有效方式。通过文档,可以分享我的技术知识和最佳实践,使其他人更好地理解我的工作。在这里&#xf…

图解 SQL 执行顺序,清晰明了

这是一条标准的查询语句: 这是我们实际上SQL执行顺序: 我们先执行from,join来确定表之间的连接关系,得到初步的数据 where对数据进行普通的初步的筛选 group by 分组 各组分别执行having中的普通筛选或者聚合函数筛选。 然后把再根据我们要的数据进行…

alias设置快捷键vim使用说明(解决服务器上输入长指令太麻烦的问题)

1. vi ~/.bashrc打开 2. (watch -n 1 gpustat 查看gpu使用情况 太麻烦)输入i进行编辑,最后一行输入 alias watchgpuwatch -n 1 gpustat alias gpuwatch -n 1 gpustat alias torch180source activate torch180 3. 按esc,然后输入:wq保存退出 4. source…

多轴加工-可变轴轮廓铣_刀轴控制策略

可变轴轮廓铣_刀轴 刀轴是可变轴轮廓铣最重要的核心参数之一,控制好刀轴对生成的刀路质量至关重要。UG NX可变轴轮廓铣提供了非常丰富的刀轴控制方法,常用的包括远离/朝向直线(点)、相对于/垂直于驱动体、侧刃驱动体、插补等&…

在Apex中获取Site URL

Foreword 目前SF暂未提供直接有效的方法在Apex获取SiteURL,我们可以在Idea (Access URL for a Site or Community from Apex)页面投票,除了下面提供的一种hack思路,当然也可以通过Custom Label手动维护。 Format of Site URL Sandbox site …

如何搭建自己的写作素材库,快来学,方法高效简单

我们平时看过的书,做过的事,不及时记下来,很可能过几天就忘记了。由此看来,搭建自己的写作素材库非常有必要。尤其是写作者,写稿的速度取决于自己写作素材的储备量,你储备的素材越多,写作时便可…

【算法学习系列】01 - 求某个数组中的任意两个位置之间的累加和

文章目录 背景解决思路代码实现 背景 已经呆在自己的舒适圈有很长一段时间了(公司快3年了,业务都熟的差不多了),决定开始改变(任何时候都不晚),尝试学习解决一些算法题,给自己一些适…

自媒体可以去哪里找免费图片素材?

推荐6个超好用的图片素材网站,免费下载,还可以商用,建议收藏起来~ 1、菜鸟图库 https://www.sucai999.com/pic.html?vNTYwNDUx 菜鸟图库是一个综合性素材网站,站内有大量的设计、自媒体等相关素材,像图片素材就非常…

Linux篇2

Linux 0. 终端提示信息1. 文件目录结构1.1 文件目录 2. 文本编辑器VI/VIM2.1 VIM编辑器2.1 一般模式2.2 编辑模式2.3 命令模式 3. 网络配置3.1 VMware提供的三种网络连接模式3.2 静态配置网络IP地址3.3 配置主机名3.3.1 修改主机名3.3.2 配置主机名-IP地址映射关系:…

离散化详解

一.概念 把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。通俗的说,离散在不改变数据相对大小的条件下,对数据进行相应的缩小。 二.适用范围 数组中元素值域很大,但个数不是很多。 比如将a[][1,3,100,2000,…

CloudCompare二次开发之如何通过PCL进行点云滤波?

文章目录 0.引言1.CloudCompare界面设计滤波(filter)按钮2.PassThrough直通滤波器3.VoxelGrid体素滤波器4.UniformSampling均匀采样5.StatisticalOutlierRemoval统计滤波器6.RadiusOutlierRemoval半径滤波器7.ConditionRemoval条件滤波器8.ProjectInliers投影滤波器9.ModelOutl…

js跨域的解决方案

一、什么是跨域? 指的是浏览器不能执行其他网站的脚本,简单来说是浏览器同源政策的限制,浏览器针对于ajax的限制。 同源政策 两个页面拥有相同的 协议,端口,域名 就是同源,如果有一个不相同就是不同源…

【SQL】作为前端,应该了解的SQL知识(第四弹)

📑集合运算 集合运算就是对满足同一规则的记录进行的加减等四则运算。 👉 对行数进行增减。 📃UNION 取并集 集合运算符会去除重复的记录 SELECT product_id, product_nameFROM Product **UNION** SELECT product_id, product_nameFROM …

图神经网络:(图的分类)在MUTAG数据集上动手实现图神经网络

文章说明: 1)参考资料:PYG官方文档。超链。 2)博主水平不高,如有错误还望批评指正。 3)我在百度网盘上传了这篇文章的jupyter notebook。超链。提取码8848。 文章目录 MUTAG数据集说明图的小批量处理法图分类的基本流程改进算法 MUTAG数据集说…