Search Unity

UV matrix rotation in shader

Discussion in 'Shaders' started by J-F, Jul 2, 2018.

  1. J-F

    J-F

    Joined:
    Nov 8, 2012
    Posts:
    101
    I'm not that good at shaders and this is the shader i've done so far:

    Code (CSharp):
    1. Shader "DecoSim/Display"
    2. {
    3.   Properties
    4.   {
    5.     _Blend ( "Blend", Range ( 0, 1 ) ) = 0.5
    6.     _MainTex ( "Texture 1", 2D ) = "white" {}
    7.     _Texture2 ( "Texture 2", 2D ) = ""
    8.   }
    9.  
    10.   SubShader
    11.   {
    12.     Tags { "RenderType" = "Transparent" "Queue" = "Transparent"}
    13.     LOD 200
    14.     Cull Off
    15.     ZWrite Off
    16.     Blend SrcAlpha OneMinusSrcAlpha
    17.     ColorMask RGB
    18.  
    19.     Pass
    20.     {
    21.       SetTexture[_MainTex]
    22.       SetTexture[_Texture2]
    23.       {
    24.         ConstantColor ( 0, 0, 0, [_Blend] )
    25.         Combine texture Lerp( constant ) previous
    26.       }
    27.     }
    28.  
    29.     CGPROGRAM
    30.     #pragma surface surf Lambert alpha
    31.    
    32.     sampler2D _MainTex;
    33.     sampler2D _Texture2;
    34.     float _Blend;
    35.    
    36.     struct Input
    37.     {
    38.       float2 uv_MainTex;
    39.       float2 uv_Texture2;
    40.     };
    41.  
    42.     void surf ( Input IN, inout SurfaceOutput o )
    43.     {
    44.       fixed4 t1  = tex2D( _MainTex, IN.uv_MainTex);
    45.       fixed4 t2  = tex2D( _Texture2, IN.uv_Texture2);
    46.       o.Albedo  = lerp( t1, t2, _Blend );
    47.     }
    48.     ENDCG
    49.   }
    50.   FallBack Off
    51. }
    I'm trying to add a rotation value for both _MainTex and _Texture2 that rotate around the center or an offset.
    I've tried some matrix-rotation shaders i found online, But each method i've implemented only works for one of the textures or the texture rotates along the bottom right.

    I'd be super glad if anyone could help me with this.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Is there any reason you need to have different UVs for each texture? It looks like you're just fading between two textures, so presumably they're both sharing the same UVs. If you plan on having them match, remove uv_Texture2 from the surface shader Input struct and use IN.uv_MainTex for both tex2D function calls.

    For rotating the texture there are several threads on the forums on this, and if they're not working it means there may be something different about your setup that you're not explaining here. However short version to rotate around an offset is to subtract that offset, apply the rotation, then add the offset back. Most examples use 0.5 as that's the middle of the 0.0 to 1.0 range UVs use for a whole texture. For surface shaders you can do that with a custom vertex function:
    https://forum.unity.com/threads/rotating-a-single-texture-and-not-the-whole-uv.359526/#post-2328017

    One thing is your shader is using a fixed function pass and a surface shader. What's the purpose of having both? You cannot rotate textures within a fixed function shader, so if you want to use that you have to modify the base mesh's UVs. However support for fixed function shaders is actually deprecated in Unity and they get converted into vertex fragment shaders anyway.
     
  3. J-F

    J-F

    Joined:
    Nov 8, 2012
    Posts:
    101
    The textures definetly need to have separate UVs or at least be able to scale and offset them separately.
    The same would apply to rotation too, independent rotation for both textures.
    I've had only little succes so far and i have no clue what i'm doing.
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    So the question I would have is around what point do you want the textures to rotate? Do you want this rotation to be done before or after the scale and offset?

    If you want it before, the custom vertex function example in my previous post is 90% of the code you need. Copy texcoord to texcoord1 and apply different rotation matrices to each. I use a constant offset of 0.5 for that example, replace that with a two float2 values (or a Vector property and use the xy and zw components for each texture's rotation offset) Then in the Input struct use uv2_ for the second texture instead of uv_ which will cause it to use the newly overridden texcoord1. (Yes, uv2_ == texcoord1 and uv_ == texcoord.)

    If you want it to be rotated after, then you can do the rotation in the surf function.
     
  5. J-F

    J-F

    Joined:
    Nov 8, 2012
    Posts:
    101
    I'm trying to set the rotation in after offsetting.
    I'm currently trying your method posted above, Where would i put uv_== texcoord to?