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

Custom vegetation mesh wind sway?

Discussion in 'Scripting' started by Studio_Akiba, Mar 1, 2015.

  1. Studio_Akiba

    Studio_Akiba

    Joined:
    Mar 3, 2014
    Posts:
    1,421
    As we are using a custom mesh for my terrain, we are unable to add grass to it, so we are adding all our grass, plant textures and everything else to models, but these do not sway in the wind, does anyone have a small script for handling things like this, either to allow a Wind Zone to effect it or handle it independently with low performance requirements?
     
  2. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
  3. ensiferum888

    ensiferum888

    Joined:
    May 11, 2013
    Posts:
    317
    I recently found this shader:
    http://forum.unity3d.com/threads/shader-moving-trees-grass-in-wind-outside-of-terrain.230911/

    It's insanely fast, I always display 25 patches of grass around the camera (5 x 5) each patch contains 7500 combined grass planes or 60 000 vertices. That's about 1.5 millions vertices being animated and I still run the game well above 100FPS.

    It takes about 6 seconds to generate and combine 100 patches (enough to cover a 1km square terrain)
     
  4. ZenMicro

    ZenMicro

    Joined:
    Aug 9, 2015
    Posts:
    206
    Hi @ensiferum888, I was reading that thread just before and found this one as well, I created a shader from the last post in there by @watermy but there is a reference error SH_Vertex.cginc. Would you mind sharing your script?

    Have you used Advanced Foliage Shader v4 by forst? I beleive that is his most up to date shader for foliage so would be interested to know if anyone has used it and if it allows for syncing of wind with grass and custom trees, for $20 I might just have to buy it and test it myself.
     
  5. ensiferum888

    ensiferum888

    Joined:
    May 11, 2013
    Posts:
    317
    Hey ZenMicro,

    No I haven't used the AFS yet but I hear it's awesome. I am using his Snow Suite shader though for the snow on the trees, terrain and objects.

    Here's the shader I ended up with:

    Code (CSharp):
    1. Shader "Custom/Grass/GrassBending" {
    2. Properties {
    3.     _Color ("Main Color", Color) = (1,1,1,1)
    4.     _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    5.     _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
    6.     _ShakeDisplacement ("Displacement", Range (0, 1.0)) = 1.0
    7.     _ShakeTime ("Shake Time", Range (0, 1.0)) = 1.0
    8.     _ShakeWindspeed ("Shake Windspeed", Range (0, 1.0)) = 1.0
    9.     _ShakeBending ("Shake Bending", Range (0, 1.0)) = 1.0
    10. }
    11. SubShader {
    12.     Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
    13.     LOD 200
    14.     Cull Off
    15.  
    16. CGPROGRAM
    17. #pragma target 3.0
    18. #pragma surface surf Lambert alphatest:_Cutoff vertex:vert addshadow
    19. sampler2D _MainTex;
    20. fixed4 _Color;
    21. float _ShakeDisplacement;
    22. float _ShakeTime;
    23. float _ShakeWindspeed;
    24. float _ShakeBending;
    25. float dist;
    26. float _GrassAlpha;
    27. struct Input {
    28.     float2 uv_MainTex;
    29.     float3 worldPos;
    30. };
    31. void FastSinCos (float4 val, out float4 s, out float4 c) {
    32.     val = val * 6.408849 - 3.1415927;
    33.     float4 r5 = val * val;
    34.     float4 r6 = r5 * r5;
    35.     float4 r7 = r6 * r5;
    36.     float4 r8 = r6 * r5;
    37.     float4 r1 = r5 * val;
    38.     float4 r2 = r1 * r5;
    39.     float4 r3 = r2 * r5;
    40.     float4 sin7 = {1, -0.16161616, 0.0083333, -0.00019841} ;
    41.     float4 cos8  = {-0.5, 0.041666666, -0.0013888889, 0.000024801587} ;
    42.     s =  val + r1 * sin7.y + r2 * sin7.z + r3 * sin7.w;
    43.     c = 1 + r5 * cos8.x + r6 * cos8.y + r7 * cos8.z + r8 * cos8.w;
    44. }
    45. void vert (inout appdata_full v) {
    46.  
    47.     float factor = (1 - _ShakeDisplacement -  v.color.r) * 0.5;
    48.      
    49.     const float _WindSpeed  = (_ShakeWindspeed  +  v.color.g );  
    50.     const float _WaveScale = _ShakeDisplacement;
    51.  
    52.     const float4 _waveXSize = float4(0.048, 0.06, 0.24, 0.096);
    53.     const float4 _waveZSize = float4 (0.024, .08, 0.08, 0.2);
    54.     const float4 waveSpeed = float4 (1.2, 2, 1.6, 4.8);
    55.     float4 _waveXmove = float4(0.024, 0.04, -0.12, 0.096);
    56.     float4 _waveZmove = float4 (0.006, .02, -0.02, 0.1);
    57.  
    58.     float4 waves;
    59.     waves = v.vertex.x * _waveXSize;
    60.     waves += v.vertex.z * _waveZSize;
    61.     waves += _Time.x * (1 - _ShakeTime * 2 - v.color.b ) * waveSpeed *_WindSpeed;
    62.     float4 s, c;
    63.     waves = frac (waves);
    64.     FastSinCos (waves, s,c);
    65.     float waveAmount = v.texcoord.y * (v.color.a + _ShakeBending);
    66.     s *= waveAmount;
    67.     s *= normalize (waveSpeed);
    68.     s = s * s;
    69.     float fade = dot (s, 1.3);
    70.     s = s * s;
    71.     float3 waveMove = float3 (0,0,0);
    72.     waveMove.x = dot (s, _waveXmove);
    73.     waveMove.z = dot (s, _waveZmove);
    74.     v.vertex.xz -= mul ((float3x3)_World2Object, waveMove).xz;
    75.  
    76. }
    77. void surf (Input IN, inout SurfaceOutput o) {
    78.     fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color * _Color;
    79.     o.Albedo = c.rgb;
    80.     float dist = distance(_WorldSpaceCameraPos, IN.worldPos);
    81.     dist = clamp(dist / 300, 0.4, 1.0);
    82.     o.Alpha = c.a - dist - _GrassAlpha;
    83. }
    84. ENDCG
    85. }
    86. Fallback "Transparent/Cutout/VertexLit"
    87. }
     
  6. ZenMicro

    ZenMicro

    Joined:
    Aug 9, 2015
    Posts:
    206
    Mate!!!!! Thanks so much, I am kind of blown away (pun :p) that this short shader has done exactly what i couldn't get a paid asset to do (read: inquiring with asset developers with them telling my no can do)

    So thank you my man... It's the first time I've seen my custom mesh trees come to life!

    I made a very quick video.. but had to zip the mp4. Anyway Thanks again! I'd have paid $10 for that :D

    Note: that my player character has a bit of a sway going on as well, the leaves are the only things moving (not the trunks) but you'd know that as it's your work!
     

    Attached Files:

  7. ThisIsSparta

    ThisIsSparta

    Joined:
    May 4, 2014
    Posts:
    142
    I tried to use this shader with a more colpex model and it's not affecting all the model...someone knows why? Some foliages moves others not...
     
  8. graphicDNA

    graphicDNA

    Joined:
    Jun 26, 2017
    Posts:
    47
  9. jubaerjams8548

    jubaerjams8548

    Joined:
    Jun 8, 2020
    Posts:
    41
    is that technique good for mobile? i mean when implementing grass on ta vast area...
    and how to apply this technique of patches and combining ? can you please tell me?
     
  10. ensiferum888

    ensiferum888

    Joined:
    May 11, 2013
    Posts:
    317
    I wouldn't know I don't play/make mobile games, my initial impression would be no since with that technique I'm greatly lowering the drawcalls but I'm still sending over 1 million verts to the GPU.

    It's a rather complicated subject but the idea is split your world into regions and each region becomes a mesh. When the grass changes you simply rebuild the mesh I'm using the https://docs.unity3d.com/ScriptReference/Mesh.CombineMeshes.html functions to do that.

    That way you don't have to go through all the grass in your world just the region(s) affected.

    For the quad tree itself I used this tutorial (it's in p5.js) and simply recreated his code in C# it was surprisingly easy to follow along with no prior experience with that kind of data structure: