HTML5 Canvas save()和restore()性能

MAAAN

因此,我遇到的问题是,在开发HTML5 canvas应用程序时,我需要使用大量的转换(即平移,旋转,缩放),因此需要对context.save()和context.restore进行大量调用()。即使绘制很少,性能也会很快下降(因为在循环中,多次调用了save()和restore())。除了使用这些方法之外,还有其他方法可以使用转换吗?谢谢!

盲人67

动画和游戏性能提示。

避免保存还原

使用setTransform,因为这样就不需要保存和还原。

保存还原的原因有很多,它们会减慢速度,这取决于当前的GPU && 2D上下文状态。如果您将当前的填充和/或笔触样式设置为大图案,或者具有复杂的字体/渐变,或者使用的是过滤器(如果有),则保存和还原过程可能比渲染图像花费更长的时间。

在编写动画和游戏时,性能就是一切,对我而言,它是关于精灵数的。我可以在每帧(第60秒)中绘制的精灵越多,可以添加的FX越多,环境越详细,游戏效果越好。

我将状态保持开放状态,也就是说,我没有详细跟踪当前2D上下文状态。这样,我永远不必使用保存和还原。

ctx.setTransform而不是ctx.transform

因为变换功能变换,旋转,缩放,翻译乘以当前变换,所以很少使用它们,因为我不知道变换状态是什么。

为了处理未知数,我使用setTransform来完全替换当前的转换矩阵。这也使我可以在一次呼叫中设置比例和平移,而无需知道当前状态是什么。

ctx.setTransform(scaleX,0,0,scaleY,posX,posY); // scale and translate in one call

我还可以添加旋转,但是用于查找x,y轴向量(setTransform中的前4个数字)的javascript代码比旋转慢。

精灵并渲染它们

以下是扩展的Sprite函数。它从一个精灵表中绘制一个精灵,该精灵具有x&y比例,位置和中心,并且由于我总是使用alpha,所以也要设置alpha

// image is the image. Must have an array of sprites
// image.sprites = [{x:0,y:0,w:10,h:10},{x:20,y:0,w:30,h:40},....]
// where the position and size of each sprite is kept
// spriteInd is the index of the sprite
// x,y position on sprite center
// cx,cy location of sprite center (I also have that in the sprite list for some situations)
// sx,sy x and y scales
// r rotation in radians
// a alpha value
function drawSprite(image, spriteInd, x, y, cx, cy, sx, sy, r, a){
    var spr = image.sprites[spriteInd];
    var w = spr.w;
    var h = spr.h;
    ctx.setTransform(sx,0,0,sy,x,y); // set scale and position
    ctx.rotate(r);
    ctx.globalAlpha = a;
    ctx.drawImage(image,spr.x,spr.y,w,h,-cx,-cy,w,h); // render the subimage
}

在普通的机器上,您可以使用该功能以全帧速率渲染1000个+子画面。在Firefox上(在撰写本文时),该函数的功能为2000+(小精灵是从1024 x 2048的小精灵表中随机选择的小精灵),最大小精灵大小为256 * 256

但是我有15种以上的此类功能,每个功能都具有执行我想要的功能所需的最少功能。如果它从未旋转过或缩放过(即针对UI),则

function drawSprite(image, spriteInd, x, y, a){
    var spr = image.sprites[spriteInd];
    var w = spr.w;
    var h = spr.h;
    ctx.setTransform(1,0,0,1,x,y); // set scale and position
    ctx.globalAlpha = a;
    ctx.drawImage(image,spr.x,spr.y,w,h,0,0,w,h); // render the subimage
}

或最简单的游戏精灵,粒子,子弹等

function drawSprite(image, spriteInd, x, y,s,r,a){
    var spr = image.sprites[spriteInd];
    var w = spr.w;
    var h = spr.h;
    ctx.setTransform(s,0,0,s,x,y); // set scale and position
    ctx.rotate(r);
    ctx.globalAlpha = a;
    ctx.drawImage(image,spr.x,spr.y,w,h,-w/2,-h/2,w,h); // render the subimage
}

