关闭

JavaScript物理引擎之Matter.js与Box2d性能对比

时间: 2019-01-19阅读: 1010标签: 引擎

前言

在挑选JavaScript 2D物理引擎的时候,不外乎两种主流的选择:第一种是老牌的Box2D,最开始的版本是C++实现的,后来有了很多种实现,比如flash版本和js版本,具体可看:https://stackoverflow.com/que...;第二种是新潮的matter-js,matter-js比较轻量,API和文档都比较有友好。

这段时间先后折腾了matter-js和Box2D,因为项目需要在微信小游戏端运行,对性能要求比较高,最终还是选择了Box2D。

但凡涉及到这种需要经常看源码才能使用的库中文社区都非常少干货,这段时间折腾之后打算整理一些文章,分享给社区也作为一个知识备忘。

本文简单对两个引擎的性能在不同平台上进行对比,其中Box2D采用的是TypeScript实现的版本:https://github.com/flyover/bo..., 作者仍然在更新,并且我看了下CocosCreator内置的物理引擎也是基于这个进行的封装,社区还是可以得到保证的。matter-js采用的是0.14.2版本(感觉作者已经更新不动这个库了:),大半年都不怎么活跃了)。


测试案例

在屏幕随机位置重复创建相同的矩形刚体,使之自由落体到底部,计算不同刚体数量下,全部刚体落地后每一帧的物理计算平均耗时。下面是测试中的一些截图:



影响性能的因素

  1. 机器本身的配置;
  2. JIT:苹果端微信小游戏没有JIT,性能会大打折扣;
  3. 刚体的随机性:刚体在随机位置生成的过程中,如果与其他刚体重叠,物理引擎需要更多的性能消耗来修正重叠,因此,每次运行测试用例数据上都不可避免会有波动。
  4. 引擎本身的设计:比如Matter.js没有圆形的定义,创建圆形刚体本质上是创建25边形,而Box2d天然就设计了圆形刚体,所以对于圆形刚体,两个引擎会存在不小的差异。


数据采集

因为是测试物理引擎的性能,这里不考虑FPS,只采集物理引擎更新每一帧的时间,因为除开物理引擎,渲染引擎(PixiJS)也会带来性能消耗。

// Box2d数据打点
let positionIterations = 3;
let velocityIterations = 8;
let timeStep           = 1 / 60;
Performance.startPoint('box2dUpdateCost');
world.Step(timeStep, velocityIterations, positionIterations);
Performance.endPoint('box2dUpdateCost');
// Matter.js数据打点
Performance.startPoint('matterUpdateCost');
matter.Engine.update(this.engine, 1e3 / this.fps);
Performance.endPoint('matterUpdateCost');
// 计算平均耗时
function calAverage(list, key) {
    let sum = list.reduce((total, curr) => curr[key] + total, 0);
    console.log(sum / list.length)
}

// 所有数据会收集到一个数组里面
let data = Performance.print();

//calAverage(data, 'matterUpdateCost');
calAverage(data, 'box2dUpdateCost');


Box2D数据

机型10个刚体20个刚体50个刚体100个刚体200个刚体300个刚体
MacBook Pro 20150.2ms0.4ms~0.5ms0.6ms~0.8ms1.3ms~1.6ms4.6ms~5.6ms7ms~8ms
iPhone7 Plus微信小游戏3.3ms~3.5ms4.5ms~5.5ms7.5ms~8.5ms13ms~14ms33ms60ms+
OPPO R11 Plus微信小游戏1.5ms~2.5ms1.8ms~3ms3.6ms6ms~8ms9ms~12ms17ms~19ms

matter-js数据

机型10个刚体20个刚体50个刚体100个刚体200个刚体300个刚体
MacBook Pro 20150.5ms~0.6ms0.6ms~1ms2ms~3ms3.5ms~4ms6ms~8ms12ms~13ms
iPhone7 Plus微信小游戏2.3ms~2.8ms3.0ms~3.5ms6.0ms~6.5ms11.5ms~12ms26ms~28ms45ms
OPPO R11 Plus微信小游戏1.5ms~2.5ms2.5ms5~6ms8ms12ms~14ms30ms

结论

在PC端,Box2d全面战胜了matter-js,在苹果的微信小游戏端,因为没有JIT,Box2d性能反而不如matter-js,而回到安卓的微信小游戏端,因为有JIT,Box2d同样是可以战胜matter-js的。


关于圆形刚体

上面提到了两个引擎对于圆形刚体的设计,因为matter-js没有正统的圆形,我大胆猜测圆形刚体的性能Box2D会大大高于matter-js!

特意去翻了下各自的源码,首先我们来看看matter-js的:

Bodies.circle = function(x, y, radius, options, maxSides) {
    options = options || {};
    var circle = {
        label: 'Circle Body',
        circleRadius: radius
    };
                                
     // approximate circles with polygons until true circles implemented in SAT
    maxSides = maxSides || 25;
    var sides = Math.ceil(Math.max(10, Math.min(maxSides, radius)));

    // optimisation: always use even number of sides (half the number of unique axes)
    if (sides % 2 === 1)
        sides += 1;
        
    return Bodies.polygon(x, y, sides, radius, Common.extend({}, circle, options));
};

从上面的代码可得,matter-js将25边形当成圆,这里在进行碰撞检测的时候,会比纯圆有更多的计算量,不知道matter-js作者是出于什么目的这样设计。

再来看看Box2D版本的实现:

class b2CircleShape extends b2Shape {
      constructor(radius = 0) {
          super(exports.b2ShapeType.e_circleShape, radius);
          this.m_p = new b2Vec2();
      }
      Set(position, radius = this.m_radius) {
          this.m_p.Copy(position);
          this.m_radius = radius;
          return this;
      }
}

与matter-js相比,Box2D的圆与多边形是独立的。

多说无益,我们对比下100个刚体状态下,两个引擎的数据对比,为了凸显差距,我们选择Box2D打不过matter-js的苹果端微信小游戏平台查看数据:

| 引擎 | 耗时 |
| ------------ | ------------ | 
| Box2D | 8ms | 
| matter-js | 25ms!! |

我们可以得出一个有意思的结论:同样是100个刚体,矩形刚体的耗时是13ms~14ms,而圆形刚体的耗时下降到了8ms,这对于一些弹球类的游戏无疑是福音,据我的观察,100个圆形刚体在苹果端微信小游戏下面丝毫不会卡顿。而matter-js的耗时从11.5ms~12ms上升到了25ms,显然就是在越多边形碰撞检测需要的计算量越大!


来自:https://segmentfault.com/a/1190000017946077

站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/1842

关闭

V8 8.0 JavaScript 引擎降低堆内存 40%,添加语言特性 Optional Chaining 和 Null Coalescing

Google 最新发布了 V8 JavaScript 引擎 V8 8.0 ,其中使用压缩指针(pointer compression)技术,在不影响性能的情况下实现堆内存占用降低了 40%。此外,V8 8.0 添加了支持“可选链”(optional chaining)的操作符 ?.

JS 引擎 V8 发布 v7.4,性能又大幅提高了

JavaScript 引擎 V8 发布了 7.4 版本,目前处于 beta 阶段,正式版将于几个星期后与 Chrome 74 Stable 一起发布。此版本带来了一些新特性,并极大提升了性能。

模板引擎art-template怎么安装?

art-template支持标准语法和原始语法。标准语法允许模板更易于读写。而原始语法具有强大的逻辑处理能力。标准语法支持基本模板语法和JavaScript表达式。原始语法支持任意JavaScript语句,与EJS相同。

如何用 JavaScript 实现一个模板引擎

不知不觉就很长时间没造过什么轮子了,以前一直想自己实现一个模板引擎,只是没付诸于行动,最近终于在业余时间里抽了点时间写了一下。因为我们的项目大部分用的是 swig 或者 nunjucks ,于是就想实现一个类似的模板引擎。

精读《V8 引擎 Lazy Parsing》

本周精读的文章是 V8 引擎 Lazy Parsing,看看 V8 引擎为了优化性能,做了怎样的尝试吧!这篇文章介绍的优化技术叫 preparser,是通过跳过不必要函数编译的方式优化性能。

免费搜索引擎提交(登录)入口大全

搜索引擎网站收录地址大全;独立博客收录提交网址;英文搜索网站收录地址;注意:目前搜狗,Soso,迅雷狗狗没有网站提交入口,它们都是由谷歌提供技术支持,基本上只要谷歌收录了它们也会跟风。

V8引擎-枚举+位运算实现参数配置

基本上从初始化引擎,到Isolate、handleScope、Context一直到编译其实都有记录,但是实在是无从下手。虽说我的博客也没有什么教学意义,但是至少也需要有一个中心和结论。

20 行代码实现模板引擎

实现功能 : 变量值的替换、if / else 及 for 循环等复杂操作。利用 exec 方法将变量替换为对象属性值,注意此方法输出的是一个数组,形如下方代码。

JS引擎V8如何与 Lite 模式两开花?

去年年底,V8 团队启动了一个名为 V8 Lite 的项目,旨在大幅降低 V8 的内存使用率。最开始,团队准备把 V8 Lite 作为 V8 的独立模式,专门用于低内存的移动设备与嵌入式设备,因为这些设备更关注的是减少内存使用而不是执行速度

JavaScript引擎是如何工作的?从调用栈到Promise你需要知道的一切

你有没有想过浏览器是如何读取和运行 JavaScript 代码的吗?这看起来很神奇,但你可以学到一些发生在幕后的事情。让我们通过介绍 JavaScript 引擎的精彩世界在这种语言中尽情畅游。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!