Search Unity

Feedback Improve ParticleSystemRenderer.BakeMesh

Discussion in 'General Graphics' started by Peter77, Nov 1, 2019.

  1. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,620
    I was looking into how to integrate a ParticleSystem into uGUI, when @karl_jones posted a link to the ParticleEffectForUGUI package out of the blue. The package is very much doing what I was aiming for.

    However, there is a lot of data copying and math involved, which has a negative performance effect on mobile devices, such as:
    Code (CSharp):
    1. _renderer.BakeMesh (_mesh, cam, true);
    2. _mesh.GetVertices (s_Vertices);
    3. var count = s_Vertices.Count;
    4. for (int i = 0; i < count; i++)
    5. {
    6.     s_Vertices [i] = matrix.MultiplyPoint3x4 (s_Vertices [i]);
    7. }
    8. _mesh.SetVertices (s_Vertices);
    https://github.com/mob-sakai/ParticleEffectForUGUI/blob/upm/Scripts/UIParticle.cs#L465

    In order to reduce this performance hit, you could provide an overload of the BakeMesh method with a matrix parameter and apply the transformation while building the mesh vertices. I imagine BakeMesh is using a matrix multiply internally already to compute vertex positions, so it would be pretty much a free operation to apply the additional matrix there and a simple change.

    Another approach, but this one would involve more changes and is more complicated, could be to provide a Job where we can manipulate vertex data during BakeMesh. Basically a "job callback" for every vertex you bake, which we can manipulate and the manipulated data is picked up by BakeMesh. This could be more powerful and would run off the main thread.

    What do you think?
     
    Last edited: Nov 1, 2019
  2. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Hey :)

    What is that matrix?

    By placing the camera and particle system transform in the "right place", it ought to be possible to bake the system directly into the desired final position, with no post-processing of the baked verts, which i agree is very slow.

    A callback from the engine into script for every vertex would almost certainly be the slowest possible way of solving this (callbacks have significant cost).

    UPDATE: I read the code a bit more. so the matrix is built from the canvas rectTransform. Well, i would have thought moving the camera by the matrix (or the inverse of it) ought to achieve the same thing. It just depends how slow that is.. as presumably you'd want to restore the camera afterwards.. and this teleporting might also have other consequences.. so all in all, yeah maybe a new overload would be safest. But if there is a solution that doesnt require new script API, that would solve this much sooner for you. eg a second, dummy camera, that is only used for baking, and has its transform set to camera.transform * matrix.
     
    Last edited: Nov 1, 2019
    Peter77 likes this.
  3. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,620
    Hey Richard,

    thanks for your reply!

    Regarding the dummy camera for baking. It sounds like the camera that can be passed to BakeMesh is used for more than "determining which way camera-space particles will face" as found in the docs?

    BTW, I guess the BakeMesh matrix overload wouldn't land in 2019.3 anymore?

    We mostly stick to LTS releases and if it won't land in 2019.3, we probably have to wait for 2020.4 and at that time we're perhaps using UIElements already, which hopefully has full particle system support as a built-in feature (hint)?! :)
     
    richardkettlewell likes this.
  4. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Well, that’s more or less accurate I think, I was just meaning that combined with adjusting the transform of the particle system, it ought to be possible to apply any transformations to the baking process.

    Indeed we won’t add a BakeMesh to 2019.3 - that version is locked down for new stuff. I can get it into 2020.x I’m sure.

    Regarding UIElements and particles, particles are not being actively worked on anymore, other than for bug fixes. I’d like to think it would work robustly with UIElements, but unless the ui team are owning this, I worry it won’t happen, as I know no one from the particles side is thinking about it. Unless it just works automatically. The VFX Graph is the new particle solution - that’s the tech I’d most expect to be getting thought about with regard to UIElements moving forwards.
     
  5. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    I looked at adding the new overload today but it hasn’t turned out to be as easy and intuitive as I’d hoped.

    Simply adding a matrix parameter makes it unclear whether the vertices would be transformed after the camera-facing logic, or before. (I.e should it be a transformation to apply to the particle transform, or to the final result?)

    It’s quite easy to support either approach, I just worry that it is not a clear API to be adding.

    I’ll give it some more thought and see if I can come up with something I’m happy with. All input welcome :)
     
    Peter77 likes this.
  6. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,620
    I know that feeling. Things often seem simple in the beginning, then you look into it and it turns out it really is not. :) I'm going to bounce some ideas below, really not sure how applicable they are, so excuse me if they're not good.

    Is the camera-facing logic just another matrix multiplication that happens inside BakeMesh? If that's so, how about not doing the facing transform inside BakeMesh, but use the user provided matrix as is to transform vertices? That would shift the implementation detail whether it should be pre- or post- multiplied from BakeMesh to the user side and we can implement that as needed.

    If that's not as simple as I assumed in my answer above, another alternative could be to provide an additional argument that indicates how to apply the transform.
     
    richardkettlewell likes this.