Search Unity

Rotating a single texture and not the whole UV

Discussion in 'Shaders' started by iPLEOMAX, Oct 6, 2015.

  1. iPLEOMAX

    iPLEOMAX

    Joined:
    Feb 16, 2014
    Posts:
    17
    Hello guys.

    I've got two texture samples. One is the main texture, and the other is used for color mask (using RGB values).

    I managed to rotate the texture using a range value (0 to 360). But I want that only to affect the first (main) texture and not the second one. Obviously because it would mess up the parts I need to mask on my mesh.

    How would I achieve that?

    Here is the code:
    Code (CSharp):
    1. Shader "Dummy/Test" {
    2.  
    3.     Properties {
    4.         _FirstTex ("Texture 1", 2D) = "white" {}
    5.         _ColorMask ("ColorMask", 2D) = "white" {}
    6.         _Rotation ("Rotation", Range(0.0, 360.0)) = 0.0
    7.     }
    8.     SubShader {
    9.         Tags { "RenderType"="Opaque" }
    10.         Blend One One
    11.         LOD 200
    12.      
    13.         CGPROGRAM
    14.         #pragma surface surf Lambert
    15.          #pragma vertex vert
    16.          sampler2D _FirstTex;
    17.          sampler2D _ColorMask;
    18.  
    19.         struct Input {
    20.             float2 uv_FirstTex;
    21.             float2 uv_ColorMask;
    22.         };
    23.         float _Rotation;
    24.      
    25.         void vert (inout appdata_full v) {
    26.             float rot = _Rotation / (57.2957795131);
    27.             float sinX = sin (rot);
    28.             float cosX = cos (rot);
    29.             float sinY = sin (rot);
    30.             float2x2 rotationMatrix = float2x2( cosX, -sinX, sinY, cosX);
    31.             v.texcoord.xy = mul ( v.texcoord.xy, rotationMatrix );
    32.         }
    33.         void surf (Input IN, inout SurfaceOutput o) {
    34.             half4 c = tex2D (_FirstTex, IN.uv_FirstTex);
    35.             half4 c2 = tex2D (_ColorMask, IN.uv_ColorMask);
    36.          
    37.             o.Albedo = (c.rgb * c2.r); //Dummy code here
    38.             o.Alpha = c.a;
    39.         }
    40.      
    41.         ENDCG
    42.     }
    43.     FallBack "Diffuse"
    44. }
    45.  
    Thanks for any response.

    EDIT:
    Nevermind, just realized I can use multiple CGPROGRAM in a shader. Excuse me, ahem.
     
    Last edited: Oct 6, 2015
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,343
    Why would you use multiple CGPROGRAM for this? You just need to send two sets of UVs to the surface shader, one modified by your rotation and one not.
    Code (CSharp):
    1. Shader "Dummy/Test" {
    2.     Properties {
    3.         _FirstTex ("Texture 1", 2D) = "white" {}
    4.         _ColorMask ("ColorMask", 2D) = "white" {}
    5.         _Rotation ("Rotation", Range(0.0, 360.0)) = 0.0
    6.     }
    7.     SubShader {
    8.         Tags { "RenderType"="Opaque" }
    9.         Blend One One
    10.         LOD 200
    11.    
    12.         CGPROGRAM
    13.         #pragma surface surf Lambert
    14.          #pragma vertex vert
    15.          sampler2D _FirstTex;
    16.          sampler2D _ColorMask;
    17.  
    18.         struct Input {
    19.             float2 uv_FirstTex;
    20.             float2 uv2_ColorMask; // uv2 denotes use second UVs.
    21.         };
    22.         float _Rotation;
    23.    
    24.         void vert (inout appdata_full v) {
    25.             v.texcoord1 = v.texcoord; // copy uvs from texcoord to texcoord1 (aka uv2) before rotation
    26.  
    27.             float rot = _Rotation / (57.2957795131);
    28.             float sinX = sin (rot);
    29.             float cosX = cos (rot);
    30.             float sinY = sin (rot);
    31.             float2x2 rotationMatrix = float2x2( cosX, -sinX, sinY, cosX);
    32.             v.texcoord.xy = mul ( v.texcoord.xy, rotationMatrix );
    33.         }
    34.         void surf (Input IN, inout SurfaceOutput o) {
    35.             half4 c = tex2D (_FirstTex, IN.uv_FirstTex);
    36.             half4 c2 = tex2D (_ColorMask, IN.uv2_ColorMask);
    37.        
    38.             o.Albedo = (c.rgb * c2.r); //Dummy code here
    39.             o.Alpha = c.a;
    40.         }
    41.    
    42.         ENDCG
    43.     }
    44.     FallBack "Diffuse"
    45. }
     
    iPLEOMAX likes this.
  3. iPLEOMAX

    iPLEOMAX

    Joined:
    Feb 16, 2014
    Posts:
    17
    Ah, thanks a bunch!

    New to shader programming here.
     
  4. Eviral

    Eviral

    Joined:
    Mar 20, 2013
    Posts:
    35
    Nice it works ! But how can i set the rotation pivot to the center of my texture ????
    Please help !
    Thx
    Eviral
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,343
    v.texcoord.xy = mul ( v.texcoord.xy - 0.5, rotationMatrix ) + 0.5;

    Should make it rotate around the center of the UV space.
     
  6. Eviral

    Eviral

    Joined:
    Mar 20, 2013
    Posts:
    35
    Thx ! It works !
    But i have a sorting layer problem now :(
    This shader seems to be stronger than the sorting layer specified on my Sprite Renderer :(

    Please help !

    Eviral