• Unity
  • two texture is batch bug

spine-unity-3_7-2019-02-26
Unity5.6.0f

Related Discussions
...

When you have two textures with only spineboy's neck in the 2nd texture, rendering each spineboy does this:

render regions from 1st texture
<flush the batch>
render the neck region from 2nd texture
<flush the batch>
render regions from 1st texture

It is not clear whether the batch is flushed at the end of those actions. If so, that would be 3 batches per spineboy * 4 spineboys = 12 batches. Maybe Harri can likely shed some light on why it doesn't seem to be batching across skeletons.

It is also not clear to me why your single atlas page screenshot is showing two batches. Ideally it would batch all 4 spineboys with 1 batch.

Thank you for recording the video!

Actually it should be batching the 4 skeletons sharing the same single atlas to a single drawcall, it does that in Unity 2018:

Unfortunately the same mesh causes 2 drawcalls in Unity 5.6.x and 2017 - so upgrading to Unity 2018 would remove this unnecessary drawcall.

In general Unity does not batch meshes with more than 900 vertices (see documentation page here), but this is not the problem here.

I noticed the Atlas not set for SkeletonData Asset error messages here:
Spine Two Material Test - YouTube
This should not happen. Do you always encounter this error message when importing Spine assets? If yes, could you please create a zip package of your Spine project files and email it to contact@esotericsoftware.com? Then we can have a look at it.

SpineProject + 256(2Texture) + Unity3d 560
SpineProject + 512(1Texture) + Unity3d 560

File >>>>
SpineTest.zip

Test result.... (566 : Unity3d 566, 2018 : Unity3d 2018.5)

2 Texture 566 : Batches 18
2 Texture 2018 : Batches 17

1 Texture 566 : Batches 2
1 Texture 2018 : Batches 1

Your example shows the same behaviour pointed out by Nate above:

When you have two textures with only spineboy's neck in the 2nd texture, rendering each spineboy does this:
render regions from 1st texture
<flush the batch>
render the neck region from 2nd texture
<flush the batch>
render regions from 1st texture
It is not clear whether the batch is flushed at the end of those actions. If so, that would be 3 batches per spineboy * 4 spineboys = 12 batches.

In your case you now have two atlases with a high number of items in the second one, instead of only the neck image as above. This creates 9 batches at a single Spineboy already, because everything needs to be in correct draw order, making many material switches necessary:

With 4 Spineboys it is at least sharing some drawcalls, ending up at 17 batches:

Maybe Harri can likely shed some light on why it doesn't seem to be batching across skeletons.

In the last screenshot we see that in Unity 2018 batching actually works across the four skeletons - so it's at least reduced to 17 instead of 9 batches per spineboy * 4 = 36 batches.

We would strongly suggest having a single atlas page instead of two small ones.
In case you really have to use two atlas pages, you can use subfolders to determine which texture goes into which atlas page.

Please note that everything above is working as expected. When your atlas has multiple textures, Unity has to switch between the textures to draw the various regions and the number of draw calls can be high. If you want to avoid this then it is most efficient to use a single texture. If you can't do that, then you can use subfolders to control which images are packed to the same atlas page. Arrange your images based on the most common draw orders for your skeletons to minimize texture switches. For example, the first half the attachments (based on draw order) on one atlas page and the rest on the other.

If you want to get really fancy, you can consider not preparing an atlas beforehand. Instead, you determine only the images needed for your skeleton for the current room/level/whatever and pack an atlas at runtime containing only those images. This way you have only a single texture but retain the flexibility of having any number of images. However, it's a much more complex solution to develop.

kyssmart wrote

The same phenomenon occurs when using attachments.

AtlasRegionAttacher is Test

Please note that this is not the same phenomenon - in the above case it is material instances that are being created, as I mentioned in the other thread.

The behaviour you described in the current thread is as expected, and as Nate described, you can assign images to the atlas pages to save the drawcalls you unnecessarily created.

I need to create a game with many items and replace it.
Loading a lot of files individually will slow down loading.
With Atlas, loading is fast and replacement is fast.
So I'm looking for a way.

Can I request a sample project?
:mail: kyssmart @ naver. com
(If you write your e-mail address, it will be erased.)

5 days later

We have an example scene on our roadmap which shall demonstrates the usage of lots of equipable items in large atlases. We will let you know as soon as this example scene is done and included in the Spine Unity Runtime.

For now we can only recommend you to create the atlases based on draw-order, as Nate descibed above:

If you want to avoid this then it is most efficient to use a single texture. If you can't do that, then you can use subfolders to control which images are packed to the same atlas page. Arrange your images based on the most common draw orders for your skeletons to minimize texture switches. For example, the first half the attachments (based on draw order) on one atlas page and the rest on the other.

If you create one atlas with your character's parts that are in the back (e.g. the character's half-naked parts with underwear on) and one or more atlases with parts in the fromt such as equipable items (e.g. armour, boots, gloves, etc), then your setup should be good in terms of drawcalls, as it does not need to switch atlases too often.

What would be bad atlas grouping is the one that you encountered above, by having parts from back to front draw order in different atlases all the time.

So as an example, when we have a caracter with front items [f1]-[f3] and back items [b1]-[b3] viewed from a camera:
camera


character
<)


[f1][f2][f3] [b1][b2][b3]
This would be good atlas grouping:

  • BackAtlas with image items





[b1][b2][b3]

  • FrontAtlas with image items [f1][f2][f3]





This would be bad atlas grouping:

  • MixedAtlas1 with image items [b1]

[b3]


[f2]


  • MixedAtlas2 with image items

[b2]


[f1]


[f3]