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

moving vertices in surface shader

Discussion in 'Shaders' started by Airship, Apr 23, 2013.

  1. Airship

    Airship

    Joined:
    Sep 10, 2011
    Posts:
    260
    I want to animate some trees/ foliage. I need them to all move in the same direction despite their rotation. It seems the vertices are moving in local object space not in world space so when a tree is rotated, the wind blows it in a different direction. Is this possible? I am looking at the docs and seeing ways to convert to different spaces like i.vertex = mul(_Object2World, i.vertex); but I am not sure what to use here. Thanks for any help.

    Code (csharp):
    1.    void vert( inout appdata_full i, out Input o )
    2.         {
    3.        float speed = _Time.y * _Speed;
    4.        i.vertex.x += _Bend * i.color.x * ((sin(speed)+.5)*.75);  
    5.         }
    6.        
     
  2. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    You'll need to take the vertex position into world space, apply the movement to the vertex position, then take it back into object space and apply it to the v.vertex attribute.

    Or - what's probably easier - calculate the movement then transform that from world space to object space and then apply it to the vertex attribute.
     
  3. Airship

    Airship

    Joined:
    Sep 10, 2011
    Posts:
    260
    Thank you! Don't get how to apply your second method but the first one proved easy.
    Code (csharp):
    1. i.vertex = mul(_Object2World, i.vertex);
    2.            i.vertex.x += _Bend * i.color.x * ((sin(speed)+.5)*.75);
    3.            i.vertex = mul(_World2Object, i.vertex);
     
  4. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Code (csharp):
    1. float4 offset = float4(0,0,0,1);
    2. offset.x += _Bend * i.color.x * ((sin(speed)+.5)*.75);
    3. v.vertex.xyz += mul(_World2Object, offset).xyz;
    4.  
    I think?

    Edit: Actually, as it's just a vector before you apply it to your vertex position you can simplify that a little.
    Code (csharp):
    1. float3 offset = float3(0,0,0);
    2. offset.x += _Bend * i.color.x * ((sin(speed)+.5)*.75);
    3. v.vertex.xyz += mul((float3x3)_World2Object, offset);
    4.  
     
    Last edited: Apr 24, 2013
  5. Sorry to be reviving an old thread, but this method makes it so that the vertices all move in a certain direction. I've tried to change this direction but I'm not being able to. Any ideas?
     
  6. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,687
    I think a naive modification like that should work somehow. (I haven’t tested this at all and I really haven’t read the thread – lol)
    _direction should be a float3

    Code (CSharp):
    1. amount = _Bend * i.color.x * ((sin(speed)+.5)*.75);
    2. float3 offset = lerp(float3(0,0,0), float3(amount, amount, amount), _direction);
    3. v.vertex.xyz += mul((float3x3)_World2Object, offset);
    4.  
     
  7. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    What's the purpose of the lerp? It looks like an expensive way of doing this:

    float3 offset = _direction * amount;
     
  8. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,687
    Yes, you are right.
     
  9. I'll take a look when i have time and let you know.

    Cheers
     
  10. This affects the speed... Any way around it?