Search Unity

[Shader] Moving Trees Grass in Wind Outside of Terrain

Discussion in 'Assets and Asset Store' started by AustinRichards, Feb 26, 2014.

  1. AustinRichards

    AustinRichards

    Joined:
    Apr 4, 2013
    Posts:
    321
    Today I put together a shader that will make grass + trees move as if in the wind, without having anything to do with the terrain. It's base is the Transparent Cutout Diffuse shader. I figured I'd share it with you guys since I spent weeks looking for a good shader like this with no success, so I made it myself.

    Here is a video of the shader in action, in scene view applied to the leaf material of this tree:
    http://gyazo.com/0507d1048ead73b6b1cb0c3c6b7a96da.mp4

    The wind is customizable on each material so you can have the desired amount of movement.
    View attachment 88902

    There are TWO versions of the shader. The 1st one is similar to the Transparent Cutout Diffuse shader. the 2nd one has Illumination. It gives it a different look, some may prefer the second one for their tree leaves.

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

    jc_lvngstn

    Joined:
    Jul 19, 2006
    Posts:
    1,508
    Nice! Can you give the details on how the vertex colors affect wind? Just looking through the code, it looks like alpha affects shakebending and b is waves and g affects windspeed impact?
    Any clarification on that would be handy :)
     
  3. AustinRichards

    AustinRichards

    Joined:
    Apr 4, 2013
    Posts:
    321
    bump!!!!!!!!!
     
  4. crol

    crol

    Joined:
    Aug 6, 2013
    Posts:
    30
    Thx for sharing this shaders!
    $Diffuse Shake.png
    Im using them in this way)

    Any idea how to lower the distance between shadow and bush?
     
    Last edited: Apr 30, 2014
  5. Courvee Black

    Courvee Black

    Joined:
    Mar 15, 2013
    Posts:
    11
    Yes. This is all about shadow offset parameter in the light, you are using. Try to tweak it.
     
  6. Collider_nyc

    Collider_nyc

    Joined:
    Jan 13, 2014
    Posts:
    14
    Thanks @GambinoInd ! This works great! I saw a youtube video of someone doing something like this with Strumpy, but I like the simplicity of this (plus I think Strumpy is not updated for 4.3... don't quote me on that - I need to check further).
    Anyway, you saved me a lot of time trying to cobble together one of these myself, so thanks again! grassImage.png
    Grass test image.
     
  7. TitoOliveira

    TitoOliveira

    Joined:
    Aug 4, 2014
    Posts:
    79
    I hope it's ok to bring up an old thread like this, but i need to solve an issue regarding this shader.
    I was trying to find a way to animate the foliage in a 2D game i'm making. So i came across this shader solution and managed to make it work nicely on the 2D sprites i have.
    The thing is, after making it work, i assembled a tree i've painted for the background of the scenery. The tree is made up of 8 sprites in a spritesheet. 1 sprite its the trunk and the other 7 are groups of leaves that together makes the treetop. Theses 7 other sprites are assigned a new material with the shake shader. The issue is, 3 of them flow and shake realy nice, but the other 4 are almost stopped. Even if i crank up the ShakeBending those 4 sprites movement is almost imperceptible. This results in a treetop wich some areas move a lot and some barely move at all. Not a nice result.
    I tried to look around the code to understand it better, but i'm kinda newb in the "shader business". I was hoping someone could kindly help me out on this matter.
    Thanks for the time.
     
  8. termway

    termway

    Joined:
    Jul 5, 2012
    Posts:
    80
    Thank you, it's very usefull.

    I add your code to the built-in Tree Soft Occlusion Leaves to have leaves movement for imported terrain tree

    Code (CSharp):
    1. Shader "Nature/Tree Soft Occlusion Leaves" {
    2.     Properties {
    3.         _Color ("Main Color", Color) = (1,1,1,1)
    4.         _MainTex ("Main Texture", 2D) = "white" {  }
    5.         _Cutoff ("Alpha cutoff", Range(0.25,0.9)) = 0.5
    6.         _BaseLight ("Base Light", Range(0, 1)) = 0.35
    7.         _AO ("Amb. Occlusion", Range(0, 10)) = 2.4
    8.         _Occlusion ("Dir Occlusion", Range(0, 20)) = 7.5
    9.         _ShakeDisplacement ("Displacement", Range (0, 1.0)) = 1.0
    10.         _ShakeTime ("Shake Time", Range (0, 1.0)) = 1.0
    11.         _ShakeWindspeed ("Shake Windspeed", Range (0, 1.0)) = 1.0
    12.         _ShakeBending ("Shake Bending", Range (0, 1.0)) = 1.0
    13.  
    14.         // These are here only to provide default values
    15.         _Scale ("Scale", Vector) = (1,1,1,1)
    16.         _SquashAmount ("Squash", Float) = 1
    17.     }
    18.  
    19.     SubShader {
    20.         Tags {
    21.             "Queue" = "Transparent-99"
    22.             "IgnoreProjector"="True"
    23.             "RenderType" = "TreeTransparentCutout"
    24.         }
    25.         Cull Off
    26.         ColorMask RGB
    27.      
    28.         Pass {
    29.             Lighting On
    30.      
    31.             CGPROGRAM
    32.             #pragma vertex leavesCustom
    33.             #pragma fragment frag
    34.             #pragma glsl_no_auto_normalization
    35.             #include "SH_Vertex.cginc"
    36.          
    37.             float _ShakeDisplacement;
    38.             float _ShakeTime;
    39.             float _ShakeWindspeed;
    40.             float _ShakeBending;
    41.  
    42.             sampler2D _MainTex;
    43.             fixed _Cutoff;
    44.  
    45.  
    46.     void FastSinCos2 (float4 val, out float4 s, out float4 c) {
    47.         val = val * 6.408849 - 3.1415927;
    48.         float4 r5 = val * val;
    49.         float4 r6 = r5 * r5;
    50.         float4 r7 = r6 * r5;
    51.         float4 r8 = r6 * r5;
    52.         float4 r1 = r5 * val;
    53.         float4 r2 = r1 * r5;
    54.         float4 r3 = r2 * r5;
    55.         float4 sin7 = {1, -0.16161616, 0.0083333, -0.00019841} ;
    56.         float4 cos8  = {-0.5, 0.041666666, -0.0013888889, 0.000024801587} ;
    57.         s =  val + r1 * sin7.y + r2 * sin7.z + r3 * sin7.w;
    58.         c = 1 + r5 * cos8.x + r6 * cos8.y + r7 * cos8.z + r8 * cos8.w;
    59.     }
    60.  
    61.     v2f leavesCustom(appdata_tree v)
    62.     {  
    63.         float factor = (1 - _ShakeDisplacement -  v.color.r) * 0.5;
    64.      
    65.         const float _WindSpeed  = (_ShakeWindspeed  +  v.color.g );  
    66.         const float _WaveScale = _ShakeDisplacement;
    67.  
    68.         const float4 _waveXSize = float4(0.048, 0.06, 0.24, 0.096);
    69.         const float4 _waveZSize = float4 (0.024, .08, 0.08, 0.2);
    70.         const float4 waveSpeed = float4 (1.2, 2, 1.6, 4.8);
    71.         float4 _waveXmove = float4(0.024, 0.04, -0.12, 0.096);
    72.         float4 _waveZmove = float4 (0.006, .02, -0.02, 0.1);
    73.  
    74.         float4 waves;
    75.         waves = v.vertex.x * _waveXSize;
    76.         waves += v.vertex.z * _waveZSize;
    77.         waves += _Time.x * (1 - _ShakeTime * 2 - v.color.b ) * waveSpeed *_WindSpeed;
    78.         float4 s, c;
    79.         waves = frac (waves);
    80.         FastSinCos2 (waves, s,c);
    81.         float waveAmount = v.texcoord.y * (v.color.a + _ShakeBending);
    82.         s *= waveAmount;
    83.         s *= normalize (waveSpeed);
    84.         s = s * s;
    85.         float fade = dot (s, 1.3);
    86.         s = s * s;
    87.         float3 waveMove = float3 (0,0,0);
    88.         waveMove.x = dot (s, _waveXmove);
    89.         waveMove.z = dot (s, _waveZmove);
    90.         v.vertex.xz -= mul ((float3x3)_World2Object, waveMove).xz;
    91.      
    92.         v2f o;
    93.  
    94.         float3 viewpos = mul(UNITY_MATRIX_MV, v.vertex);
    95.         o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    96.         o.uv = v.texcoord;
    97.  
    98.         TerrainAnimateTree(v.vertex, v.color.w);
    99.      
    100.         float4 lightDir = 0;
    101.         float4 lightColor = 0;
    102.         lightDir.w = _AO;
    103.  
    104.         float4 light = UNITY_LIGHTMODEL_AMBIENT;
    105.  
    106.         for (int i = 0; i < 4; i++) {
    107.             float atten = 1.0;
    108.             #ifdef USE_CUSTOM_LIGHT_DIR
    109.                 lightDir.xyz = _TerrainTreeLightDirections[i];
    110.                 lightColor = _TerrainTreeLightColors[i];
    111.             #else
    112.                     float3 toLight = unity_LightPosition[i].xyz - viewpos.xyz * unity_LightPosition[i].w;
    113.                     toLight.z *= -1.0;
    114.                     lightDir.xyz = mul( (float3x3)_CameraToWorld, normalize(toLight) );
    115.                     float lengthSq = dot(toLight, toLight);
    116.                     atten = 1.0 / (1.0 + lengthSq * unity_LightAtten[i].z);
    117.              
    118.                     lightColor.rgb = unity_LightColor[i].rgb;
    119.             #endif
    120.  
    121.             lightDir.xyz *= _Occlusion;
    122.             float occ =  dot (v.tangent, lightDir);
    123.             occ = max(0, occ);
    124.             occ += _BaseLight;
    125.             light += lightColor * (occ * atten);
    126.         }
    127.  
    128.         o.color = light * _Color;
    129.         o.color.a = 0.5 * _HalfOverCutoff;
    130.  
    131.         return o;
    132.     }
    133.      
    134.  
    135.     fixed4 frag(v2f input) : SV_Target
    136.     {
    137.         fixed4 c = tex2D( _MainTex, input.uv.xy);
    138.         c.rgb *= 2.0f * input.color.rgb;
    139.              
    140.         clip (c.a - _Cutoff);
    141.              
    142.         return c;
    143.     }
    144.     ENDCG
    145. }
    146.      
    147.         Pass {
    148.             Name "ShadowCaster"
    149.             Tags { "LightMode" = "ShadowCaster" }
    150.          
    151.             Fog {Mode Off}
    152.             ZWrite On ZTest LEqual Cull Off
    153.             Offset 1, 1
    154.  
    155.             CGPROGRAM
    156.             #pragma vertex vert
    157.             #pragma fragment frag
    158.             #pragma glsl_no_auto_normalization
    159.             #pragma multi_compile_shadowcaster
    160.             #include "UnityCG.cginc"
    161.             #include "TerrainEngine.cginc"
    162.          
    163.             struct v2f {
    164.                 V2F_SHADOW_CASTER;
    165.                 float2 uv : TEXCOORD1;
    166.             };
    167.          
    168.             struct appdata {
    169.                 float4 vertex : POSITION;
    170.                 fixed4 color : COLOR;
    171.                 float4 texcoord : TEXCOORD0;
    172.             };
    173.             v2f vert( appdata v )
    174.             {
    175.                 v2f o;
    176.                 TerrainAnimateTree(v.vertex, v.color.w);
    177.                 TRANSFER_SHADOW_CASTER(o)
    178.                 o.uv = v.texcoord;
    179.                 return o;
    180.             }
    181.          
    182.             sampler2D _MainTex;
    183.             fixed _Cutoff;
    184.                  
    185.             float4 frag( v2f i ) : SV_Target
    186.             {
    187.                 fixed4 texcol = tex2D( _MainTex, i.uv );
    188.                 clip( texcol.a - _Cutoff );
    189.                 SHADOW_CASTER_FRAGMENT(i)
    190.             }
    191.             ENDCG  
    192.         }
    193.     }
    194.  
    195.     // This subshader is never actually used, but is only kept so
    196.     // that the tree mesh still assumes that normals are needed
    197.     // at build time (due to Lighting On in the pass). The subshader
    198.     // above does not actually use normals, so they are stripped out.
    199.     // We want to keep normals for backwards compatibility with Unity 4.2
    200.     // and earlier.
    201.     SubShader {
    202.         Tags {
    203.             "Queue" = "Transparent-99"
    204.             "IgnoreProjector"="True"
    205.             "RenderType" = "TransparentCutout"
    206.         }
    207.         Cull Off
    208.         ColorMask RGB
    209.         Pass {
    210.             Tags { "LightMode" = "Vertex" }
    211.             AlphaTest GEqual [_Cutoff]
    212.             Lighting On
    213.             Material {
    214.                 Diffuse [_Color]
    215.                 Ambient [_Color]
    216.             }
    217.             SetTexture [_MainTex] { combine primary * texture DOUBLE, texture }
    218.         }      
    219.     }
    220.  
    221.     Dependency "BillboardShader" = "Hidden/Nature/Tree Soft Occlusion Leaves Rendertex"
    222.     Fallback Off
    223. }
    224.  
     
  9. Dolkar

    Dolkar

    Joined:
    Jun 8, 2013
    Posts:
    576
    Why define your own sincos function? I doubt that whatever implementation you have there will outperform the built-in sincos(), which could even be engineered into the hardware.
     
  10. marcvp1988

    marcvp1988

    Joined:
    Dec 15, 2014
    Posts:
    3
    Many thanks Gambinolnd!
    Can you give an answer to this? Looks like the sader works without painting any vertex-colors though... Can you explain how does the shader work in regard to the vertex colors?

    Thanks again!
     
  11. AustinRichards

    AustinRichards

    Joined:
    Apr 4, 2013
    Posts:
    321
    To be honest I kind of just pieced together scripts that i found to produce this. I'm not great with shaders. Can't answer your question haha
     
  12. marcvp1988

    marcvp1988

    Joined:
    Dec 15, 2014
    Posts:
    3
    Well, since I discovered how does the wind works with "detail mesh" along with the default hidden/grass shader, I ended up using "detail mesh" in the terrain. Good thing is that, if you use terrain "detail mesh" as grass you can still benefit from the detail distance fade out, which is very nice and optimizes your scene.

    Here's the way:
    - Create whatever you like in your 3d app, say 10 X-shaped patches of grass scattered around
    - Still in the 3d app, paint the mesh using grayscale in the color vertex alpha (vertex paint)
    - Import the mesh to unity
    - In your unity terrain object, set the imported mesh as "detail mesh" and use "grass" as render mode.
    - Now your mesh bends with the terrain wind properties

    Detail meshes can't have edge turbulence (like tree/leaves or tree/fronds) by default, so it can only be used with meshes that you want to be bending without shaking (grass-like).
     
  13. ensiferum888

    ensiferum888

    Joined:
    May 11, 2013
    Posts:
    317
    Using this shader with my own grass placement system it works super fast and was very easy to setup. I modified the shader to fade based on camera distance. Thank you so much for giving this shader to the community!!

     
  14. Vintage_Green

    Vintage_Green

    Joined:
    Mar 27, 2015
    Posts:
    22
    do you still have that modified shader?
     
  15. ensiferum888

    ensiferum888

    Joined:
    May 11, 2013
    Posts:
    317
    Yes I'm not home at the moment but it's exactly he same shader except o.Alpha is detemined by the camera distance. I'll look it up tonight and give you the code, but it's a simple modification from the above shader.
     
  16. Vintage_Green

    Vintage_Green

    Joined:
    Mar 27, 2015
    Posts:
    22
    awesome man no rush and thanks alot :)
     
  17. AdowTatep

    AdowTatep

    Joined:
    Feb 5, 2015
    Posts:
    6
    Hi! Can you help me on how to use it? I created a Shader archive and put the code in there, then in the materials of my tree i set to this custom one, but doesn't work :(
     
  18. belamessex

    belamessex

    Joined:
    May 12, 2015
    Posts:
    12
    Hey thanks for the shader code. Exactly what I was looking for. Just need to randomize the movement a little bit and it will be perfect.
     
  19. RustySly

    RustySly

    Joined:
    Dec 12, 2015
    Posts:
    1
    Hey, thanks for the great solution! Just wondering how to randomize the movement; belamessex have you managed to do it and if you have, could you share it please?
     
  20. TheGabelle

    TheGabelle

    Joined:
    Aug 23, 2013
    Posts:
    242
    Excellent!

    I have no experience with shaders. I'm hoping to tweak this shader so foliage is double-sided and the shake / warping responds appropriately to directional and spherical wind.

    Any ideas on where to start?
     
  21. Eudaimonium

    Eudaimonium

    Joined:
    Dec 22, 2013
    Posts:
    131
    Hi,

    Apologies for resurrecting an old thread. I hope this is not frowned upon.

    I have re-worked the shader by GambinoInd to use standard vertex + frag programs instead of Surface shading. I am targeting very low hardware requirements and would like to simplify the shader.

    I would like to implement additional coloring of the fragments by accessing baked in AO data of the mesh so that the trees and foliage would be ... "prettier" for lack of better term. See screenshots. For now, shading is pretty flat:

    NotVeryPretty.jpg

    As you can see here, using the SpeedTree shader brings out the color variation and apparent "shadowed" leaves and branches:

    MuchBetter.jpg

    I thought they have the AO data baked into the Vertex colors but vertex colors are all white across the mesh. How does the speedtree shader bring out the brightness variety?

    As to why I'm not using the SpeedTree shader, it's because it isn't batched, whereas this shader apparently is. Speed tree produces "Saved by batching: 0" whereas this one produces numbers in range of dozens where everything except trees is culled out of camera view.

    This is my progress so far:

    http://pastebin.com/j00qT1Qz

    Operative part being this:
    Code (CSharp):
    1. half4 surf(v2f IN) : SV_Target
    2.         {
    3.             float4 color = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    4.             clip(color.a - _Cutoff);
    5.             return color * IN.color;
    6.             //return half4(IN.uv_MainTex.x, IN.uv_MainTex.y, 0, 1);
    7.         }
    Apparently IN.color makes little difference since color is white across the mesh (checked).

    How do I accomplish the brightness difference that SpeedTree shader does?

    Thank you all in advance!
     
  22. gurayg

    gurayg

    Joined:
    Nov 28, 2013
    Posts:
    269
    Hi @Eudaimonium
    I can not help you with the shader part but if you can use the incoming Unity 5.4 with your project you might be in luck.

    Unity Roadmap shows there is new feature called "Basic GPU Instancing"
    which has "Enhanced Standard shader & SpeedTree shader with instancing support."
    with notes for mobile as "mobile platforms support might come in 5.4."

    So you might want to try the 5.4 Beta and see what happens.
    Good luck!
     
  23. Eudaimonium

    Eudaimonium

    Joined:
    Dec 22, 2013
    Posts:
    131
    Hmm, I am not very inclined to try out Beta before it's ready, I will wait for the official 5.4 release - but until then I need to figure out something. Thanks!
     
  24. QuantumTheory

    QuantumTheory

    Joined:
    Jan 19, 2012
    Posts:
    1,081
    Any chance this can work in deferred? Buffers are wonky..
     
  25. Zante

    Zante

    Joined:
    Mar 29, 2008
    Posts:
    429
    Any way to get this working with 2D sprites?
     
  26. jeremiahlangner

    jeremiahlangner

    Joined:
    Oct 30, 2016
    Posts:
    2
    Set up your sprite as a 3d quad; add the shader in the material, then set the texture to the image of a sprite you would be using otherwise.
     
    Zante likes this.
  27. Zehru

    Zehru

    Joined:
    Jun 19, 2015
    Posts:
    84
  28. Adamantius

    Adamantius

    Joined:
    Apr 28, 2014
    Posts:
    7
    GambinoInd, you sir are a legend. This has made my nature scenes look so much better and fluid. Thank you for this and well done!
     
  29. nu51313932

    nu51313932

    Joined:
    Oct 28, 2016
    Posts:
    81
    Zehru, Thank you so much. This is what I am looking for.
    The one variable that I don't understand is "k".What is "k" in the code?
     
  30. Zehru

    Zehru

    Joined:
    Jun 19, 2015
    Posts:
    84
    I didn't finish implementing this on my project yet, but it seems that this is a reference from the player on the blog creator's script. So, it probably can be changed with your reference to the player( in this case, he is using layers, but you can maybe use tags, or the name of the Player gameobject)
     
  31. Zehru

    Zehru

    Joined:
    Jun 19, 2015
    Posts:
    84
    also, the "map" variable, is part of Prime31 free asset(you can get it on github) called utilityKit.
     
  32. KarlKarl2000

    KarlKarl2000

    Joined:
    Jan 25, 2016
    Posts:
    606
    You sir a the new God! Thanks for sharing this

    Sharing is caring

    https://twitter.com/IndieNendoroid
     
  33. Zehru

    Zehru

    Joined:
    Jun 19, 2015
    Posts:
    84
    @indieNendoroid I'm happy that I could help.
    and heheh, I surely don't deserve been called God ^^
     
  34. KarlKarl2000

    KarlKarl2000

    Joined:
    Jan 25, 2016
    Posts:
    606
    Last edited: Feb 10, 2017
  35. KarlKarl2000

    KarlKarl2000

    Joined:
    Jan 25, 2016
    Posts:
    606
  36. EnlightenedOne

    EnlightenedOne

    Joined:
    Jun 17, 2015
    Posts:
    14
    I love this I want to use it on grass and leaves in my scene, any chance you can shove a license on it to clear up if this is public, MIT or for personal use only?
     
  37. intaj_cse

    intaj_cse

    Joined:
    Nov 25, 2014
    Posts:
    10
    hi @ensiferum888, i know , its so long, but do u have this modified shader code .
    i want the same grass effect for my game. can u please share me the code.

    Thanks in advance.
     
  38. Thorno

    Thorno

    Joined:
    Jun 16, 2017
    Posts:
    2
     
  39. Thorno

    Thorno

    Joined:
    Jun 16, 2017
    Posts:
    2
    Hello all.
    I am new at all this. So my question may sound silly to most of you experienced guys ;)
    Here is the thing, i copied each script and pasted it into a new script in Unity (each one into a separate script).
    As soon as i try to add these scripts on to an object i am confronted with a message telling me that i have to fix compile errors first. As said, i am new at all of this so i have no idea how to fix these errors. I mean, i know how to edit the script but i have no idea to what i should change those errors into. Can any one tell me hat i am doing wrong and how i can fix these errors?
     
  40. mbbmbbmm

    mbbmbbmm

    Joined:
    Dec 28, 2013
    Posts:
    59
    @Thorno These are shaders, not C# scripts. In your project window, click on Create and then Shader> Standard surface shader. Then open the newly created shader with your IDE or text editor, and replace the contents with the new code. Save and go back to Unity. Right-click on the shader and select Create>Material. Now you should have a material using the new shader and you can drag it onto a 3d object in the scene.
     
  41. Renan-Bomtempo

    Renan-Bomtempo

    Joined:
    May 1, 2017
    Posts:
    13
    Hello everyone.
    I'm one year into the world of Game Development, and I'm currently working on my second game.
    I needed a shader that I could use to simulate wind on Low Poly Assests (Trees, grass, etc), but I couldn't find one.

    But then, I found AustinRichards's shader and thought it would be usefull for my project. I was having a problem that it would rip my mesh appart while manipulating its vertices, and so I abandoned it and went on to develop my own Vertex/Fragment Shader.
    I was sucessful on manipulating the vertices the way I wanted in the Vertex Shader, but I couldn't get the lighting to work correctly.

    So then, I went back to AustinRichards's shader and decided to use it as a base for my Shader. After some tweaking I finally got it to work both on manipulating the vertices and correctly illuminating the assets.

    I'm currently improving some other aspects of it. But when I'm done, I plan on making it available for anyone who wants to use it.

    So I'm here to thank this thread and specially AustinRichards for sharing he's shader, that made it possible for me to learn more about Shader programming and to develop one.

    Note: This is the result I achieved so far: Low Poly Wind Demo.gif
     
    Last edited: Sep 7, 2017
  42. KarlKarl2000

    KarlKarl2000

    Joined:
    Jan 25, 2016
    Posts:
    606
    Amazing work!! Thanks so much for sharing. This is what makes the Unity community better than the rest

     
    Renan-Bomtempo likes this.
  43. AustinRichards

    AustinRichards

    Joined:
    Apr 4, 2013
    Posts:
    321
    Cool to see people used the shader as a base and have found it useful :D.
     
    nxrighthere and Renan-Bomtempo like this.
  44. SomerenV

    SomerenV

    Joined:
    Dec 20, 2011
    Posts:
    83
    Any progress on this shader? It looks really neat and it's perfect for my own low poly assets:
     
    Renan-Bomtempo likes this.
  45. Renan-Bomtempo

    Renan-Bomtempo

    Joined:
    May 1, 2017
    Posts:
    13
    Wow! Those models are incredibly beautifull!
    As soon as I get some things done, I'll notify you.
     
  46. KarlKarl2000

    KarlKarl2000

    Joined:
    Jan 25, 2016
    Posts:
    606
    HI Renan-Bomtempo, Does your shader work on simple sprite images? Or just on 3d objects?
    Thanks!
     
  47. Bizulka

    Bizulka

    Joined:
    Oct 12, 2016
    Posts:
    1
    Hello, can you share what you achive? :oops::oops::oops: I very bad with shaders, but very need these effect too. :(
     
  48. sarahnorthway

    sarahnorthway

    Joined:
    Jul 16, 2015
    Posts:
    78
    I had trouble using this shader with batching in Unity 2017.3. When Unity adds or removes a sprite to the batch, it changes the local position (v.vertex) which is used in the wave calculation. So any time a piece of grass moves offscreen, the other sprites in the batch change to a different wave orientation.

    Fixed by using world position to determine wave size, and by including Y axis when adjusting waveMove to world position. I also use transparent edges instead of an alpha cutoff.

    Updated shader:

    Code (CSharp):
    1.  
    2. // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
    3. // from 2017.1.1 built-in Sprites-Diffuse Shader
    4. // and https://forum.unity.com/threads/shader-moving-trees-grass-in-wind-outside-of-terrain.230911/
    5. Shader "Northway/SpritesDiffuseWave" {
    6.     Properties {
    7.         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    8.         _Color ("Tint", Color) = (1,1,1,1)
    9.         [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
    10.         [HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1)
    11.         [HideInInspector] _Flip ("Flip", Vector) = (1,1,1,1)
    12.         [PerRendererData] _AlphaTex ("External Alpha", 2D) = "white" {}
    13.         [PerRendererData] _EnableExternalAlpha ("Enable External Alpha", Float) = 0
    14.         _ShakeDisplacement ("Displacement", Range (0, 1.0)) = 1.0
    15.         _ShakeTime ("Shake Time", Range (0, 1.0)) = 1.0
    16.         _ShakeWindspeed ("Shake Windspeed", Range (0, 1.0)) = 1.0
    17.         _ShakeBending ("Shake Bending", Range (0, 1.0)) = 1.0
    18.     }
    19.  
    20.     SubShader {
    21.         Tags {
    22.             "Queue"="Transparent"
    23.             "IgnoreProjector"="True"
    24.             "RenderType"="Transparent"
    25.             "PreviewType"="Plane"
    26.             "CanUseSpriteAtlas"="True"
    27.         }
    28.  
    29.         Cull Off
    30.         Lighting Off
    31.         ZWrite Off
    32.         Blend One OneMinusSrcAlpha
    33.  
    34.         CGPROGRAM
    35.         #pragma surface surf Lambert vertex:vert nofog nolightmap nodynlightmap keepalpha noinstancing
    36.         #pragma multi_compile _ PIXELSNAP_ON
    37.         #pragma multi_compile _ ETC1_EXTERNAL_ALPHA
    38.         #include "UnitySprites.cginc"
    39.        
    40.         float _ShakeDisplacement;
    41.         float _ShakeTime;
    42.         float _ShakeWindspeed;
    43.         float _ShakeBending;
    44.  
    45.         struct Input {
    46.             float2 uv_MainTex;
    47.             fixed4 color;
    48.         };
    49.        
    50.         void FastSinCos (float4 val, out float4 s, out float4 c) {
    51.             val = val * 6.408849 - 3.1415927;
    52.             float4 r5 = val * val;
    53.             float4 r6 = r5 * r5;
    54.             float4 r7 = r6 * r5;
    55.             float4 r8 = r6 * r5;
    56.             float4 r1 = r5 * val;
    57.             float4 r2 = r1 * r5;
    58.             float4 r3 = r2 * r5;
    59.             float4 sin7 = {1, -0.16161616, 0.0083333, -0.00019841} ;
    60.             float4 cos8  = {-0.5, 0.041666666, -0.0013888889, 0.000024801587} ;
    61.             s =  val + r1 * sin7.y + r2 * sin7.z + r3 * sin7.w;
    62.             c = 1 + r5 * cos8.x + r6 * cos8.y + r7 * cos8.z + r8 * cos8.w;
    63.         }
    64.  
    65.         void vert (inout appdata_full v, out Input o) {
    66.             v.vertex.xy *= _Flip.xy;
    67.  
    68.             #if defined(PIXELSNAP_ON)
    69.             v.vertex = UnityPixelSnap (v.vertex);
    70.             #endif
    71.  
    72.             float4 color = v.color;
    73.  
    74.             // waving
    75.             float factor = (1 - _ShakeDisplacement - color.r) * 0.5;
    76.             const float _WindSpeed  = (_ShakeWindspeed  + color.g );
    77.             const float _WaveScale = _ShakeDisplacement;
    78.             const float4 _waveXSize = float4(0.048, 0.06, 0.24, 0.096);
    79.             const float4 _waveZSize = float4 (0.024, .08, 0.08, 0.2);
    80.             const float4 waveSpeed = float4 (1.2, 2, 1.6, 4.8);
    81.             float4 _waveXmove = float4(0.024, 0.04, -0.12, 0.096);
    82.             float4 _waveZmove = float4 (0.006, .02, -0.02, 0.1);
    83.            
    84.             float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
    85.             float4 waves;
    86.             waves = worldPos.x * _waveXSize;
    87.             waves += worldPos.z * _waveZSize;
    88.  
    89.             waves += _Time.x * (1 - _ShakeTime * 2 - v.color.b ) * waveSpeed *_WindSpeed;
    90.             waves = frac (waves);
    91.             float4 s, c;
    92.             FastSinCos (waves, s,c);
    93.             float waveAmount = v.texcoord.y * (color.a + _ShakeBending);
    94.             s *= waveAmount;
    95.             s *= normalize (waveSpeed);
    96.             s = s * s;
    97.             float fade = dot (s, 1.3);
    98.             s = s * s;
    99.             float3 waveMove = float3 (0,0,0);
    100.             waveMove.x = dot (s, _waveXmove);
    101.             waveMove.z = dot (s, _waveZmove);
    102.  
    103.             v.vertex.xyz -= mul(unity_WorldToObject, waveMove).xyz;
    104.  
    105.             UNITY_INITIALIZE_OUTPUT(Input, o);
    106.             o.color = v.color * _Color * _RendererColor;
    107.         }
    108.  
    109.         void surf (Input IN, inout SurfaceOutput o) {
    110.             fixed4 c = SampleSpriteTexture (IN.uv_MainTex) * IN.color;
    111.             o.Albedo = c.rgb * c.a;
    112.             o.Alpha = c.a;
    113.         }
    114.         ENDCG
    115.     }
    116.  
    117.     Fallback "Transparent/VertexLit"
    118. }
    119.  
    120.  
     
    aymen-Wiz, Kojote, Grimbyte and 9 others like this.
  49. aymric

    aymric

    Joined:
    Feb 22, 2018
    Posts:
    2
    Hey thank you Austin for this shader share ! And thank you Sarah, I'm really happy of the result in my project with your update. A question : is it mobile-friendly or mobile-overkill ?
     
  50. OmarVector

    OmarVector

    Joined:
    Apr 18, 2018
    Posts:
    130
    Yes its monile friendly, however, dont go crazy with the number of trees and grasses, I tested on around 12 tress for top down game and it worked like charm.