Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Resolved Emit Particles From Animated Rig Model with Color Sampled from the Texture

Discussion in 'Visual Effect Graph' started by hectorfan, Sep 10, 2023.

  1. hectorfan

    hectorfan

    Joined:
    Feb 1, 2023
    Posts:
    8
    Hi, Is there a way to make particles emitting from an animated rig model using the colors sampled from the texture of the model?

    I was able to realize this effect on a static model by using the point cache method, but seems like it doesn't work for animated rig models since the mesh is changing. (the method was from here: https://forum.unity.com/threads/emit-particles-from-texture-with-colour.870127/#post-9284197)

    And I was able to emitting particles from an animated rig model by using the skinned mesh position, but the color is set, not sampled from the texture. I tried to add the point cache to Initialize Particle part, but it doesn't work.

    The following screenshots are emitting particles from a static model and an animated rig model:
    pointCache-staticModel.png skinnedMesh-animatedModel.png
     
  2. OrsonFavrel

    OrsonFavrel

    Unity Technologies

    Joined:
    Jul 25, 2022
    Posts:
    216
    Morning :)
    So, from what I can see, you're using a Set Position (Skinned Mesh) Block.
    This Block is practical as it as many embed functionality to properly spawn particles on a SkinnedMesh including nice orientation options. But, at the moment, this block can't help you to sample the Skinned Mesh Uvs, Normals, or other information.
    So to do this, you need to use a more generic Sample SkinnedMesh operator. This operator, will let you sample a Mesh or Skinned Mesh and get all the information that you need. Just this block operator and in the inspector you should see all the different information that you can get from the Mesh:
    upload_2023-9-11_10-31-56.png

    So, with this operator, you need to fill which Skinned Mesh do you want to sample.
    In my example, I'm using an exposed Skinned Mesh property to be able to use a Skinned Mesh in the Scene.
    You can sample either, the Edges, the Vertex, or Triangles. In my case, I'm sampling the Triangle randomly.
    To do this, I'm using a fixed random number operator between 0 and the Triangle Count of the same Skinned Mesh. This allows for each particle to get a random triangle to sample from. The Triangle Count can be obtained with a GetSkinnedMesh Triangle Count Operator.
    From here, each particle can access various information. I'm using the Position to set the particles position, and the UVs to sample the Base Color texture of my skinned mesh. This is possible by using a SampleTexture2D operator.
    From here, I just use this color to Set the Color attribute of my particles. upload_2023-9-11_10-45-12.png

    Hope this small example will help you. Have a great day.


    Unity_Xqx3Rii59N.gif
     

    Attached Files:

    Qriva and hectorfan like this.
  3. hectorfan

    hectorfan

    Joined:
    Feb 1, 2023
    Posts:
    8
    wow, this is amazing, thank you so much! I was able to realize the effect by using your method.
    I have one more question about the visuals, after implementing your method, the particles align strictly to the vertices, leading to denser particles in areas with more vertices, like the head. In contrast, my previous effect on a static Spiderman model had particles that were more randomly distributed. I noticed that the particles in your gif appear more randomly placed – a look I prefer since I don't want the visuals to resemble a mesh x-ray. How did you achieve that? Is it due to the particles' movement, creating the illusion of non-alignment to vertices? sampleSkinnedMeshEffect.png sampleSkinnedMesh.png
     
  4. OrsonFavrel

    OrsonFavrel

    Unity Technologies

    Joined:
    Jul 25, 2022
    Posts:
    216
    So in my case, I'm not using “Vertex” as “placement Mode” but Surface to spawn on the Triangles of the Mesh.
    This gives you the option to spawn randomly on the surface of each triangle that can lead to a more organic/natural position.
    upload_2023-9-11_12-16-40.png upload_2023-9-11_12-16-49.png

    That being said, there isn't a simple solution to Uniformly spawn particles at the moment. As there is often more density vertex/triangles in some areas (ex: the face) , you get more chance to spawn from it when spawning randomly.
    What is typically done is to have a "Proxy Mesh" to be sample from. This proxy Mesh is a simplified version of your skinned Mesh with a Uniform topology. You won't render it so that only the “Beauty” mesh is visible, but it will still be animated and samples by the VFX Graph so that particles can spawn on it.
    This solution allow you to have uniformly distributed particles, but also usually better performances as the Proxy mesh is usually more lightweight.

    I can try to take the time to make a post on how to set up a proxy Mesh efficiently in Houdini if you're interested.

    You should also check this post from @PaulDemeulenaere that talk about Uniform Sampling:
    https://forum.unity.com/threads/uniform-distribution-with-skinned-mesh-sampling.1188571/

    Hope this helps.
     
    hectorfan likes this.
  5. hectorfan

    hectorfan

    Joined:
    Feb 1, 2023
    Posts:
    8
    Thank you! I'll check the post you mentioned, and if you have time to make the post about proxy Mesh, I would be very interested to see it.
    As for the placement method, I did choose the surface, but the particles are still spawned on the vertices. Please check my attached picture for my setting, I haven't found the reason why this happened. Thank you again! Screenshot 2023-09-11 063628.png sampleSkinnedMesh.png
     
  6. OrsonFavrel

    OrsonFavrel

    Unity Technologies

    Joined:
    Jul 25, 2022
    Posts:
    216
    Alright, it's my fault, I didn't detail enough the Surface Coordinate part of the Sample Skinned Mesh Operator.
    So when you're in “Surface mode” a new “Surface Coordinate” option appears. This allows to specify the how to sample the Surface of each triangle. By default, it is set to “uniform” to sample the surface uniformly within the triangle area.
    But you still need to specify uniform coordinates to sample the triangle at. You set this with the “Square” slot, and the Block takes this value and maps it from a square coordinate to triangle space.

    In Uniform mode, the X and Y values range from 0-1. Unity_est1KxoNCk.gif


    So to be able to spawn particles randomly on the full surface of random triangles, You'll need a Random Number between 0-Triangle count of your Mesh.
    Two other random number operator with different Seeds for X and Y coordinate of the “Square” uniform coordinates.
    Two random with different seeds are necessary to be sure that X-Y values are not tied together.
    Also, I'm using 'Constant' random Number so that the random generation is done once in case I want to use my block in the update (don't want that my particles get new random coordinate each frame)

    upload_2023-9-11_14-58-35.png

    This should help you to get particles that are spawn on the full surface of each Triangle.

    Will be back with the “Proxy Mesh” solution.
     
    hectorfan and PaulDemeulenaere like this.
  7. OrsonFavrel

    OrsonFavrel

    Unity Technologies

    Joined:
    Jul 25, 2022
    Posts:
    216
    Alright, so this might be a long post. As stated above, spawning particles uniformly on a Mesh (SkinnedMesh or Mesh) isn't possible out of the box with VFXGraph. This post by @PaulDemeulenaere is covering the limitation and a solution to get a uniform spawning across a Mesh/Skinned Mesh Surface.

    To summarize, often the triangle density of a mesh is relative to the needs of details in certain areas like the Face and/or the Hands/hairs etc… More triangles in some areas means more chance to samples this area when spawning randomly on the surface of a Mesh.

    Here is a quick Preview of a mesh that is relatively uniform in its triangle density but still have more triangles in the Hands/face area:

    upload_2023-9-11_16-17-50.png

    While this mesh isn't too bad, we can see that there are more Triangles/quads on some regions that leads to more particles being spawn on those regions and some "gap/holes".

    So one solution is to create a “Proxy Mesh” use only for particles sampling with uniform topology. While many solutions exists, I will give some details of two of them using Houdini.

    Scatter Triangles:

    The idea, is just to uniformly scatter points on the Mesh Surface. In Houdini it's pretty trivial and you can just use the regular "Scatter" node. The nice thing is that it's really easy to control the number of points, and you can relax their position so that the position is really uniform. It's also very fast to compute. To finish, all the scattered points inherit the attributes from their Surfaces. This means that all the Scattered points inherit the UVs, Vertex Colors, Normals, Skin/blend Weights etcs...
    So you only need to copy on each of those points Triangles that will also inherit attributes values from the points, and you get a procedural setup to have a Proxy Mesh that is already skinned:

    upload_2023-9-11_16-37-0.png
    The Procedural Houdini Setup, to get a Skinned Triangle Clouds Proxy Mesh.

    houdini_bBKv0zBpgG.gif

    By sampling this more uniform Proxy Mesh in VFX Graph, you'll have several advantages :
    • Better sampling performances as you can sample a Mesh with fewer triangles
    • A uniform particle distribution, and overall less gap/holes.
    But this also means that you'll have fewer details in some Area that might need them.
    upload_2023-9-11_16-53-52.png

    Unity_ZSjW9mfs5r.gif
     
    hectorfan and Qriva like this.
  8. OrsonFavrel

    OrsonFavrel

    Unity Technologies

    Joined:
    Jul 25, 2022
    Posts:
    216
    Remesh:
    Another solution, in Houdini, is to use the Remesh node. This node allows to Remesh an input geometry with triangles and allow you to specify the Triangle Target size and to perform some relaxing iterations to get a uniform triangle distribution. As with the previous solution, the created triangles inherit the Previous surface attributes. This means that your proxy Mesh already got the UVs, normals, and Skinning information:

    upload_2023-9-11_17-7-1.png
    The Procedural Houdini Setup, to get a Remesh Proxy Mesh.
    houdini_6Qzmh25QjG.gif

    By sampling this more uniform Proxy Mesh in VFX Graph, you'll have several advantages :
    • Better sampling performances as you can sample a Mesh with fewer triangles
    • A uniform particle distribution, and overall less gap/holes.
    upload_2023-9-11_17-8-32.png Unity_qBZvlN888G.gif


    Unity_HBV6umDSdG.gif
    Here is a comparison between the original Mesh sampling, and the two solution mention above.
    Bottom Left =Original, Bottom Right = Remesh Solution, Top Left = Scatter Triangle Solution.

    I do hope that in the future will be able to give out of the box Uniform sampling options. In the meantime, I do hope that this procedural approach and this Post will be helpful.
     
    hectorfan likes this.
  9. hectorfan

    hectorfan

    Joined:
    Feb 1, 2023
    Posts:
    8
    Thank you for your detailed explanation! Really appreciate the effort and time you put into writing the post.
    After connecting the random number operator to the "square" slot in Sample Skinned Mesh, the particle placement is much better.
    I'll try both of these solutions on spawning particles uniformly on a Mesh, and I'll update here how it goes.
    Here's my current result, just recorded it as gif:
    sampleSkinnedMeshParticl-betterPlacement.gif
     
    Last edited: Sep 12, 2023
    OrsonFavrel likes this.
  10. OrsonFavrel

    OrsonFavrel

    Unity Technologies

    Joined:
    Jul 25, 2022
    Posts:
    216
    Indeed, it's way better :)
    Glad to know that you managed to improve your result. Depending on what you're trying to achieve, you might not need the Proxy Mesh mention above. I'm sure it's possible to create such a proxy in Blender, but sadly I'm not fluent with it.
    Have a great day
     
  11. hectorfan

    hectorfan

    Joined:
    Feb 1, 2023
    Posts:
    8
    I'll definitely try the Proxy Mesh method, since I'm trying to make the particle effect looks similar enough to the original model so that you can identify different people in the scene, as I'm making this effect as a visual representation to memories in the game I'm developing.
    But I'm not familiar with Houdini, so it will take me some time for sure, but good to know Blender is possible too.
    You have a great day too!