Performance and Mesh.CreateVBO on iPad

On scenes with lots of geometry rendered with Transparent/Diffuse shader, performance drops badly when deployed to iPad1 (iPad2 is fine). The profiler shows that 80% of the time is going into Mesh.CreateVBO(). Here what the profiler shows:

When the same geometry is opaque then everything is wicked fast.

I’m not surprised that transparent objects will render slower and have some overhead, but 80% of all time going into creating VBO’s is surprising and the fact that VBO’s seem to be getting recreated on every frame is surprising (this is a static mesh with nothing changing - no changes to its data and it is not moving or transforming at all). Does anyone know what Unity is actually doing here? When and why does it decide to create vbo’s and what can we do to minimize it?

Thanks in advance for any tips anyone might have!

Unusual. Would like to know more.

Are you actually scaling them at any time? This causes a CPU hit if the scale is non uniform for any reason.

Bump.

I am experiencing the exact same problem. Anyone has an explanation on why is this happening and how to optimize ?
Claytonious did you finally find a solution ?

i remember seeing bug related to this but i don’t remember what was the outcome. So, can you submit bug report with simple repro and drop me case number?

Bug report with sample project submitted. The case number is 420513.
Thanks a lot for helping Alexey.

i wasn’t able it to repro it on ipad1 on latest unity codebase
So most probably it means that this is gonna be fixed in 3.5 :wink:

Well, good news! Thanks.
Side question: any idea when Unity 3.5 will be out? :slight_smile:

Bump. I’m seeing this too. Is there a suggested workaround, or is it fixed in 3.4.1 (I’m still on 3.4.0)? When will 3.5 be out?

well, i don’t know at what we are looking so i can’t propose a workaround (and not - this info is not enough)
One more note though - during unite i was helping guys with performance and we found pretty bad stuff about SpriteManager2 or EZGui or something (can’t remember)
The idea is - when you change scale to non-uniform mesh would be recreated. And that was the case with sprite animation in there. So watch your back

Thanks. Do you mean that it’s bad to have a non-uniform scale even if you never dynamically change the scale (i.e. if you set the scale once in Unity but not at runtime)? I would have thought that you could have a non-uniform scale, but if you never modify it at runtime the mesh shouldn’t need to be recreated constantly.

Is there a way to find out what is causing the VBO to be recreated? All I see in the profiler is the call to CreateVBO. Is it just a case of turning stuff off until I find the offending object?

Yeah the EZGUI scroll list when set to clip is pretty performance intensive. I’m using it for some scrolling marquee text but I don’t think it’s really designed for that; it clips every individual character that is outside of the scroll area.

Also why does it need to recreate VBOs when scaling at all, ever? Why can’t it just apply the transform to the incoming vertex in the vertex shader?

Ok so I finally dug up a post on unity answers that says that unity scales vertices on the cpu if using non-uniform scaling, which I guess is what you were telling me. This seems incredibly dumb to me, but I assume it’s because your physics engine doesn’t handle non-uniform scaling, which is fair enough since you can do a lot of optimisations. Except in my case I don’t have any collision on this object, so it seems pretty lame that it is rebuilding the VBO every frame. Anyway I’ve written a custom shader that lets me specify the scale as a shader property, and that has fixed the issue. The only unfortunate thing now is that Unity seems to have a problem applying the vertex shader in the editor; my object appears at its original size and is also rendered with the vertex shader applied. Oh well!

I’m having the same issue. I’m using Sprite Manager 2 and am getting massive CreateVBO spikes which sometimes take up to 7ms. It’s usually only one or two of them, but at a total of 16ms it really kills the otherwise smooth 60FPS I’m getting. I’ve seen the problem on every iOS device I’ve tested on (3Gs, iPad 1, iPod v4)

I noticed somebody made a comment on how it has something to do with the way the openGL buffers are defined, as DYNAMIC rather than STATIC or something of the sort.

EDIT: http://forum.anbsoft.com/viewtopic.php?f=7&t=2369

I disabled game objects one by one to narrow down which one(s) was/were causing the problem. It seems that just scaling the object once in Unity (not even every frame) causes it to re-create the VBOs.

You mean it re-creates the VBO every frame, even if you only scaled it once? submit a bug report, this is TERRIBLE behaviour.

that sounds very weird - should not happen

In my case, it turned out to be caused by a dynamic mesh that I had in the scene - it was a small mesh (< 200 vertices) that I was using for a GUI layer. I was setting the positions of the vertices every frame so that the GUI stayed positioned in front of the camera and was all drawn in a single draw call.

So Unity was creating a new VBO for this mesh every frame and even though the mesh was tiny this was hurting performance noticeably as the profiler showed.

I tried turning off the MeshRenderer component and instead calling Graphics.DrawMesh directly. No difference. Then I tried calling DrawMeshNow in OnPostRender from a camera. Still no difference - create vbo every single frame. Finally, I used the GL class to directly render myself from OnPostRender. This fixed the issue for me. No more expensive CreateVBO every frame and my framerate improved dramatically.

Obviously, having to do you own direct GL calls just to avoid expensive CreateVBO is probably not intended and hopefully in 3.5 this will be an unnecessary optimization. But I’m sticking with this solution for now!

hopefully it’ll get fixed in 3.5 since that would kind of make ios cry.

Could you share exactly how you did this? I use a large number of custom meshes as well, and I’d be interested to see how you actually do the direct GL calls.