如果是背景图片

function drawSprite(image){
    var s = Math.max(image.width / canvasWidth, image.height / canvasHeight); // canvasWidth and height are globals
    ctx.setTransform(s,0,0,s,0,0); // set scale and position
    ctx.globalAlpha = 1;
    ctx.drawImage(image,0,0); // render the subimage
}

通常可以缩放,平移和旋转运动场。为此,我保持了一个闭合转换状态(上面的所有全局变量都在变量和部分渲染对象上闭合)

// all coords are relative to the global transfrom
function drawGlobalSprite(image, spriteInd, x, y, cx, cy, sx, sy, r, a){
    var spr = image.sprites[spriteInd];
    var w = spr.w;
    var h = spr.h;
    // m1 to m6 are the global transform
    ctx.setTransform(m1,m2,m3,m4,m5,m6); // set playfield
    ctx.transform(sx,0,0,sy,x,y); // set scale and position
    ctx.rotate(r);
    ctx.globalAlpha = a * globalAlpha; (a real global alpha)
    ctx.drawImage(image,spr.x,spr.y,w,h,-cx,-cy,w,h); // render the subimage
}

以上所有内容与实际游戏精灵渲染的速度一样快。

一般提示

切勿使用任何矢量类型渲染方法(除非有空闲的帧时间),例如fill,stroke,filltext,arc,rect,moveTo,lineTo,因为它们会立即变慢。如果需要渲染文本,请创建一个屏幕外的画布,对其进行一次渲染,然后显示为sprite或图像。

图像大小和GPU RAM

创建内容时,请始终对图像大小使用幂规则。GPU处理大小为2的幂的图像(2,4,8,16,32,64,128 ....),因此宽度和高度必须为2的幂。即1024 x 512或2048 x 128是合适的尺寸。

当您不使用这些大小时,2D上下文将不在乎,它所做的是扩展图像以适合最接近的功率。因此,如果我有300 x 300的图像以适合GPU上的图像,则必须将图像扩展到最接近的功效,即512 x512。因此,实际的内存占用量是您能够容纳的像素的2.5倍以上显示。当GPU的本地内存用完时,它将开始从主板RAM切换内存,这时您的帧速率将下降至无法使用。

确保调整图像大小,以免浪费RAM,这意味着您可以在碰到RAM壁之前将更多的东西装入游戏中(对于较小的设备来说,这根本就不多)。

GC是主要框架

最后一项优化是确保GC(垃圾收集器)几乎没有干什么。在主循环中,避免使用new(重用和对象而不是对其进行取消引用并创建另一个对象),避免从数组中推入和弹出(保持其长度不落)保持活动项的单独计数。创建一个自定义的迭代器,并推送对项目上下文敏感的函数(知道数组项目是否处于活动状态)。推送时,除非没有不活动的项目,否则不要推送新项目;当一个项目变为不活动状态时,请将其保留在数组中,并在以后需要时使用它。

我称之为“快速堆栈”的简单策略超出了此答案的范围,但可以处理零负荷(零寿命)的零负载(短期)游戏对象。一些更好的游戏引擎使用类似的方法(提供不活动项目池的池数组)。

GC应该少于您游戏活动的5%,否则,您需要找到不必要创建和取消引用的位置。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Javascript和HTML5 Canvas Sprite

来自分类Dev

HTML5 canvas动画和旋转

来自分类Dev

HTML5 canvas动画和旋转

来自分类Dev

HTML5 Canvas重绘周期性能优化

来自分类Dev

多个html5 canvas元素:性能问题?

来自分类Dev

HTML5 Canvas垂直和水平滚动

来自分类Dev

SVG和HTML5基于Canvas的图表

来自分类Dev

Three.js和HTML5 Canvas toDataURL

来自分类Dev

html5 canvas和javascript的奇怪行为

来自分类Dev

实时预览HTML5 Canvas背景和颜色

来自分类Dev

平移,使用HTML5 Canvas和KineticJS在Android Webview上缩放性能

