Search Unity

Huge performance loss in Mesh.CreateVBO for dynamic meshes [ IOS ]

Discussion in 'iOS and tvOS' started by TrialByFun, Jan 9, 2012.

  1. TrialByFun

    TrialByFun

    Joined:
    Jun 23, 2009
    Posts:
    96
    This is a follow on from a problem noticed in unity 3.4 which I thought might be fixed in 3.5 as there is this build note

    "Optimizations for OpenGL ES 2.0 to avoid performance spikes with dynamic geometry"

    A thread talking about a user fix for the problem 3.4 is here ;
    THREAD


    To be fair the performance spiking (as it was before) is gone but Mesh.CreateVBO is still appearing and taking a large amount of frame time. Leaving the only option to continue implementing one of the solutions noted in the linked thread.


    For a visual comparison here is the profiler scene [ iPod 4, IOS5 ] with a number of dynamic meshes updated every frame.
    Make sure to note the scale of the graphs.

    Ping ponging between two meshes that are updated every frame (i.e double buffering)


    Single Mesh updated every frame


    CPU changes from 9ms to 17ms and the overall render time increases dramatically. Digging down we can see that MeshDrawVBO remains mostly the same (as expected) but Mesh.CreateVBO goes from 0.39ms to 8.75ms ( Ping Pong method to Single ) which is a huge performance loss per frame.

    Would this be classed as a bug?
    Or should it simply be a user note that if you want to change a dynamic mesh every frame you need to double buffer it yourself?

    Many Thanks,
    Steven
     
  2. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,354
    Looks like a genuine problem from my point of view.
     
  3. gametr4x

    gametr4x

    Joined:
    Apr 22, 2009
    Posts:
    83
    I'm having this problem as well, but I'm not sure I understand how to ping-pong between two meshes. Could you elaborate how you did this?
     
  4. TrialByFun

    TrialByFun

    Joined:
    Jun 23, 2009
    Posts:
    96
    In your awake() or start() function create two empty meshes.

    meshA and meshB
    don't assign anything to the meshFilter yet.

    At the end of each frame ( end of update in a script for example ) assign a different one of the meshes to the mesh filter like so.

    bool on = true;
    void Update()
    {
    /////
    //// Update your meshes here
    ////

    // Alternate between which mesh you're using
    if( on )
    {
    meshFilter.sharedMesh = meshA;
    on = false;
    }
    else
    {
    meshFilter.sharedMesh = meshB;
    on = true;
    }
    }

    Thats literally the only different between those two profiler stats.
    The first one flips between two meshes like above, the second one only uses meshA with no flipping.
     
  5. wightwhale

    wightwhale

    Joined:
    Jul 28, 2011
    Posts:
    388
    Still not working for me :/ I'm wondering what you do in this section


    /////
    //// Update your meshes here
    ////
     
  6. gametr4x

    gametr4x

    Joined:
    Apr 22, 2009
    Posts:
    83
    It works perfectly for me. I'm doing a ping-pong between two meshes for each mesh that is updated frequently. I use SpriteManager 2, so I changed it in the core of that system to make it easy to use. I did a couple of things:

    - Add a second Mesh instance to SpriteMesh that gets created in tandem with the original, and a bool "ping" to check which is currently being used
    - Add a "dynamic" bool to ISpriteMesh interface, and also add it to the PackedSprite Sprite classes, which then transfers it to its child SpriteMesh instance
    - Added an "isDirty" bool to ISpriteMesh that is set whenever you would have changed set any mesh data (and commented those lines of code)
    - Created a class that keeps a List of dynamic SpriteMesh instances, and updates them in a loop during its LateUpdate function

    The actual updating of the SpriteMesh looks like this:

    Code (csharp):
    1.  
    2.         public void UpdateMesh()
    3.     {
    4.         if ( m_mesh == null || m_secondMesh == null )
    5.         {
    6.             SpriteMeshListener.Unregister( this );
    7.             return;
    8.         }
    9.        
    10.         if ( ping )
    11.         {
    12.             m_secondMesh.vertices = m_vertices;
    13.             if ( m_useUV2 )
    14.                 m_secondMesh.uv = m_uvs2;
    15.             else
    16.                 m_secondMesh.uv = m_uvs;
    17.             m_secondMesh.colors = m_colors;
    18.             m_secondMesh.triangles = m_faces;
    19.             m_secondMesh.RecalculateBounds();
    20.             #if SPRITE_WANT_NORMALS
    21.                 m_secondMesh.RecalculateNormals();
    22.             #endif
    23.            
    24.             meshFilter.mesh = m_secondMesh;
    25.        
    26.             ping = false;
    27.         }
    28.         else
    29.         {
    30.             m_mesh.vertices = m_vertices;
    31.             if ( m_useUV2 )
    32.                 m_mesh.uv = m_uvs2;
    33.             else
    34.                 m_mesh.uv = m_uvs;
    35.             m_mesh.colors = m_colors;
    36.             m_mesh.triangles = m_faces;
    37.             m_mesh.RecalculateBounds();
    38.             #if SPRITE_WANT_NORMALS
    39.                 m_mesh.RecalculateNormals();
    40.             #endif
    41.            
    42.             meshFilter.mesh = m_mesh;
    43.            
    44.             ping = true;
    45.         }
    46.        
    47.         isDirty = false;
    48.     }
    49.  
    Note that when a SpriteMesh instance is NOT dynamic, I simply call the UpdateMesh function directly when I would have otherwise set the isDirty flag.
     
  7. nsxdavid

    nsxdavid

    Joined:
    Apr 6, 2009
    Posts:
    291
    This affect iOS only or does Android also see this sort of problem?

    David
     
  8. ArenMook

    ArenMook

    Joined:
    Oct 20, 2010
    Posts:
    1,902
    Can someone confirm that this was fixed in 3.5.2?
     
  9. daveUnit9

    daveUnit9

    Joined:
    Apr 1, 2010
    Posts:
    8
    Still an issue in 3.5.1 (is there a beta of 3.5.2 or something?). I've just hacked my SpriteManager to double buffer meshes and it has made a difference, but still not perfect.
     
  10. TrialByFun

    TrialByFun

    Joined:
    Jun 23, 2009
    Posts:
    96
    3.5.2 has just been publicly released with this in the build notes;

    "iOS: Fixed dynamic geometry performance regression in 3.5/3.5.1."

    Hopefully that's a yes, but I haven't done a test yet. If anyone else has a go first please post results.
     
  11. TrialByFun

    TrialByFun

    Joined:
    Jun 23, 2009
    Posts:
    96
    Okay, my results are in....

    Slow vertex color submission :Not Fixed
    Mesh.CreateVBO :Not Fixed

    So I believe the double buffer trick is still the fastest way to render dynamic geometry. Sorry guys. I have a sad face too.

    For reference my test is to allocate fixed arrays at startup for 100 quads ( 400 verts, 400 uv0,400 uv1, 400 colors )
    Length of arrays does not change ever after startup.

    -Each frame change the positions of all the quads ( vertices ) and values of the colors.
    -Perform the same operation as above but ping pong between two meshes
    -On top of these two tests, alternate between the different vertex colour submission techniques ( Color vs Tangent ) to see what difference that makes

    Here is my results [ iPod 4 3rd generation ]




    9ms normal. 0.4ms with double buffer

    Its only 400 verts too, this must be killing NGUI, EZGUI, QuadUI, 2Dtoolkit guys right?
     
    Last edited: Jun 30, 2012
  12. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,354
    That's right. What's going on?
     
  13. ArenMook

    ArenMook

    Joined:
    Oct 20, 2010
    Posts:
    1,902
    Have you tried simply setting meshFilter.mesh = null before changing the mesh?
     
  14. TrialByFun

    TrialByFun

    Joined:
    Jun 23, 2009
    Posts:
    96
    Just tried what you suggested on meshFilter.sharedMesh = null, and then tried again on meshFilter.mesh = null but It didn't make a difference.

    Are you having different results?
     
  15. ArenMook

    ArenMook

    Joined:
    Oct 20, 2010
    Posts:
    1,902
    I can't test iOS, so can't say. I was just curious if de-referencing the mesh would fix it. I guess not! I'll have to tweak NGUI.
     
  16. ArenMook

    ArenMook

    Joined:
    Oct 20, 2010
    Posts:
    1,902
    Another question... I noticed in the code posted above the mesh is never cleared: http://unity3d.com/support/documentation/ScriptReference/Mesh.Clear

    It specifically states that you should call that function before rebuilding the array. Would adding that function fix the issues? I'm doing that in NGUI, but without a way to test it it makes it difficult to tell if it helps or not.
     
  17. TrialByFun

    TrialByFun

    Joined:
    Jun 23, 2009
    Posts:
    96
    That's only true for rebuilding the whole object to prevent a mismatch of triangle versus vertex data. Resubmitting the triangle array every frame is super bad for performance, you ideally want to never change this ( or rarely change it ) after initialisation. Definitely not every frame.

    http://unity3d.com/support/documentation/ScriptReference/Mesh.html

    Unitys own example for modifying vertex attributes every frame shows you are not required to call clear (example 2),only doing so if triangle ( or vertex count ) changes.
     
  18. ArenMook

    ArenMook

    Joined:
    Oct 20, 2010
    Posts:
    1,902
    From the hardware perspective there is no reason why assigning indices would be slow at all. Sure, setting less data would result in better performance, but nothing that would be classified as "super bad".

    I wonder if Unity does this check every time you set the vertex array...

    Out of curiosity though, have you tried doing a clear first and setting indices at the end? What performance effect does it have in reality?
     
  19. ArenMook

    ArenMook

    Joined:
    Oct 20, 2010
    Posts:
    1,902
    Curious, I just gave it a try with a PC build. Frame time dropped from 0.85 to 0.59 by not setting the index buffer. I guess it does affect Unity in a bad way... thanks for the tip!
     
  20. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,603
    It doesn't need to. The mesh index arrays are all properties (not fields actually) and it can mark them as dirty for rebuild immediately without checking so they can be updated at the end of the frame.
     
  21. TrialByFun

    TrialByFun

    Joined:
    Jun 23, 2009
    Posts:
    96
    Yeah It's going to be a small saving everywhere ( doing less work is always better on all platforms ) but understandably its most pronounced on older devices like iPad, iPhone 4, iPod 4 and 3GS where it can make a big difference so I generally try to avoid triangle resubmission at all costs.

    Saying that, testing on the actual devices is the only way to know for sure it your code changes are benefiting performance. Whats faster on PC / Mac is not necessarily the same on idevice.
     
    Last edited: May 16, 2012
  22. unikronsoftware

    unikronsoftware

    Joined:
    May 21, 2011
    Posts:
    1,287
    Last time I investigated this, I found double buffering (and just updating meshes in general) caused issues on certain Android HW. Can't remember what specifically though, it was quite a long time ago. In 2D Toolkit, we don't update index buffers where it isn't necessary, and found it did speed things up quite a bit. I'll have to investigate this again to see where we stand with different hardware configs and the latest Unity.

    Edit: I've not done much tests on other devices (not much on PC/Mac either), my main target is mobile, and historically this has been mainly iOS devices. I wouldn't be surprised if the flash and NaCl build have completely different perf characteristics.

    It would be good to have some sort of official recommendations and expected behavior from the Unity guys, its not much fun having hacks in for different devices and configs.
     
    Last edited: May 29, 2012
  23. unikronsoftware

    unikronsoftware

    Joined:
    May 21, 2011
    Posts:
    1,287
    I've done some tests on iPhone4 (slowest device I've got handy), and there results are mixed at best. This was hacked into the current version of 2D Toolkit - I might do some more isolated tests later to confirm these findings.

    I already have a Vector3[] for mesh position and all other attributes, including indices cached locally.

    1. Updating just the changed triangle data (rather than all attributes and resubmitting tri data), is by far the quickest, but has large performance spikes occasionally.

    2. Double buffered, changing all data with a Mesh.Clear() followed by filling up the new mesh, is significantly slower than the above, taking up a lot more script time, but doesn't spike as much as 1.

    3. Using arm6 (GLES1.1), spikes when just changing triangle data almost never happens, and seems to be the quickest of the lot.

    4. Double buffering with GLES1.1 doesn't seem to give any performance gains, but this has similar performance characteristics to 2.

    Looks like the best option for GLES2 is the double buffered one, but it'll need the tri index cacheing code in there for it to be comparable to 1. I suppose one takeaway from this is that resubmitting all attributes and indices is expensive on iOS.

    The fact theres such a difference in behaviour between GLES1.1 and GLES2 paths is worrying.
     
  24. malcolmr

    malcolmr

    Joined:
    Feb 18, 2010
    Posts:
    51
    Unikon, any hints for 2Dtk users who have this problem? I'm getting intermittent periods of really high load from CreateVBO, with no particular pattern that I can discern.
     
  25. unikronsoftware

    unikronsoftware

    Joined:
    May 21, 2011
    Posts:
    1,287
    Wait a bit if possible, I'm prepping a version which double buffers internally, and does some slightly more intelligent resubmitting to avoid the situation described above, and generally reduce the number of CPU branches in there. If you have very few animated sprites, I have that naive version described above which does away with almost all the CreateVBO overhead at the cost of updating mesh data - it only becomes significant with large numbers of animated sprite (around 135 in my case). Send me a PM/support email if you'd like to try it out.
     
  26. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,354
    Well that's one of the mysteries answered for iOS: why has 1.1 always been faster than 2.0. However on droid, it's looking like 2.0 is faster. So you're looking for unity to solve this rather than workarounds. I don't see why this is our problem to solve. Hopefully as unity know about it, there will be good progress on that front.
     
  27. numberkruncher

    numberkruncher

    Joined:
    Feb 18, 2012
    Posts:
    949
    Does the latest Unity update address this issue?

     
  28. SCS_Dani

    SCS_Dani

    Joined:
    May 28, 2012
    Posts:
    55
    If I'm not wrong it seems that now works correctly! :)
     
  29. numberkruncher

    numberkruncher

    Joined:
    Feb 18, 2012
    Posts:
    949
    Awesome! just in time for Unity 3.x :)
     
  30. SCS_Dani

    SCS_Dani

    Joined:
    May 28, 2012
    Posts:
    55
    Oh, I was wrong. Yesterday I did a fast test and it seemed to work but today I have made the real test and I have checked that it has not been fixed. On iPad 1 Mesh.CreateVBO takes 39-42 ms each frame and it drops the FPS from 30 to 15.
     
  31. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,603
    How does it look when you test it on a device that is not underspeced on RAM and GPU like the iPad1 / iTouch4? Is it equally bad on the 3GS devices or 4S / iPad2 generations?
     
  32. SCS_Dani

    SCS_Dani

    Joined:
    May 28, 2012
    Posts:
    55
    Yes, on iPad 2 also drops from 60 to 30.
     
  33. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,354
    Convenient numbers. Have you check Application target FPS yet?
     
  34. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,603
    That drop is nothing to worry though as it looks like a VSync based drop so that would be the first place to check

    Did you hook up the unity pro profiler while running on the device to ensure that you really need that much time, that its not just wait for vsync filling up?

    The same applies to the iPad1 too naturally as its also a drop by a 'natural fraction' of 60 ie 60 -> 30 -> 15 -> 7 / 8
     
  35. SCS_Dani

    SCS_Dani

    Joined:
    May 28, 2012
    Posts:
    55
    Yep, VSync is disabled on both devices (VSync is set to "Don't Sync"). Profiler shows the drop is casued only when using morphers that calls CreateVBO each frame.
     
  36. Vavius

    Vavius

    Joined:
    Aug 31, 2012
    Posts:
    20
    I'm trying to make a game with many procedural trails from objects - the gameplay is based on this trails.
    This CreateVBO bug is really annoying in my case.

    I have tried two workarounds posted here: double buffering and dynamic batching path.
    I don't have Unity Pro and cannot see profiler details, so I used iPhone profiler stats (mainly cpu-player and render) to compare results. Tested on iPhone 4.
    1) Two meshes (240 verts each), nothing changes, everything is static. render: 0.5
    2) Two meshes (240 verts each), all vertex colors are changed via Colors32 each frame. render: 9.2
    3) Same meshes with double buffering. render: 6.1
    4) Same meshes with dummy zero triangles to force dynamic batching. batching: 0.4 render: -0.1

    In the last case numbers are good, but there are also huge visible spikes. Cpu-player max shows 50
    Combining all together (double buffering + forcing batching) removes some spikes, but not completely.

    All this things are kind of very disappointing for me, looks like Unity is definitely not suited for dynamic geometry game for mobile. I'm even thinking of changing game engine for this project...
     
  37. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,123
    Did you use Mesh.MarkDynamic()?

    --Eric
     
  38. numberkruncher

    numberkruncher

    Joined:
    Feb 18, 2012
    Posts:
    949
    I see that `Mesh.MarkDynamic` is new for Unity 4. Do you know if this improves performance for editor scripts as well?
     
  39. numberkruncher

    numberkruncher

    Joined:
    Feb 18, 2012
    Posts:
    949
    I have been experimenting with procedural meshes on iOS but my FPS is between 20 and 30 and occasionally flicks to 5. When should I be calling `Mesh.MarkDynamic` in the lifecycle of a procedural mesh? I just stuck it after the mesh is first created.
     
  40. TrialByFun

    TrialByFun

    Joined:
    Jun 23, 2009
    Posts:
    96
    Hello everyone! Me again!

    So The project I was working on finished early in the year, and in the end I got around the biggest probs of dynamic meshes in a number of sneaky ways. ( under unity 3.5 )

    For text quad rendering I continued to use the double buffer technique and took lots of steps to make sure any vertex data submission was minimised ( couldn't avoid this with score counters, or timers which need updating all the time ), so that was always expensive.

    For all other GUI elements I engineered our GUI system to use a skinned mesh instead of the normal mesh class. All GUI vertex, bone and skinning data was generated dynamically at runtime and vertex information bound to those bones. Benefit of this was that instead of calculating and resubmitting vertex data to the mesh to move an element, I simply moved the bone the element was attached to.

    Color information had to be submitted as normal ( using the faster Color32 ), HOWEVER I avoided any submissions of colour data for alpha by making the z position of the vertex equal to the alpha in the shader.

    so in the glsl shader there is a line like this;

    It makse sense given that GUI typically has no depth, so the position.z of a vertex was free to abuse.

    This meant that all the fancy rotation, position, scale and alpha effects of our gui elements were in effect free. ( other than the minimal cost for it being a skinned mesh, but overall that was still cheaper than a dynamic mesh. )

    I tried to speed this up even further by using the double buffer trick on skinned meshes, but this results in significantly worse performance. ( unlike with a normal mesh )





    Now i'm back again and we're now moving over to Unity 4.0+, so it felt like a good time to revisit this post and evaluate again how things have changed since last year.

    Okay, first of test conditions;
    Ipod4, iOS5.1, Unity 4.1.5, blank scene with just the mesh generator script and a camera.

    At Start() I create 500 quads worth of vertex data, and store that information in local arrays.

    Every frame I simply apply those same arrays unchanged back to the mesh ( effectivly resubmitting vertex data )
    So CPU cost is how long that bit of code takes.

    I tested,
    • Normal, vs MarkDynamic once vs MarkDynamic everyframe
    • Normal vs Double Buffering.
    • Color ( with triangles ) vs Color32 ( with triangles )
    • Clearing a mesh with Clear(true) and Clear(false) before submitting vertex information

    Using the Profiler I note the average time for CPU of the script, and Mesh.CreateVBO, Mesh.SubmitVBO and mesh.DrawVBO for each test case.

    The results!

    Winner - A , MarkDynamic makes everything slower


    Winner - B, double buffer meshes. ( but the margin isn't as massive any more )


    Winner B - Color32 is faster than Color, triangles submission is slow whatever.


    Winner - A, use Clear(true) if you HAVE to clear the mesh. But avoid clear() calls like the plague


    As always you should test results in your own code yourself before taking them as gospel, but heres my summary of the results;

    • Mesh class when submitting geometry every frame in 4.0 is A LOT faster than 3.5 ( especially CreateVBO )
    • Mesh.MarkDynamic() is SLOWER, so unless someone knows the use case for this??? i wouldn't bother.
    • Color32 is faster than Color
    • Never ever Clear() a mesh every frame.
    • Avoid triangle submission every frame if you can, try caching your triangles at startup.
    • Double buffering meshes is still the fastest ( but margins are no where near as big as before ~1ms )
    • Not tested here but I recommend using a skinned mesh for elements that only move, scale and rotate


    Hope this is of help to someone, many moons later.
    Steven.
     
    Last edited: Jul 6, 2013
  41. numberkruncher

    numberkruncher

    Joined:
    Feb 18, 2012
    Posts:
    949
    Hi Steven

    Thanks for the detailed follow up!

    It is a shame that the documentation for the Mesh.MarkDynamic function is so poor. But I too have noticed that it seems to worsen performance.
     
  42. Alexey

    Alexey

    Unity Technologies

    Joined:
    May 10, 2010
    Posts:
    1,378
    just my 2 cents:
    1. first of all comparing JUST cpu times around your code wont get you anywhere (as in - there are lots of driver things and probable gpu impact)
    2. can we have repro pretty please? i mean - unless we see stuff, we cant help you
     
  43. numberkruncher

    numberkruncher

    Joined:
    Feb 18, 2012
    Posts:
    949
    I do not have my tests any more (this from a while back) but I was comparing FPS instead of CPU under various loads which showed that performance was worse when the mesh was initialised using MarkDynamic. Whether this is still the case with more recent versions of Unity 4 I do not know.
     
  44. Alexey

    Alexey

    Unity Technologies

    Joined:
    May 10, 2010
    Posts:
    1,378
    well, for the future - bug report. We cant fix what we cant see ;-)
     
  45. numberkruncher

    numberkruncher

    Joined:
    Feb 18, 2012
    Posts:
    949
    It would be nice if the documentation for this function was more verbose:
    • When should the function be called?
    • If an asset is made dynamic at runtime, should this function be called?
    • Is the "marked dynamic" state persisted when a mesh is saved as an asset?
    • When making an asset dynamic at runtime, is it necessary to create a new mesh, mark it dynamic, and then copy its data from the asset?
    • What does MarkDynamic actually do, and why is this good for performance?
    • Should MarkDynamic be called each time Clear() is called? or will the previous mention be retained?
    • Will it benefit Android and iOS platforms?
    At the moment it seems that we are just guessing at whether MarkDynamic would be suitable for our scenarios without an actual understanding as to what the function even does. There are always trade-offs when it comes to performance, so what are we trading with MarkDynamic?
     
  46. Alexey

    Alexey

    Unity Technologies

    Joined:
    May 10, 2010
    Posts:
    1,378
    >>When should the function be called?
    >>Is the "marked dynamic" state persisted when a mesh is saved as an asset?
    >>Should MarkDynamic be called each time Clear() is called? or will the previous mention be retained?
    It is "instance" function, so it wont be saved to asset. You call it to tell unity that this one mesh should be regarded as dynamic geometry (changing frequently).
    >>What does MarkDynamic actually do, and why is this good for performance?
    now, thats quite interesting. As in - we added it so we can push more platform specific stuff. e.g. on mobiles, on some gpu's dynamic vbo are slow per-se (slow, as in SLOW), so on them it would be beneficial to draw from memory. Mind you, we've added better determination, buffer size threshold (when VBO became faster again, unless you run on some utter S***) etc.
     
  47. Stephan-B

    Stephan-B

    Unity Technologies

    Joined:
    Feb 23, 2011
    Posts:
    2,269
    Calling Mesh.RecalculateBounds every frame also seems pretty expensive. So what is the consensus on that function?

    What is the impact of not having accurate bounds on a mesh?
     
  48. numberkruncher

    numberkruncher

    Joined:
    Feb 18, 2012
    Posts:
    949
    This is to be expected since it must traverse each vertex to determine the minimum and maximum bounds. If there are a lot of vertices, then this could take some time.

    I would imagine that accurate bounds help with the culling process.
     
  49. Stephan-B

    Stephan-B

    Unity Technologies

    Joined:
    Feb 23, 2011
    Posts:
    2,269
    Is there still a decent benefit to using the double buffering and a good post explaining the technique?

    I am also curious about memory allocation vs. pushing smaller data.

    How badly is memory allocation frowned upon by Asset Store buyers? Right now, my GC Allocations are ZERO but that comes at the expense of having to push larger arrays around.
     
  50. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,354
    Personally I won't purchase anything with garbage being generated unless it's unavoidable in a technical way and the asset is really awesome. It's a good selling point to have optimised assets for sale :)