box2d 服务器性能,JavaScript物理引擎之Matter.js与Box2d性能对比

前言

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

本文简单对两个引擎的性能在不同平台上进行对比,其中Box2D采用的是TypeScript实现的版本:https://github.com/flyover/bo..., 作者仍然在更新,matter-js采用的是0.14.2版本(感觉作者已经更新不动这个库了:),大半年都不怎么活跃了)。

测试案例

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

影响性能的因素机器本身的配置;

JIT:苹果端微信小游戏没有JIT,性能会受到一些影响;

刚体的随机性:刚体在随机位置生成的过程中,如果与其他刚体重叠,物理引擎需要更多的性能消耗来修正重叠,因此,每次运行测试用例数据上都不可避免会有波动。

引擎本身的设计:比如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的苹果端微信小游戏平台查看数据:引擎耗时Box2D8ms

matter-js25ms

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值