GAF / DragonBones / Spine / Spriter in Openfl

10 dragons:

  • WebGL ~20fps
  • Canvas ~7fps

Well, wait wait wait, this example is pretty different from the first one we tested :crazy_face:

The first test we made was using the classic dragon-with-shirt gfx, that uses 1 or no meshes at all, if I’m not wrong: when I say that Canvas is faster than WebGL I am referring to that, we will redo a test with that gfx, sorry for the mistake.

Perhaps we could double check if it was really using hardware rendering. WebGL (which runs through the software path) will be slower than plain canvas (which is always software)

New test with the classic dragon-with-shirt.
The test is based on the same animation in 2 versions, one with no meshes and one with a very simple animated mesh applied to the horns.

Note, in the previous post with the screenshot of the other dragon I said that in canvas there were some glitches on the meshes, but not in the WebGL version: in this test the glitches appear in the WebGL version too.

image

The results with 28 dragons are:

  • WebGL no mesh: ~31fps
  • WebGL mesh: ~12fps
  • Canvas no mesh ~45fps
  • Canvas mesh ~13fps

With a small mesh or without any, Canvas wins!

I would like to test the fps of Spriter with the same animation. Can you send me your dragonbones animation so I could adapt it to Spriter and evaluate the amount of fps so we could compare.

Ok, I’ll send it through mail.

thanks I’ll try this week!

What the heck…?! Mesh deformations work in openfl-spine too?!
It works pretty good in WebGL, better than DragonBones, apparantly, but in canvas it explodes.

WebGL

and Canvas

Obviously it is only usable in WebGL, an annoying restriction :roll_eyes:

Hello,

Hey, here are some feedbacks on the code you sent to me:

  1. Don’t recreate all your dragons when you add only one (save 50Mo of RAM and have 10 more fps for same amount of dragons : 31) => if you removeChild, try to destroy all the data of the removed animation
  2. Don’t cacheAsBitmap your animation. (can have 27 fps more for 31 dragons)

Both optimisation lead to x2.2 dragons at 30 fps.

I’ve tested on WebGL but I don’t know if the code you sent to me uses mesh or not.

EDIT : it’s definitely “no mesh”.
EDIT 2: I’ve just tried the “mesh” and it still really bad.

I’ve checked the code of dragonBones and it seems that every part of the animation is rendered in a Shape, so there is no batch in dragonBones. The dragon animation has 19 Shapes.

DragonBones could benefits using Tilemap (but it doesn’t support mesh) or a custom rendering that supports Mesh and batching.

Yes, tilemap meshes would be great, as we could animate dozens items at once without slowdowns, and it would/will be an incredible step forward for the Openfl community.

The current renderer is useful for 1-2 big characters/items on screen, but as a simple warmup for the future evolutions of the library anyway.

The Openfl renderer of dragonbones apparently suffers of “rounding”.
This is how the original animation looks in the DragonBones editor

egret

and this is how it looks when inserted in an executable

openfl

I searched for Math.round or similar, but couldn’t find anything.

Hi. The problem is that DragonBones uses sprite.graphics to render anything. But graphics in OpenFL has some sort of “crisp filtering”, look at openfl.display.graphics (my version OpenFL is 8.9.1, unfortunately my projects refuse to work on later versions at this moment). There is a code:

// Floor the world position for crisp graphics rendering
__worldTransform.tx = Math.ffloor(tx);
__worldTransform.ty = Math.ffloor(ty);

// Offset the rendering with the subpixel offset removed by Math.floor above
__renderTransform.tx = __worldTransform.__transformInverseX(tx, ty);
__renderTransform.ty = __worldTransform.__transformInverseY(tx, ty);

There is a “rounding”. Try to change it to

// Floor the world position for crisp graphics rendering
__worldTransform.tx = tx;// Math.ffloor(tx);
__worldTransform.ty = ty;// Math.ffloor(ty);

// Offset the rendering with the subpixel offset removed by Math.floor above
__renderTransform.tx = 0;// __worldTransform.__transformInverseX(tx, ty);
__renderTransform.ty = 0;// __worldTransform.__transformInverseY(tx, ty);

and moving of bones should be much smoother.
Of course, it’s not the best way to solve the problem, but you can try to write a hack to disable this “filtering” only for DragonBones (something like sprite.graphics.crispFilter = false), or maybe it will be OK for you to use canvas always without “crisp filter”…
Obviously, the best solution would be to not use the sprite.graphics in DragonBones (and sprites at all), it is not right way of render :frowning: But it would not be easy to make it work with Tilemap or somethink like this… :frowning:

This fixes the problem, thanks.
I noticed that normally the coordinates are already ALL integers, so these operations are totally useless: commenting them by default would simply increase performance.

Maybe I am used to round everything when possible (e.g.: with .snapping() in Actuate) and I don’t need these hidden operations at all.

Now that I know about it I am wondering why it is active by default, I’d like to set it by myself in some way, but not through an hack.