物理浏览器模拟



在本文中,我将描述现有的解决方案,这些解决方案可用于通过物理模拟创建应用程序,比较它们的性能和提供的工具。

引言


本文中将考虑以下引擎:

Ammo.js
Cannon.js
Oimo.js
box2dweb
Unity3D WebGL

主要目标是选择使用物理模拟来开发游戏和应用程序的最高效,便捷和轻便的引擎。

Ammo.js


它是使用Emscripten编译器的javascript中Bullet物理引擎的端口,并且据开发人员称,具有几乎相同的功能。 Ammo.js的功能确实很广泛。 要使用它,您需要一个单独的库进行可视化。 最常用的是Three.js。 此外,每个重绘周期都必须手动将场景中每个对象的位置和旋转与其物理模型同步,引擎不会自动执行此操作。

至于性能,它并不太高,但是在大多数项目中不会出现明显的fps下降。

该API有时可能会造成混乱,并且文档并没有真正帮助。
通常,一个很好的工具会不断发展并得到进一步发展。

Cannon.js


Cannon.js是一个开源的轻量级物理引擎。 与前一个不同,它最初是用javascript编写的,允许您使用其所有功能和优化。 实际上,很难说这是加号还是减号,因为编译后的代码比从头开始编写的代码效率更高。 尽管如此,与ammo.js相比,cannon.js被认为更紧凑,更高效并且更易于理解,但是它没有那么多功能。 实际上,它们的性能通常近似相同。

使用引擎的过程非常简单:

//   var world = new CANNON.World(); world.gravity.set(0, 0, -9.82); //   (   ) //        var radius = 1; var sphereBody = new CANNON.Body({ mass: 5, position: new CANNON.Vec3(0, 0, 10), shape: new CANNON.Sphere(radius) }); world.addBody(sphereBody); var fixedTimeStep = 1.0 / 60.0; var maxSubSteps = 3; //    var lastTime; (function simloop(time){ requestAnimationFrame(simloop); if(lastTime !== undefined){ var dt = (time - lastTime) / 1000; world.step(fixedTimeStep, dt, maxSubSteps); } lastTime = time; })(); 

工作还需要第三方图形库,并且每个渲染周期都必须手动将场景上的相应对象移动到物理对象的位置。

 mesh.position.x = body.position.x; mesh.position.y = body.position.y; mesh.position.z = body.position.z; mesh.quaternion.x = body.quaternion.x; mesh.quaternion.y = body.quaternion.y; mesh.quaternion.z = body.quaternion.z; mesh.quaternion.w = body.quaternion.w; 

目前,该引擎实际上尚未开发,这是两年多前项目存储库中的最后一个活动,而那时该引擎才刚刚开始开发,因此在某些地方可能无法解决。

Oimo.js


Oimo.js是用纯JavaScript重写的OimoPhysics引擎版本。 与其他解决方案相比,它具有非常好的性能和准确性,但仅支持基本几何体(立方体和球体)。 它包含在Babylon.js中,Babylon.js是用于渲染2D和3D图形的框架,因此不需要其他库。

 //   world = new OIMO.World({ timestep: 1/60, iterations: 8, broadphase: 2, worldscale: 1, random: true, info: false, gravity: [0,-9.8,0] }); //    var body = world.add({ type:'sphere', size:[1,1,1], pos:[0,0,0], rot:[0,0,90], move:true, density: 1, friction: 0.2, restitution: 0.2, belongsTo: 1, collidesWith: 0xffffffff; }); var body = world.add({ type:'jointHinge', body1: "b1", body2: "b1", }); world.step(); //           myMesh.position.copy( body.getPosition() ); myMesh.quaternion.copy( body.getQuaternion() ); 

引擎的主要缺点不是非常高质量的文档,但是开发人员仍在继续努力。

此刻,发动机继续发展。

box2dweb


box2dweb是javascript box2d端口。 顾名思义,它专门用于模拟2D物理。 尽管如此,box2dweb是一个相当强大的工具,并不落后于其三维立体模型。 例如,该发动机包括用于检测碰撞和模拟连接(约束)的极为方便的系统。

至于性能,您需要真正尝试编写非最佳代码,以便出现fps缩图。

在优点中,值得一提的是API的简单性和方便的文档。

Unity3d


Unity3D是一种流行的跨平台游戏引擎。 包括一个简单方便的拖放编辑器和一个用于创建3D内容的广泛工具包。 用于编写游戏逻辑的引擎的最新版本支持C#。

Unity具有内置的物理模拟,为此使用了NVIDIA的内置PhysX引擎。 PhysX提供了广泛的功能来模拟固体,液体和组织的物理特性,并且具有非常好的性能,尽管在使用NVIDIA以外的图形加速器时会取消许多优势。 一个非常令人高兴的事实是,自2018年12月3日起,该引擎的源代码在开放的BSD-3许可下可用,但是该引擎过于复杂,无法尝试自行重写或了解其设备,因此文档将对此有所帮助。

Unity最终出现在该列表上,因为可以在WebGL下在其上构建项目。 为此,只需在构建设置中选择适当的项目。



但是,由于WebGL版本的Unity体系结构的特殊性(将代码从C#转换为C ++,再转换为JavaScript),在移动设备的性能,内存消耗和工作容量方面存在许多问题,并且似乎开发人员不会这样做。即将要做的事情。 因此,此选项并不受欢迎,我将不对其进行详细介绍。

性能比较


让我们通过引擎处理大量对象碰撞的方式来比较它们的性能。 使用的浏览器是Firefox 64.0.2 x64。
引擎处理100个对象时的fps处理500个对象时的fps处理1000个对象时的fps
ammo.js40-5025-2715-25
cannon.js30-4020-2515-20
oimo.js45-5535-4035-40

根据测试结果,Oimo.js表现出最佳性能。

当然,这些结果取决于许多第三方因素,因此不能提供对生产率的充分评估,但是全面的研究将需要更多的时间,而我并没有设定自己的目标。 此外,值得注意的是,所有经过比较的引擎的性能都非常低,因此这些解决方案不适合远距离编写每个游戏,而非常适合创建小型演示。

结论


通常,特定引擎的选择取决于任务。 如果您需要一个易于理解和易于学习的引擎,Cannon.js或Oimo.js.非常适合。 如果需要更多功能,最好使用Ammo.js。 在某些情况下,如果不需要出色的性能,则可以尝试使用Unity。

Source: https://habr.com/ru/post/zh-CN436192/


All Articles