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

Simple animated UV's?

Discussion in 'Shaders' started by cres64, Jun 6, 2009.

  1. cres64

    cres64

    Joined:
    Apr 27, 2009
    Posts:
    39
    I've been looking for a simple animated uv shader
    similar to the water but without all of the fancy stuff. Just need to have animated uv coordinates.
    Does anyone have one?
    Thanks
    Josh
     
  2. f3rDz

    f3rDz

    Joined:
    May 15, 2009
    Posts:
    15
    there are some videos about shaders from unite08 done by amir. later part of the video shows how to do this.
     
  3. cres64

    cres64

    Joined:
    Apr 27, 2009
    Posts:
    39
    going through that video now... also found another one that was this, but I couldn't get it to work.
    var scrollSpeed = 0.5;
    function Update() {
    var offset = Time.time * scrollSpeed;
    renderer.material.mainTextureOffset = Vector2 (offset%1,0)
    }
     
  4. Ramen Sama

    Ramen Sama

    Joined:
    Mar 28, 2009
    Posts:
    561
  5. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    That's not a shader, that's a script (also, it works fine). You don't need a shader to do UV animation.

    --Eric
     
  6. cres64

    cres64

    Joined:
    Apr 27, 2009
    Posts:
    39
    thanks!
    I got the rotation one to work, but I'm getting an error on the movement script.
     
  7. cres64

    cres64

    Joined:
    Apr 27, 2009
    Posts:
    39
    works now. Here it is for future posterity:
    ___________________________________

    var scrollSpeed :float = 0.5;
    var u : boolean = false;
    var v : boolean = false;

    function Update () {
    var offset : float = Time.time * scrollSpeed % 1;
    if (u == true v == true)
    {
    renderer.material.SetTextureOffset ("_MainTex", Vector2(offset,offset));
    }
    else if (u == true)
    {
    renderer.material.SetTextureOffset ("_MainTex", Vector2(offset,0));
    }
    else if (v == true)
    {
    renderer.material.SetTextureOffset ("_MainTex", Vector2(0,offset));
    }


    }
     
    Ali-Nagori and twobob like this.
  8. ng.aniki

    ng.aniki

    Joined:
    Jan 6, 2010
    Posts:
    3
    Is it possible to do something similar directly in the shader ?

    For exemple, I'm willing to animate only the uv offset for one of the textures on my object (a mask), and I would like to do that automatically for every models that has this material.

    It could be really more clean to do it in the shader (if it is possible), than associating a script to every models that has this material, or to create a loop which will check every models to find the ones that has this material, or anything else.
     
  9. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Just animate renderer.sharedMaterial in one script, and it will animate everything that's using the same material. Animating renderer.material makes a duplicate scene material and animates that. So if you have 10 scripts animating renderer.material, you actually end up with 10 materials, not 1. With sharedMaterial, you keep it down to just 1 only.

    --Eric
     
  10. ng.aniki

    ng.aniki

    Joined:
    Jan 6, 2010
    Posts:
    3
    Oh, thank you for the tip ! Could be really useful !
     
  11. Zante

    Zante

    Joined:
    Mar 29, 2008
    Posts:
    429
    How can this script be edited to scroll a bump map?
     
  12. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Replace "_MainTex" with the name of the bumpmap property. This is "_BumpMap" for all built-in shaders.
     
  13. Dover8

    Dover8

    Joined:
    Aug 20, 2010
    Posts:
    94
    Ok, I really DO need to do this in the shader, anyone actually know how to?
     
  14. Dover8

    Dover8

    Joined:
    Aug 20, 2010
    Posts:
    94
    What I have:
    Code (csharp):
    1.  
    2. Shader "UV Scroll" {
    3.     Properties {
    4.         _offset ("Scroll Speed", Range (-0.99, 0.99)) = 0.99
    5.         _Color ("Main Color", Color) = (1,1,1,1)
    6.         _MainTex ("Base (RGB)", 2D) = "white" {}
    7.         _BumpMap ("Bump (RGB) Illumin (A)", 2D) = "bump" {}
    8.     }
    9.     SubShader {
    10.         Pass{
    11. CGPROGRAM
    12. #pragma vertex vert
    13. #include "UnityCG.cginc"
    14.  
    15. struct v2f{
    16.     float4 uv : TEXCOORD0;
    17.     float3 color : COLOR;
    18. };
    19.        
    20. v2f vert (appdata_base v) {
    21.     v2f o;
    22.     o.uv = float4(v.texcoord.x + _offset,v.texcoord.y +  _offset, 0, 1);
    23.     return o;
    24. }
    25. ENDCG
    26.         }
    27.     }
    28.     FallBack "Diffuse"
    29. }
    30.  
    Errors I get:

    Cg in program 'vert': error C0000: syntax error, unexpected identifier, expecting ';' or ',' at token "vert" at line 20

    Cg in program 'vert': error C0501: type name expected at token "vert" at line 20

    Cg in program 'vert': error C1002: the name "v2f" is already defined at (15) at line 20

    Cg in program 'vert': error C1016: expression type incompatible with function return type at line 23

    Cg in program 'vert': warning C7011: implicit cast from "float4" to "float3" at line 79

    My CG is a little rusty, and I don't know where it's getting line 79 from when the shader only has 28 lines in it. Any help would be greatly appreciated.
     
    Last edited: Apr 13, 2011
  15. Dover8

    Dover8

    Joined:
    Aug 20, 2010
    Posts:
    94
    (doh) I should have known that. Well I had had one there at some point, don't know where it went.

    Now I can't pick up my offset variable, have edited the above code with the last fix.

    Edit: worked that one out, soldiering on now. Thanks for the help
     
    Last edited: Apr 13, 2011
  16. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    All the built-in shaders have scaling and tiling properties for their textures. You don't need to write a shader to add an offset: it's already there.
     
    Girish-sruthkia likes this.
  17. rapidlaser

    rapidlaser

    Joined:
    Jul 11, 2011
    Posts:
    2
    I have been searching for ages to learn how to animate uv based on system time rather than frames per second.

    I have built a clock www.unobtainium.eu I would like to get it running in unity as a working clock, I did this quite easily using guitext but i then realised guitext passes through all objects, so I now want to animate the clock getting information from the system time and animating the digits with animated uv's

    I found the 2 scripts below one for the the clock with guitext, and one for animating the uv's I am sure the answer is in there somewhere but I am a modeller not a coder.

    If you like my clock and would like to help me make it into an app, I would be forever indebted.
     
  18. rapidlaser

    rapidlaser

    Joined:
    Jul 11, 2011
    Posts:
    2
    oops! I forgot to put the code in.

    import System;

    var date = DateTime.Now;

    InvokeRepeating("Start", 2, 0.10);

    function Start () {


    var TheHour = System.DateTime.Now.ToString("HH");
    var TheMinute = System.DateTime.Now.ToString("MM");
    var TheSecond = System.DateTime.Now.ToString("ss");
    var TheMonth = System.DateTime.Now.get_Month();
    var TheDay = System.DateTime.Now.get_Day();
    var TheYear = System.DateTime.Now.get_Year();
    var tm : TextMesh = gameObject.GetComponent(TextMesh);
    tm.text = TheSecond;
    //renderer.material.color = Color(1, 0.7, 0.0, 1.2);
    //var color : Color = Color(0.2, 0.3, 0.4, 0.5);
    }

    var uvAnimationTileX = 10; //number of columns per sheet.

    var uvAnimationTileY = 1; //number of rows per sheet.

    var framesPerSecond = 1; //replace this with get time ??

    function Update () {

    // Calculate index
    var index : int = Time.time * framesPerSecond;
    // repeat when exhausting all frames
    index = index % (uvAnimationTileX * uvAnimationTileY);

    // constructs the vector
    var size = Vector2 (1.0 / uvAnimationTileX, 1.0 / uvAnimationTileY);

    // split into horizontal and vertical index
    var uIndex = index % uvAnimationTileX;
    var vIndex = index / uvAnimationTileX;

    // build offset
    // v coordinate is the bottom of the image in opengl so we need to invert.
    var offset = Vector2 (uIndex * size.x, 1.0 - size.y - vIndex * size.y);

    renderer.material.SetTextureOffset ("_MainTex", offset);
    renderer.material.SetTextureScale ("_MainTex", size);
    }
     
  19. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    if (u == true v == true) requires a logical AND. two ampersands. &&.
    For posterity.
     
  20. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    Can anyone comment on the efficiency of running SetTextureOffset("_MainTex", Vector2(0,offset)); every frame? I've been curious about shaders and uv animation for a while but is this the best way to do it?
     
  21. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    I actually ran it every other frame.

    Tried 3 water shaders. All managed 8 - 10 fps on the android device. 2 were custom bought, 1 was the default crappy unity pro mobile one, All tragic.

    I think this is a nice cheap alternative used correctly.

    Code (csharp):
    1.  
    2. #pragma strict
    3. var scrollSpeed :float = 0.5;
    4. var u : boolean = false;
    5. var v : boolean = false;
    6. private var tick : int =0;
    7.  
    8. function Update () {
    9. tick ++;
    10. if (tick %2) return;
    11.  
    12. var offset : float = Time.time * scrollSpeed % 1;
    13. if (u == true && v == true)
    14. {
    15. renderer.material.SetTextureOffset ("_MainTex", Vector2(offset,offset));
    16. }
    17. else if (u == true)
    18. {
    19. renderer.material.SetTextureOffset ("_MainTex", Vector2(offset,0));
    20. }
    21. else if (v == true)
    22. {
    23. renderer.material.SetTextureOffset ("_MainTex", Vector2(0,offset));
    24. }
    25.  
    26. tick = tick %50;
    27.  
    28. }
    29.  
     
    Last edited: Nov 24, 2014
  22. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    Alright, thanks. I'll try everything, might get better performance since I'm targeting desktops haha.
     
  23. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    desktops can pretty much "eat this stuff for dinner."
    if you really want to show off...

    goo.gl/yyxDb which in unity is:
    http://scrawkblog.com/2013/12/12/tiled-directional-flow-in-unity/

    but in the main, any - half decently optimised - shader that doesnt spend a week reflecting/refracting the world and his dog every frame should be fine

    I own this one:

    not that I would use it for mobile. over time they have a tendency to "slow down", I would always err on the side of overformance. never overloading the card
     
  24. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    I'm more of a conceptual-awesomeness > graphical-awesomeness kinda guy, so I've always been afraid of shaders that tend to exchange performance for eyecandy. But if it's such a light task for the Nvidia 860, I'll give it a shot in the future :)
     
  25. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    I just tried this on a TERRIBLE ancient laptop, a decent hybrid, an android device and a PC.
    Only device that even noticed it was the terrible laptop. So, trivial, then.
     
  26. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    I'll move this off of the "Never" list and into the "before death" list, then. Thanks
     
  27. DMinsky

    DMinsky

    Joined:
    May 20, 2012
    Posts:
    30
    Also, just for example you can use UV animation inside shader.




    Code (CSharp):
    1. Shader "Custom/UVAnimation" {
    2.     Properties {
    3.         _MainTex ( "Base (RGB)", 2D ) = "white" {}
    4.         _XScrollSpeed ( "X Scroll Speed", Float ) = 1
    5.         _YScrollSpeed ( "Y Scroll Speed", Float ) = 1
    6.     }
    7.     SubShader {
    8.         Tags { "RenderType"="Opaque" }
    9.         LOD 200
    10.        
    11.         CGPROGRAM
    12.         #pragma surface surf Lambert
    13.  
    14.         sampler2D _MainTex;
    15.         float _XScrollSpeed;
    16.         float _YScrollSpeed;
    17.  
    18.         struct Input {
    19.             float2 uv_MainTex;
    20.         };
    21.  
    22.         void surf( Input IN, inout SurfaceOutput o ) {
    23.             fixed2 scrollUV = IN.uv_MainTex;
    24.             fixed xScrollValue = _XScrollSpeed * _Time.x;
    25.             fixed yScrollValue = _YScrollSpeed * _Time.x;
    26.             scrollUV += fixed2( xScrollValue, yScrollValue );
    27.             half4 c = tex2D( _MainTex, scrollUV );
    28.             o.Albedo = c.rgb;
    29.             o.Alpha = c.a;
    30.         }
    31.         ENDCG
    32.     }
    33.     FallBack "Diffuse"
    34. }
     
  28. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    @DMinsky What's the benefit of writing that shader code vs accessing the texture in a script? Is there some data here that can't be accessed from a script?

    I still haven't touched shaders, so pardon that question if the operations done by shaders actually cannot be done at all by a script.
     
  29. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Tom is right: this transformation would be better done in a script.

    uv_MainTex
    is already transformed by the texture tiling and offset values of the material, so doing additional offsets is redundant work.
     
  30. DMinsky

    DMinsky

    Joined:
    May 20, 2012
    Posts:
    30
    @Tomnnn @Daniel Brauer yep, you're right. It was "just one more" option ;) I spied it in "Unity Shaders and Effects Cookbook".
     
  31. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    What can shaders do in code that scripts cannot? I know shaders are for effects on materials, but what kind of code "belongs" in a shader? With visual material editors, is there even a need to write them from scratch?

    Maybe I'll avoid learning shader code.
     
  32. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    495
  33. EdL_75

    EdL_75

    Joined:
    Apr 1, 2017
    Posts:
    3
    Your link is bad. I do like your "owned" water animation. I currently play SimCity App by BuiltIt and that is close to yours. I am struggling learning how to create shaders to work like this. And the ones built-in shaders by Unity as Assets are no where near the same unless I am just applying their components wrong.
    I also fail to understand how to setup a basic land/water landscape/terrain. Do I create separate layers for the two? If so a plane? How do you make a jagged shoreline? Any links to tutorials for this would be appreciated.
     
  34. Evil_Moo

    Evil_Moo

    Joined:
    Jan 23, 2014
    Posts:
    25
    Scrawk took their blog down a while ago, here is a copy of the write-up: https://www.digital-dust.com/single-post/2017/03/24/Tiled-directional-flow-in-unity
     
  35. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    Both are now defunct wastes of money