Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

submesh animation bug

Discussion in 'Visual Effect Graph' started by stiltskin, May 27, 2021.

  1. stiltskin

    stiltskin

    Joined:
    Feb 27, 2010
    Posts:
    95
    hi gang,

    I'm running into an issue with VFX Graphs, where I'm unable to simply animated a sequence of meshes.

    I see that the submesh system in unity is quite limited, so I'm trying to work around it via a switch node. But for some reason it errors out when i try to feed the index a dynamic value (lifetime). But it does not bug out if i feed the index an exposed property.

    If I try this setup I get an error. That seems to be an issue between CPU / GPU communication. -

    upload_2021-5-27_8-49-35.png

    VFX_EggBurst_01 : Exception while compiling expression graph: System.InvalidOperationException: Unable to compute CPU expression for mapping : mesh
    at UnityEditor.VFX.VFXDataParticle.FillDescs (UnityEditor.VFX.VFXCompileErrorReporter reporter, System.Collections.Generic.List`1[T] outBufferDescs, System.Collections.Generic.List`1[T] outTemporaryBufferDescs, System.Collections.Generic.List`1[T] outSystemDescs, UnityEditor.VFX.VFXExpressionGraph expressionGraph, System.Collections.Generic.Dictionary`2[TKey,TValue] contextToCompiledData, System.Collections.Generic.Dictionary`2[TKey,TValue] contextSpawnToBufferIndex, UnityEditor.VFX.VFXDependentBuffersData dependentBuffers, System.Collections.Generic.Dictionary`2[TKey,TValue] effectiveFlowInputLinks, UnityEditor.VFX.VFXSystemNames systemNames) [0x00dd8] in [i removed filename]

    at UnityEditor.VFX.VFXGraphCompiledData.Compile (UnityEditor.VFX.VFXCompilationMode compilationMode, System.Boolean forceShaderValidation) [0x007bd] in [i removed filename] at UnityEditor.VFX.VFXDataParticle.FillDescs (UnityEditor.VFX.VFXCompileErrorReporter reporter, System.Collections.Generic.List`1[T] outBufferDescs, System.Collections.Generic.List`1[T] outTemporaryBufferDescs, System.Collections.Generic.List`1[T] outSystemDescs, UnityEditor.VFX.VFXExpressionGraph expressionGraph, System.Collections.Generic.Dictionary`2[TKey,TValue] contextToCompiledData, System.Collections.Generic.Dictionary`2[TKey,TValue] contextSpawnToBufferIndex, UnityEditor.VFX.VFXDependentBuffersData dependentBuffers, System.Collections.Generic.Dictionary`2[TKey,TValue] effectiveFlowInputLinks, UnityEditor.VFX.VFXSystemNames systemNames) [0x00dd8] in [i removed filename]
    at UnityEditor.VFX.VFXGraphCompiledData.Compile (UnityEditor.VFX.VFXCompilationMode compilationMode, System.Boolean forceShaderValidation) [0x007bd] in [i removed filename]
    UnityEditor.EditorApplication:Internal_CallUpdateFunctions ()




    If I try this though, I can then set that property externally with no errors -
    upload_2021-5-27_8-49-56.png


    does anyone know why one method would work the other would not? I've also tried using the SpawnTime attribute to see if it was an issue with a particle being considering dead when the mesh is swapped, leading to the particle lifetime being useless. but with no luck.

    Thanks!
     
    Last edited: May 27, 2021
  2. VladVNeykov

    VladVNeykov

    Unity Technologies

    Joined:
    Sep 16, 2016
    Posts:
    550
    Hi @stiltskin ,
    This is a limitation of being unable to link GPU operators to a CPU input (i.e. you cannot assign meshes or textures on a per-particle basis.) This is why you are getting errors when using Get Attribute: lifetime, but it works if you just feed it an inline number as then it is a consistent value for all particles and the same mesh gets applied.

    Depending on what you are trying to do, you have a few options:
    1. You can use Multi-Mesh (up to 4 meshes per output) and then you can manually set a random Mesh Index to specify per-particle which of the up-to-4 meshes you'd want to use.

    (This feature is still experimental, so to see it appear you need to go to Edit > Preferences > Visual Effects and enable Experimental Operators/Blocks)

    2. I see from your screenshot that you are already using the ShaderGraph integration for VFX. In 2021.2 we've refactored the SG/VFX integration for HDRP to allow, among other things, access to modify particles at the vertex stage. If your meshes are just deformations with the same geometry, you could probably quite soon move the animation to be done directly within shadergraph.

    3. (This one is messy) Combine all meshes into 1, and apply some vertex color gradient on them (i.e. the first mesh is black, mesh in the middle is 0.5 red, and the last mesh is 1 red) and then in shadergraph clip based on comparing the vertex color to a value you supply from the graph (this time this could be per-particle).

    Hope this helps!
     

    Attached Files:

    RoyBarina likes this.
  3. stiltskin

    stiltskin

    Joined:
    Feb 27, 2010
    Posts:
    95
    @VladVNeykov thank you for the reply. Yes that helps. I looked into the experimental submesh feature already, but only 4 meshes doesn't work in my case. I'm not super crazy about that shader pipeline from a UX point of view, but i'll take what I can get. :)

    Are there plans to have the option to force a VFX Graph to CPU for this sort of thing? If im just spawning one particle, it would not be very costly for the CPU, but would improve the UX for this type of thing.

    cheers!
     
  4. VladVNeykov

    VladVNeykov

    Unity Technologies

    Joined:
    Sep 16, 2016
    Posts:
    550
    We are considering having simulation on the CPU down the road, mainly to allow targeting of devices which don't have compute-shader capabilities, but it should also address your use case. You can upvote this task here.

    If you have only 1 particle, you can probably do something like this:

    This will cycle the mesh once every second and then repeat.

    If the animation is supposed to repeat, you can make the particle immortal (i.e. don't assign any lifetime) and then use modulo with the same value as you mesh count (26 in your case) so the animation will loop. Otherwise, just assign time directly without modulo.

    You can also change the speed of switching by multiplying the time value.

    Here's the result:


    You can also convert any over-lifetime blocks you had before (like Set Color over Lifetime) to use Custom as the sample mode and then connect your custom logic to this so things are synchronized. In this case, it will take 5 second for the particles to transition between opaque red to transparent green:
     

    Attached Files: