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

Question Particles orient to camera even though Orient: Along Velocity block is used

Discussion in 'Visual Effect Graph' started by Sooly, Apr 19, 2023.

  1. Sooly

    Sooly

    Joined:
    Jan 28, 2021
    Posts:
    19
    As per title - I add Orient: Along Velocity to my Output Particle Mesh and particles are rotated to some strange cross-product of velocity and camera facing. Same setup works perfectly fine with Output Particle Line.
    It looks a bit as the meshes try to compensate for perspective and follow velocity vector in screen-space.
    Is it an expected behaviour and I should use Advanced or am I missing some additional setting?
    It's VFX Graph 10.10.1 in 2020.3.25f1.

    Recording of that behaviour: https://drive.google.com/file/d/1NbIFHdGFRIoh7NPhClkvLlnXvonfiYkx/view?usp=sharing
    Output setup:
    upload_2023-4-19_12-39-59.png
     
    Last edited: Apr 19, 2023
  2. Sooly

    Sooly

    Joined:
    Jan 28, 2021
    Posts:
    19
    Nevermind, I just realized I skipped a part of a sentence in the documentation. :)
    Can be closed.
     
    OrsonFavrel likes this.
  3. OrsonFavrel

    OrsonFavrel

    Unity Technologies

    Joined:
    Jul 25, 2022
    Posts:
    218
    Usually, to properly orient a Mesh, you need at least two vectors. A "Facing" vector and an "Alignment" vector.
    The "Orient along Velocity" is aligning the mesh along the "Velocity" but "Facing" is still relative to the viewPosition.
    This is usually what you'll want for Flat Billboard quad:

    The "Orient to Velocity" computed source code:

    axisY = normalize(velocity);
    axisZ = position - GetViewVFXPosition();
    axisX = VFXSafeNormalizedCross(axisY, axisZ, float3(1,0,0));
    axisZ = cross(axisX,axisY);


    So we need two vectors and the third one is going to be "derived" from those with a cross product by the "Orient Block":

    houdini_x8rbwvf9YZ.gif
    A Forward Vector (Blue) an Up Vector (Green) and side Vector (red) use to orient a mesh along a Path.

    So what you can do is use the "Orient Block" in Advanced mode. With my mesh initial Orientation, I'm using the XY axis. "Y" is corresponding to my particles "normalized" velocity and the "X" (side) is the Cross product between the "Normalized Velocity" and the World up (0,1,0).

    With this, I'm able to get a stable orientation for my ugly plane meshes:

    upload_2023-4-19_14-8-26.png

    Unity_SPhRMvjj4C.gif

    Hope that this will help you.
    Have a great day.

    edit: I guess that my answer took too long to write... Glad that you found an answer @Sooly :)
     
    Last edited: Apr 19, 2023
    Sooly likes this.
  4. Sooly

    Sooly

    Joined:
    Jan 28, 2021
    Posts:
    19
    Yep, but that explanation helps a lot either way, thanks a milion! That's a bit more elaborative than documentation and the flashy gifs there. :D
     
  5. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,341
    One note, the solution above will obviously fail when vectors are collinear/parallel (velocity up/down in this case), so you would need to add safe check like Orson did previously here.

    What you need is to recreate VFXSafeNormalizedCross:

    Code (CSharp):
    1. float3 VFXSafeNormalizedCross(float3 v1, float3 v2, float3 fallback)
    2. {
    3.     float3 outVec = cross(v1, v2);
    4.     outVec = dot(outVec, outVec) < VFX_EPSILON ? fallback : normalize(outVec);
    5.     return outVec;
    6. }
    As operator subgraph:
    upload_2023-4-20_15-13-2.png
     
    Sooly and OrsonFavrel like this.
  6. Sooly

    Sooly

    Joined:
    Jan 28, 2021
    Posts:
    19
    Good to know, cheers!