Thanks, I'll give this a read through and show it to the artists as well!
Harald What does the current list of materials at your skeleton look like in the Inspector, do you only see two materials alternating many times, or do you see many different materials (e.g. because you're using blend modes at certain slots and slot material overrides)? In any case, grouping attachments (ordering them so that they are in sequence in the draw order) that require the same material would "fuse" two or more draw calls to a single one.
I see the same two materials alternating back and fourth 29 times, which is why I had assumed that this could be part of the issue and that "fusing" these 29 draw calls into 2 or 3 I'd think would get us closer to the 50 FPS with all three skeletons rendering. We also aren't doing any type of blending or anything with these spines, just the "Normal" blending mode.
I can try that out when we start using the skins we've implemented in this test scene, but right now I have only applied a single skin through the SkeletonAnimation inspector window. (I might be doing something wrong too, because a very quick test I threw together to test the Runtime Repacking feature gave me a malformed atlas and several errors in the Console window with the following format:
Graphics.CopyTexture called with region not fitting in source element: trying to copy from region (x:2218, y:1147, width:194, height:136) of mip 0 (size: 2048x2048)
I did set those textures to Read/Write
as well, and it didn't improve the situation there.
The script I used for this test was mostly CnP from your Spine Examples for Mix and Match, but here it is anyways in case you spot something I'm doing entirely wrong. My biggest guess as to what I'm doing wrong is that I'm using the wrong material, since the skeleton uses two materials (alternating back and forth 29 times as I mentioned earlier).
using UnityEngine;
using Spine.Unity;
using Spine.Unity.AttachmentTools;
public class DummyRepacker : MonoBehaviour
{
public SkeletonAnimation Skeleton;
public Texture2D runtimeAtlas;
public Material runtimeMaterial;
void Start()
{
// Create a repacked skin.
Spine.Skin repackedSkin = new Spine.Skin("repacked skin");
Spine.Skin skin = Skeleton.skeleton.Data.FindSkin("male");
repackedSkin.AddSkin(skin);
skin = Skeleton.skeleton.Data.FindSkin("male_head_1");
repackedSkin.AddSkin(skin);
repackedSkin = repackedSkin.GetRepackedSkin("repacked skin", Skeleton.SkeletonDataAsset.atlasAssets[0].PrimaryMaterial, out runtimeMaterial, out runtimeAtlas);
Skeleton.skeleton.SetSkin(repackedSkin);
// Use the repacked skin.
Skeleton.Skeleton.Skin = repackedSkin;
Skeleton.Skeleton.SetSlotsToSetupPose();
Skeleton.AnimationState.Apply(Skeleton.Skeleton); // skeletonMecanim.Update() for SkeletonMecanim
// You can optionally clear the cache after multiple repack operations.
AtlasUtilities.ClearCache();
Resources.UnloadUnusedAssets();
}
}
Harald That's strange indeed. You could do a test in the Unity Editor and watch the Game view while going back and forth in the draw-call-timeline at the top of the screenshot, then you should see when the crowd appears in the list of draw calls. If the list is completely different, that won't help of course..
Sorry about that, it was just my misunderstanding of how the Frame Debugger is displayed. With both the Crowd and the Scam Caller they get properly rendered with SRP Batch in two draw calls, and if I disable one or the other I see a single draw call in SRP Batch now. So it's only the player spine that isn't getting properly batched, even with OpenGLES3 enabled.
Harald Ok, that at least saves compile time for diffent builds when testing then 🙂. A quick guess it that it could be because it's GPU limited and any optimizations would mainly affect performance on the CPU side. Anyway, that's just speculations of course. 🙂
Actually that makes a lot of sense, I hadn't thought of that. Because the CPU isn't being hit almost at all with these test I'm running, everything is GPU bound. I'm sure that the Unity Profiler doesn't use hardly any GPU bandwidth at all, and likely just eats up CPU Usage instead.