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

A waving texture?

Discussion in 'Shaders' started by Marscaleb, May 22, 2014.

  1. Marscaleb

    Marscaleb

    Joined:
    Jan 7, 2014
    Posts:
    1,036
    Does anyone know how to make a waving texture?

    I'm actually working with a 2D game and I've not worked with materials in Unity before, but I'm thinking I could really use some sort of waving effect on this one tile to animate it.

    Something like this: http://youtu.be/IlqcEvX4MCI?t=9s
    Or if I could just have it wave in the X axis, that would work too.

    I have no idea how to go about doing this though. Is this even possible?
     
  2. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,589
    This looks like UV distortion to me. If you have a rather evenly tessellated grid, just add an offset to each vertex UV using sin/cos functions in the vertex shader for example. Use the original UV's also as input for sin/cos to make it look more chaotic, as well as _Time to get the animation.

    Rather than per vertex UV distortion, you can could also use per-pixel distortion as shown in the following presentation, starting at slide 36: http://www.gdcvault.com/play/1015898...Up-Our-Sleeves

    Edit: Since I'm a fan of distortion shaders, I couldn't resist to throw together a quick example. Assign a material with the following shader to a Plane GameObject and it looks like this:



    Code (csharp):
    1.  
    2. Shader "Custom/NewShader" {
    3.     Properties {
    4.         _MainTex ("Base (RGB)", 2D) = "white" {}
    5.     }
    6.     SubShader {
    7.         Tags { "RenderType"="Opaque" }
    8.         LOD 200
    9.      
    10.         CGPROGRAM
    11.         #pragma surface surf Lambert vertex:vert
    12.  
    13.         sampler2D _MainTex;
    14.         float4 _MainTex_ST;
    15.  
    16.         struct Input {
    17.             float2 st_MainTex;
    18.         };
    19.  
    20.         void vert (inout appdata_full v, out Input o)
    21.         {
    22.             UNITY_INITIALIZE_OUTPUT(Input,o);
    23.  
    24.             o.st_MainTex = TRANSFORM_TEX(v.texcoord, _MainTex);
    25.  
    26.             // add distortion
    27.             // this is the part you need to modify, i  recomment to expose such
    28.             // hard-coded values to the inspector for easier tweaking.
    29.             o.st_MainTex.x += sin((o.st_MainTex.x+o.st_MainTex.y)*8 + _Time.g*1.3)*0.01;
    30.             o.st_MainTex.y += cos((o.st_MainTex.x-o.st_MainTex.y)*8 + _Time.g*2.7)*0.01;
    31.         }
    32.  
    33.         void surf (Input IN, inout SurfaceOutput o) {
    34.             half4 c = tex2D (_MainTex, IN.st_MainTex);
    35.             o.Albedo = c.rgb;
    36.             o.Alpha = c.a;
    37.         }
    38.         ENDCG
    39.     }
    40.     FallBack "Diffuse"
    41. }
    42.  
    43.  
    Hope it helps!
     
    Last edited: Feb 4, 2015
    jhocking likes this.
  3. Marscaleb

    Marscaleb

    Joined:
    Jan 7, 2014
    Posts:
    1,036
    I know this was a month ago, but after I got that answer I realized I had no idea what I was doing with shaders.
    I'm just now starting to learn them.

    I tried plugging that shader into my game, but it does nothing.
    What am I doing wrong?
     
  4. mouurusai

    mouurusai

    Joined:
    Dec 2, 2011
    Posts:
    350
    Maybe your grid does not have enough vertex count (something like a 4 vertices plane)?
    Try move the changing of coordinates part in the surface block, something like this:
    void surf (Input IN, inout SurfaceOutput o) {
    IN.st_MainTex.x + = sin ((o.st_MainTex.x + o.st_MainTex.y) * 8 + _Time.g * 1.3) * 0.01;
    IN.st_MainTex.y + = cos ((o.st_MainTex.xo.st_MainTex.y) * 8 + _Time.g * 2.7) * 0.01;
    half4 c = tex2D (_MainTex, IN.st_MainTex);
    o.Albedo = c.rgb;
    o.Alpha = c.a;
    }
     
  5. Marscaleb

    Marscaleb

    Joined:
    Jan 7, 2014
    Posts:
    1,036
    I tried using it on a default plane, but it still didn't have any effect.

    I tried replacing the surf function with the one you posted and the material broke and turned into magenta.
     
  6. mouurusai

    mouurusai

    Joined:
    Dec 2, 2011
    Posts:
    350
    It's should work fine:
    Code (csharp):
    1.  
    2. Shader "Custom/NewShader" {
    3.     Properties {
    4.         _MainTex ("Base (RGB)", 2D) = "white" {}
    5.         _SpeedX("SpeedX", float)=3.0
    6.         _SpeedY("SpeedY", float)=3.0
    7.         _Scale("Scale", range(0.005, 0.2))=0.03
    8.         _TileX("TileX", float)=5
    9.         _TileY("TileY", float)=5
    10.     }
    11.     SubShader {
    12.         Tags { "RenderType"="Opaque" }
    13.         LOD 200
    14.        
    15.         CGPROGRAM
    16.         #pragma surface surf Lambert
    17.  
    18.         sampler2D _MainTex;
    19.         float4 uv_MainTex_ST;
    20.  
    21.         float _SpeedX;
    22.         float _SpeedY;
    23.         float _Scale;
    24.         float _TileX;
    25.         float _TileY;
    26.  
    27.         struct Input {
    28.             float2 uv_MainTex;
    29.         };
    30.  
    31.  
    32.         void surf (Input IN, inout SurfaceOutput o)
    33.         {
    34.             float2 uv = IN.uv_MainTex;
    35.             uv.x += sin ((uv.x+uv.y)*_TileX+_Time.g *_SpeedX)*_Scale;
    36.             uv.x += cos (uv.y*_TileY+_Time.g *_SpeedY)*_Scale;
    37.  
    38.             half4 c = tex2D (_MainTex, uv);
    39.             o.Albedo = c.rgb;
    40.             o.Alpha = c.a;
    41.         }
    42.         ENDCG
    43.     }
    44.     FallBack "Diffuse"
    45. }
    46.  
    47.  
     
    RomanSpai and jhocking like this.
  7. Marscaleb

    Marscaleb

    Joined:
    Jan 7, 2014
    Posts:
    1,036
    Hey, it's fantastic!
    Easy-to-tweak variables, and it even runs on my android!
    The only thing I need now is to make it unlit.
     
  8. SBull

    SBull

    Joined:
    Jun 1, 2013
    Posts:
    6
    This shader works great for 2D water. I'm not that familiar with shaders however and am wondering how one could add transparency to this.
     
  9. jhocking

    jhocking

    Joined:
    Nov 21, 2009
    Posts:
    813
    (This is really old but I just found it, so answering in case anyone still cares)

    See where it says o.Alpha near the bottom? Instead of just setting that to c.a, set it to c.a*_Opacity, with _Opacity being another range slider like _Scale, only ranging 0 to 1.

    Or, I guess that's not even necessary if you put alpha transparency in the texture. Meanwhile, the depth sorting needs to be adjusted so that it'll display transparent. So replace the Tags line with:

    Tags { "RenderType"="Transparent" "Queue"="Transparent" }
    ZWrite Off
    Blend SrcAlpha OneMinusSrcAlpha
     
    Last edited: Aug 31, 2019
  10. Marscaleb

    Marscaleb

    Joined:
    Jan 7, 2014
    Posts:
    1,036
    I actually do appreciate getting an answer to this issue. Of course, Unity has changed so much since then that the effect I was trying to create is no longer relevant through this process; there are better ways to achieve what I want.
    But it is actually pleasing to see an answer to this problem I had way back when.
    And hey, maybe I will want to use this effect in a future project.