hippocoder

  • 20 nov. 2018
  • Inscrit 11 mai 2013
  • You can't rely on .colors array being the same size as the verts array. You have to push the size of the verts array into the colors array to make them match. Is that the problem being experienced here?

  • I think Nate should do a poll on which runtimes need their own forum, probably will end up looking like:

    Cocos
    Unity
    Generic C++
    Generic C#
    Other

    I guess? Especially as now there's probably going to be a fair few runtimes tweaks that users submit.

  • If you can go to settings, you can select a version you prefer to use instead of "latest" - that should do the trick.

  • The texture packer may be a little buggy right now and the developer is away 2 weeks on honeymoon. So what you could do in the meantime is use smaller images - this is likely the reason most texture packing code will fail - it runs out of space.

    For now, try it with smaller images or use an external program to pack the textures. It's not an ideal situation but I can't see what else you can do in the meantime while waiting.

  • Congrats nate! I'm sure programmers round here will fill in.

  • His problem is he's messing around with different resolution source assets... don't think spine is the problem.

  • http://docs.unity3d.com/Documentation/S ... ounds.html

    This is a slow process and it's not actually needed if triangles are set. You could add it as a tickbox to do it every frame for problematic weird corner cases like this (someone animating something far off screen to come down on screen etc). Although I can't see why that would still be an issue tbh.

  • It may be an optimisation if users use spine throughout a large rayman style level where it's still calculating stuff off screen. In cases like this, people need to learn to cull and I'm certainly not going to be asking you to program our games for us 😃 Yes it's faster, but I doubt it's faster in most real world cases (unless targeting the lower end of mobile).

    But if you have a lot of elements spread out through the level it will be faster not also set color. But then, people perhaps should be culling regardless.

  • I feel the current code is pretty efficient. Is there a bottleneck we can identify and changes we can make that improve that bottleneck?

    Definitely avoiding submitting triangles unless the topology changed, that should speed it up (along with only submitting colour on change, or submitting colour in colors32 format, which avoids the internal unity conversion for each color (it converts from 0..1 to 0..255 or such, 4 floats at a time plus overhead per vert). When you've 300 verts on screen thats 1200 needless calculations + overhead.

    That's just 10 objects with 30 verts each - sounds trivial but it's doing a LOT that it doesn't have to.

    http://docs.unity3d.com/Documentation/S ... ors32.html

    Same as colors, except using Color32 structure which is better for performance.

    1. avoid submitting triangles at all unless topology changes (this is the most expensive operation, as each triangle has to be fed through unity's pipeline so its better not to do it unless you have to)

    2. avoid submitting colors at all second most expensive thing to do - (4 times more expensive than submitting verts regardless of optimised version in link above). I know you said you wouldn't know if someone changed it or you, but I think you would, as they'd have to go through your api anyway.

    For a few models this is never expensive, but being the fastest doesn't have to take too much time. It's probably a bit of an anxiety attack not knowing unity well and having so much work to do, but these changes are pretty much all you need to do.

    (Along with having an option to generate normals and tangents (both optional) on a skeleton so that those guys doing lit cool looking stuff can show off spine even more without having to give the source a good kicking).

    These changes sound minor, but they're really not. When you consider most of the time, sprites will all be on different frames, doing different things in a real world game, the savings on average add up really quickly. You could be doing a quarter of the cpu hog 🙂

    I'm not in a rush for these optimisations, but they'll serve as a good point of reference if you need them 🙂

  • Hey nate! welcome back as well. Thanks for the reply. Regarding mesh stuff, it's probably going to be only a minor change on your part to not resubmit each part of the mesh and have a small bool. For example if there's been no actual changes from the last frame in the quads, you could just submit .vertices, and if there's been a vert colour change, just submit .colors... triangles and = new Mesh are a last resort (as is making a new mesh) in unity. It's a pretty hefty hit (I presume due to the way unity works internally, with shaders, materials, batching, 3D stuff, sorting and so forth).

    Those are minor easy changes you can make which will really reduce how much time unity spends internally with it's above nonsense + scenegraph stuff.

    For 4+ it's also recommended in addition to the above tips of not making a new mesh every frame, you use http://docs.unity3d.com/Documentation/S ... namic.html - MarkDynamic - which helps unity's overhead to remain as small as possible. If it only unity was a simple as the other platforms!

  • Hiya,

    Would it be a good idea to have cell sheets generated? you specify how big the sprite should be rendered and how many frames each anim will use and it figures out the texture size for a square texture and shoves it onto a sprite sheet....

    or just outputs individual frames for that criteria, would help all those people who don't want or can't use a runtime (maybe for performance or a niche thing like game salad for instance).

  • Thanks Nate!

    I guess I will just have to live with breaking batching and try to minimise it happening because we usually like to scale our sprites in game a lot, for subtle effects such as squashing them and so on (see mario wii)... We will just have to refactor the code our end.

  • Scaling the container in unity breaks batching, though which leads to lower performance (unity will cause another draw call if any elements are a different size as it is a 3D engine, and needs to do so in order to keep lighting correct).

    Does anyone have any code to reliably scale a spine model without breaking batching (I mean the entire thing, rather than just one part) ?

  • I don't really dig sm, I think it's got it's own set of wonderful bugs, and I don't think using skinned meshes provides the right kind of overall performance. I mean, if you wanted a lot of them, you need to jump through hoops and have 1 skinned mesh renderer for a lot of skinned meshes ie 1 mesh but lots of sub animations. That still gets your 1 draw call, but its horrible to work with and not worth it. As small indie developers, a decent workflow is that much more important.

  • Pharan a écrit

    but on the other hand you get one draw call per mesh.

    I'm not sure you get one draw call per mesh in the one-object-per-quad setup. Unity does dynamic batching. Try making several copies of one spine skeleton in a scene. Unity seems to batch their separate meshes as one draw call as long as they share a material.

    criteria for it: http://docs.unity3d.com/Documentation/M ... ching.html
    The per-vertex overhead is interesting though. That's probably the thing to watch.

    Anyway, a one-object-per-quad setup isn't a clear winner.

    I don't think you understood me. Spine creates one mesh, which is dynamically batched. Smooth Moves creates one SKINNED MESH which cannot be dynamically batched. Which is why you get one draw call per mesh with SM. However, you can sidestep this by creating many animated objects within a single skinned mesh, which will always force a single draw call. Back in 2011 we exploited this in Physynth, reducing 70 draw calls to 1 draw call. It was of course, much faster.

    This has nothing to do with dynamic batching and I've never ever implied anything to do with one gameobject per mesh. Here's the quote again:

    Regarding the speed of Smooth Moves, that uses unity skinned mesh, its a lazy man's solution to the problem by not doing the maths in unity, that has pros and cons. On one hand you get much higher performance as your bone complexity rises, but on the other hand you get one draw call per mesh.

    I should make the last bit read per SKINNED mesh, but I felt it was ok in context.

  • Shiu a écrit

    Hey just wanted to tell you that Nate is currently in Turkey which is why there has been no reply and personally I don't know enough about the coding aspects to be of any assistance. Nate will be back in a couple of days.

    Ah good to know. I hope things are OK in Turkey with the current events being what they are.

  • Garbage collection hit:

    AnimationStateData.cs - GetMix

    		public float GetMix (Animation from, Animation to) {
    			KeyValuePair<Animation, Animation> key = new KeyValuePair<Animation, Animation>(from, to);
    			float duration;
    			animationToMixTime.TryGetValue(key, out duration);
    			return duration;
    		}

    Causes garbage collection and adds up quickly, if you change animations a lot - say 25 ai creatures running around, builds up on mobile for stutter. Probably not necessary to create new data at any point during an animation as you already know ahead of time. A fixed dictionary or pool would be best here for anims which change a lot. Eliminating GC is one of the main points about unity asset store / middleware stuff. Creating new items during gameplay is bad for mono's terrible garbage collector used in unity.

  • Hiya,

    Thanks for the heads up, Pharan, it's good to know that the runtimes will be changing soon. These do need the optimisations I hinted at above. Changing material each frame is an overhead that's not needed. The ipad1 is particularly well-suited to handle Spine, more so than the iPhone4, and of course obliterates the 3GS. It also depends on bone count and number of keyframes. 40 is the same as 5 complex models as far as Spine's concerned.

    In a demo, Spine's performance is good enough. In a full game with everything else running, it's a different story. On multi-core devices, unity's skinned mesh will be quicker.

    Regarding the speed of Smooth Moves, that uses unity skinned mesh, its a lazy man's solution to the problem by not doing the maths in unity, that has pros and cons. On one hand you get much higher performance as your bone complexity rises, but on the other hand you get one draw call per mesh. I think with a couple of optimisations there will be no places where Smooth Moves actually beats out a tight optimised approach in Spine and that is what we all want.

    What I want to know is my options in helping Nate, because I like him and I love their product.

    While we are at it, shouldn't most runtimes have optional normal/tangents for those using normal mapped sprites / or hardware lighting?