gpt4 book ai didi

javascript - Pixi.js 等二维绘图框架如何让 canvas 绘图更快?

转载 作者:技术小花猫 更新时间:2023-10-29 12:15:07 28 4
gpt4 key购买 nike

我为 Javascript canvas 找到了一个 bunnymark here .

当然,我知道他们的默认渲染器正在使用 webGL,但我现在只对原生 2D 上下文性能感兴趣。我在 Firefox 上禁用了 webGL,在生成 16500 个兔子后,计数器显示 FPS 为 25。我决定编写自己的非常简单的渲染循环,看看 Pixi 增加了多少开销。令我惊讶的是,我的 FPS 仅为 20。

我大致相当于 JSFiddle .

所以我决定查看他们的来源here而且他们的渲染代码似乎并不神奇:

do  
{
transform = displayObject.worldTransform;
...
if(displayObject instanceof PIXI.Sprite)
{

var frame = displayObject.texture.frame;

if(frame)
{
context.globalAlpha = displayObject.worldAlpha;

context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]);

context.drawImage(displayObject.texture.baseTexture.source,
frame.x,
frame.y,
frame.width,
frame.height,
(displayObject.anchor.x) * -frame.width,
(displayObject.anchor.y) * -frame.height,
frame.width,
frame.height);
}
}

奇怪的是,他们似乎正在为他们的渲染循环使用链表,并且两个应用程序的配置文件显示虽然我的版本每帧分配相同数量的 cpu 时间,但他们的实现显示 cpu 使用率呈峰值。

不幸的是,我的知识到此为止,我很好奇是否有人可以阐明发生了什么。

最佳答案

我认为,在我看来,这归结为代码的“可编译”(可缓存)程度。正如我们所知,Chrome 和 Firefox 使用两种不同的 JavaScript“编译器”/引擎,它们以不同的方式优化和缓存代码。

Canvas 操作

使用变换与直接坐标不应该有影响,因为设置变换只是更新矩阵,无论如何都与其中的任何内容一起使用。

位置值的类型可能会影响性能,floatinteger 值相比,但是因为您的 fiddle 和 PIXI 似乎都使用 float 只是这不是这里的关键。

所以在这里我不认为 Canvas 是造成差异的原因。

变量和属性缓存

(在这个答案的第一个版本中,我无意中过于关注了原型(prototype)方面。我试图了解的本质主要是对象遍历,因此这里重新措辞了以下文本有点-)

PIXI 使用对象属性作为 fiddle ,但 PIXI 中的这些自定义对象的尺寸较小,因此与遍历更大的对象(如 Canvas 或图像)相比,遍历对象树所需的时间更少(属性如width 也将在此对象的末尾)。

由于这个原因(遍历时间),缓存变量是众所周知的经典优化技巧。随着引擎变得更智能,今天的效果不那么明显了,尤其是 Chrome 中的 V8,它似乎能够在内部更好地预测/缓存它,而在 Firefox 中,不在代码中缓存这些变量似乎仍然有一些影响。

这对性能有影响吗?对于短期操作非常少,但在 Canvas 上绘制 16,500 个兔子是一项要求很高的操作,确实可以从中获益(在 FF 中),因此在这种情况下,任何微优化实际上都算数。

演示

我制作了“渲染器”原型(prototype),以更接近 PIXI 以及缓存对象属性。这使 Firefox 的性能突飞猛进:
http://jsfiddle.net/AbdiasSoftware/2Dbys/8/

我使用了一台速度较慢的计算机(以衡量影响),它以大约 5 FPS 的速度运行您的 fiddle 。缓存值后,它以 6-7 fps 的速度运行,这在这台计算机上增加了 20% 以上,表明它确实有效果。在具有较大 CPU 指令缓存等的计算机上,效果可能较小,但它存在,因为这与 FF 引擎本身有关(免责声明:我并不是说这是一项科学测试,只是一个指针:- )).

/// cache object properties
var lastTime = 0,
w = canvas.width,
h = canvas.height,
iw = image.width,
ih = image.height;

下一个版本将这些变量缓存为对象(本身)的属性,以表明与直接使用大型全局对象相比,这也提高了性能 - 结果与上面大致相同:
http://jsfiddle.net/AbdiasSoftware/2Dbys/9/

var RENDER = function () {
this.width = canvas.width;
this.height = canvas.height;
this.imageWidth = image.width;
this.imageHeight = image.height;
}

总结

根据结果和以往的经验,我确信 PIXI 可以更快地运行代码,因为使用自定义的小型对象而不是直接从 Canvas 和图像等大型对象(元素)获取属性。

FF 引擎在树和分支的对象遍历方面似乎还不如 V8 引擎“聪明”,因此缓存变量确实对 FF 有影响,当需求很高时(例如当每“帧”绘制 16,500 只兔子。

关于javascript - Pixi.js 等二维绘图框架如何让 canvas 绘图更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20297589/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com