来自分类Dev

平底锅,使用HTML5 Canvas和KineticJS在Android Webview上缩放性能

来自分类Dev

Canvas HTML5的性能-Chrome的运行速度明显比Firefox和IE慢

来自分类Dev

HTML5 canvas javascript

来自分类Dev

HTML5 canvas javascript

来自分类Dev

实时数据绘图性能HTML5 canvas vs Dom附加

来自分类Dev

实时数据绘图性能HTML5 canvas vs Dom附加

来自分类Dev

使用jCanvas和jQuery在HTML5 Canvas中水平动画化渐变

来自分类Dev

在HTML5 canvas中,translate()和moveTo()JavaScript函数之间有什么区别?

来自分类Dev

设置背景填充,笔触和HTML5 Canvas的不透明度

来自分类Dev

html5 canvas中的OffsetX可与IE,Safari,Chrome和Firefox兼容

来自分类Dev

Javascript HTML5 Canvas Mario Bros NES克隆,碰撞和跳跃中断

来自分类Dev

使用HTML5 canvas和Javascript显示多帧dicom图像

来自分类Dev

如何使用动态图案和颜色设置Html5 Canvas FillStyle

来自分类Dev

如何获取HTML5 Canvas中绘制弧的宽度和高度?

来自分类Dev

如何使用jQuery淡入和淡出HTML5 canvas ctx对象?

来自分类Dev

HTML5 Canvas Arc的形状取决于画布的宽度和高度

来自分类Dev

HTML5 Canvas的getImageData值像素颜色闪烁白色和黑色

来自分类Dev

在Chrome和Easyljs上调整HTML5 Canvas图像的大小

Related 相关文章

  1. 1

    Javascript和HTML5 Canvas Sprite

  2. 2

    HTML5 canvas动画和旋转

  3. 3

    HTML5 canvas动画和旋转

  4. 4

    HTML5 Canvas重绘周期性能优化

  5. 5

    多个html5 canvas元素:性能问题?

  6. 6

    HTML5 Canvas垂直和水平滚动

  7. 7

    SVG和HTML5基于Canvas的图表

  8. 8

    Three.js和HTML5 Canvas toDataURL

  9. 9

    html5 canvas和javascript的奇怪行为

  10. 10

    实时预览HTML5 Canvas背景和颜色

  11. 11

    平移,使用HTML5 Canvas和KineticJS在Android Webview上缩放性能

  12. 12

    平底锅,使用HTML5 Canvas和KineticJS在Android Webview上缩放性能

  13. 13

    Canvas HTML5的性能-Chrome的运行速度明显比Firefox和IE慢

  14. 14

    HTML5 canvas javascript

  15. 15

    HTML5 canvas javascript

  16. 16

    实时数据绘图性能HTML5 canvas vs Dom附加

  17. 17

    实时数据绘图性能HTML5 canvas vs Dom附加

  18. 18

    使用jCanvas和jQuery在HTML5 Canvas中水平动画化渐变

  19. 19

    在HTML5 canvas中,translate()和moveTo()JavaScript函数之间有什么区别?

  20. 20

    设置背景填充,笔触和HTML5 Canvas的不透明度

  21. 21

    html5 canvas中的OffsetX可与IE,Safari,Chrome和Firefox兼容

  22. 22

    Javascript HTML5 Canvas Mario Bros NES克隆,碰撞和跳跃中断

  23. 23

    使用HTML5 canvas和Javascript显示多帧dicom图像

  24. 24

    如何使用动态图案和颜色设置Html5 Canvas FillStyle

  25. 25

    如何获取HTML5 Canvas中绘制弧的宽度和高度?

  26. 26

    如何使用jQuery淡入和淡出HTML5 canvas ctx对象?

  27. 27

    HTML5 Canvas Arc的形状取决于画布的宽度和高度

  28. 28

    HTML5 Canvas的getImageData值像素颜色闪烁白色和黑色

  29. 29

    在Chrome和Easyljs上调整HTML5 Canvas图像的大小

热门标签

归档