Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Feedback VFX Graph Instancing

Discussion in 'Visual Effect Graph' started by Qriva, Aug 14, 2022.

  1. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,108
    I would like to leave some feedback and clarify some aspects of visual effect instancing.
    Tested version 2022.2.0b4.2768

    upload_2022-8-14_18-36-37.png

    First of all, I want to say that the performance of the VFX graph has been significantly improved over the previous version. My test setup consist of plane and 900 effects (30x30) - playing these effects on 2021.3 is two times slower while rendering is not event batched! I guess this is mainly because updates are batched now.
    2021.3 on top and 2022.2 beta on bottom
    upload_2022-8-14_18-46-26.png

    I tested different combinations of options and I want to clarify/confirm following statements:
    1. There are two types of batching, one for rendering and one for updating. Update batching is not affected by rendering options (such as blending mode), so even if effect cannot be rendered in single batch it can be updated way faster.
    2. Assuming first point is correct - is it good strategy to move blocks from output to update context when possible, because update most likely can always be batched, while rendering not?
    3. Any non-blittable data (such as texture) exposed in inspector breaks batching.
    4. Why exposed, but unused texture property breaks batching?
    5. From where comes number of update calls '113' in picture above?
    6. Only opaque particles can be batched and any other alpha blending option will disable batching.
    7. When Alpha blending is enabled, but sorting disabled, then number of draw calls is around 270 instead of 900+, what is actually happening here?
    8. BTW how to use custom sort mode?

    And my 3 cents: it would be great if we had warning box in instancing section with informations that instancing can't work in current setup and what can be done to fix it. For example "There is texture exposed in inspector - this is not supported by instancer".

    upload_2022-8-14_20-11-42.png
     
    PaulDemeulenaere and VladVNeykov like this.
  2. gabriel-delacruz

    gabriel-delacruz

    Unity Technologies

    Joined:
    May 19, 2021
    Posts:
    31
    Hi Qriva,

    Thanks for your feedback!

    I'll try to answer your questions:

    1. Yes, kind of, let me explain. When we instance a VFX, we put it together with others, sharing their memory buffers. This means that we will run compute shaders (inits, updates, outputupdates) on all those instances at the same time. For draw calls (outputs) we want to do the same, but it is not always possible. However, even when we need multiple drawcalls, it should be faster when instanced, as we can set the material once and do many drawcalls in a row.

    2. I think the main criteria for placing blocks should be clarity. There is probably not a big difference, and there are pros and cons. Updates can run more than once depending on time step vs outputs can be rendered in more than one pass, etc. If you have some blocks that could be in either place, the best way to be sure is to test in both places.

    3. Yes, anything derived from Object (textures, meshes, graphicsbuffers) that is exposed will disable instancing. This is because we would need to bind different data in the shader, so they can't be run together. In future versions we would like to improve this and group those that belong to the same batch and have the same value for all their exposed objects.

    4. This is because the value in exposed textures can change dynamically, so we don't know if they are going to be used or not when we decide to place it together with other instances (at creation). With the future improvement mentioned in 3, empty exposed objects should not break batching anymore.

    5. That is a good question. The number there should be 900, all the VisualEffects get updated individually. VisualEfect Update function is multi-threaded, and maybe the profiler counters are only counting the ones running on main thread. If you have 8 cores, 900 / 8 = 112.5 ~ 113. Multi-threaded update was introduced in 2021.2, I think, so it should be available for both versions you are comparing. There are some reasons that can prevent multi-threaded update, like output events or mesh sampling, I don't know which one is causing that for your effect.

    6. I think it is really sorting, not alpha blending itself. In those cases, instancing should still be enabled for computes, as explained in 1. Sorting (used by default with alpha blending) requires an indirection that currently makes it impossible to render more than one VFX in the same drawcall. They will still be rendered in a row, when possible.

    7. Even if you disable sorting for the particles, transparent objects need to be sorted by the engine and rendered back to front. This means that unity instancing batcher (different from our VFX instancing) will have the last say in which instances can be rendered together. If you arrange your VFX in a different way or rotate the camera around, you should see that number change dynamically.

    8. I'm afraid I can't help with that one, maybe someone else in the team will be able to give you more info.

    Regarding your suggestion, that should be already there in the version you are testing (but not in the first version). Can you double check?
    upload_2022-8-15_10-59-35.png

    Finally, all the information here is subject to change in the future. This feature required big changes internally and we will need to tweak and improve some things. That is why your feedback is so valuable, thanks!

    Also, I would like to use this opportunity to thank you for all the help you provide in the forums, it is really appreciated :)
     
    Last edited: Aug 15, 2022
  3. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,108
    Thank you very much!

    I had plan to ask, if batching the same setup is on the roadmap, but that has been already answered. Regarding this:
    Just to be 100% sure we are on the same board - I meant exposed texture without any connections (exists only in property list).
    This effect is super simple, I don't think there is anything that could break it.
    upload_2022-8-15_13-58-17.png

    You are right, I could not see it because I expected to see box when i play with other options. If I understand correctly exposing texture disables batching completely, however I think there should be info when it's partly enabled, for example:
    • Particles with Alpha blend cannot be rendered in batches
    • Indirect draw enabled - rendering in batches will not be possible
    • Sorting mode bla bla...

    One more thing, is there any rule for the same graphs (duplicated nodes) or subgraphs? I don't see there is anything like that, so would it be possible to batch the same subgraphs or anything like that?
     
  4. gabriel-delacruz

    gabriel-delacruz

    Unity Technologies

    Joined:
    May 19, 2021
    Posts:
    31
    Well, in that case it is true that we could ignore it, but at the moment we just look at the exposed variables list, connected or not. If it is not being used, there should be no problem for the user to remove it.

    Then I'm not sure why you see 900 updates in the previous version. Maybe the counters worked properly then, maybe the multi-threaded update is disabled in that version.

    Ok, I understand now. I would not consider the feature to be partly enabled in that case, though. Compute shaders will work the same as fully batched, and rendering will still be faster than if it was not instanced. There is little action for the user in that case, other than explaining what is going on when looking at a GPU capture.
    We will consider your suggestion for future versions, and investigate the best way to show this kind of information.

    Once an effect gets compiled, the subgraph becomes part of the graph. We can't batch subgraphs because they don't exist in runtime.
     
  5. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,108
    Sure, that's not a problem. For some reason expected that maybe it's compiled away as it's not used.
    Understandable, but from user (at least mine) perspective it feels like it works in 50%. If this is just nature of this feature, then I expect docs to explain it in detail (btw instancing is not mentioned in "What's new" doc page).

    I mention this, becuase graph becomes more and more complex, there are more edge cases and gimmicks, so it might be hard to remember everything, especially for new user. This is why I think it's better to throw some additional info box, so user is aware what is happening.
    Yeah, I guess it would require another big refector. I consider this as nice addition. The fact there is any batching is huge improvement already.

    I think everything is clear now, thank you very much again!
     
    raaan127 and gabriel-delacruz like this.
  6. Nanachi88

    Nanachi88

    Joined:
    Aug 10, 2022
    Posts:
    14
    I am sorry for the basic question. How do you manage to get the Instancing Mode option? I could not find it in my vfx graph inspector
     
  7. gabriel-delacruz

    gabriel-delacruz

    Unity Technologies

    Joined:
    May 19, 2021
    Posts:
    31
    Hi!
    You need to be in 2022.2 or later to use instancing.
    You can find the instancing mode in the Visual Effect Asset inspector.