Search Unity

Tiling texture in masked shader

Discussion in 'Shaders' started by hellcaller, Jul 7, 2021.

  1. hellcaller

    hellcaller

    Joined:
    May 19, 2010
    Posts:
    381
    I've got simple shader that is masking main texture with mask texture:
    Code (CSharp):
    1. Shader "MaskedTexture"
    2. {
    3.    Properties
    4.    {
    5.       _MainTex ("Base (RGB)", 2D) = "white" {}
    6.       _Mask ("Culling Mask", 2D) = "white" {}
    7.       _Cutoff ("Alpha cutoff", Range (0,1)) = 0.1
    8.    }
    9.    SubShader
    10.    {
    11.       Tags {"Queue"="Transparent"}
    12.       Lighting Off
    13.       ZWrite Off
    14.       Blend SrcAlpha OneMinusSrcAlpha
    15.       AlphaTest GEqual [_Cutoff]
    16.       Pass
    17.       {
    18.          SetTexture [_Mask] {combine texture}
    19.          SetTexture [_MainTex] {combine texture, previous}
    20.       }
    21.    }
    22. }
    23.  
    works great but i need to be able to change tiling value of "_MainTex". As i understood tiling is stored in "_MainTex_ST" but i got no idea how to include it into shader so i can reference to it via script.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    This is a fixed function style shader for use with GPUs that Unity no longer supports. Unity no longer supports using fixed function shaders and they are considered deprecated, though they still "work" by treating them as vertex fragment shader generators rather than trying to use the shader code directly. So the above shader is automatically turned into a vertex fragment shader that the engine actually uses. You can select the shader in the project view and click on "Show Generated Code" to see what it outputs, but it looks like this:
    Code (csharp):
    1. Shader "MaskedTexture" {
    2. Properties {
    3.  _MainTex ("Base (RGB)", 2D) = "white" { }
    4.  _Mask ("Culling Mask", 2D) = "white" { }
    5.  _Cutoff ("Alpha cutoff", Range(0.000000,1.000000)) = 0.100000
    6. }
    7. SubShader {
    8.  Tags { "QUEUE"="Transparent" }
    9.  Pass {
    10.   Tags { "QUEUE"="Transparent" }
    11.   ZWrite Off
    12.   Blend SrcAlpha OneMinusSrcAlpha
    13. CGPROGRAM
    14. #pragma vertex vert
    15. #pragma fragment frag
    16. #pragma target 2.0
    17. #include "UnityCG.cginc"
    18. #pragma multi_compile_fog
    19. #define USING_FOG (defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2))
    20.  
    21. // uniforms
    22. float4 _Mask_ST;
    23. float4 _MainTex_ST;
    24.  
    25. // vertex shader input data
    26. struct appdata {
    27.   float3 pos : POSITION;
    28.   float3 uv0 : TEXCOORD0;
    29.   UNITY_VERTEX_INPUT_INSTANCE_ID
    30. };
    31.  
    32. // vertex-to-fragment interpolators
    33. struct v2f {
    34.   fixed4 color : COLOR0;
    35.   float2 uv0 : TEXCOORD0;
    36.   float2 uv1 : TEXCOORD1;
    37.   #if USING_FOG
    38.     fixed fog : TEXCOORD2;
    39.   #endif
    40.   float4 pos : SV_POSITION;
    41.   UNITY_VERTEX_OUTPUT_STEREO
    42. };
    43.  
    44. // vertex shader
    45. v2f vert (appdata IN) {
    46.   v2f o;
    47.   UNITY_SETUP_INSTANCE_ID(IN);
    48.   UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    49.   half4 color = half4(0,0,0,1.1);
    50.   float3 eyePos = mul (UNITY_MATRIX_MV, float4(IN.pos,1)).xyz;
    51.   half3 viewDir = 0.0;
    52.   o.color = saturate(color);
    53.   // compute texture coordinates
    54.   o.uv0 = IN.uv0.xy * _Mask_ST.xy + _Mask_ST.zw;
    55.   o.uv1 = IN.uv0.xy * _MainTex_ST.xy + _MainTex_ST.zw;
    56.   // fog
    57.   #if USING_FOG
    58.     float fogCoord = length(eyePos.xyz); // radial fog distance
    59.     UNITY_CALC_FOG_FACTOR_RAW(fogCoord);
    60.     o.fog = saturate(unityFogFactor);
    61.   #endif
    62.   // transform position
    63.   o.pos = UnityObjectToClipPos(IN.pos);
    64.   return o;
    65. }
    66.  
    67. // textures
    68. sampler2D _Mask;
    69. sampler2D _MainTex;
    70. fixed _Cutoff;
    71.  
    72. // fragment shader
    73. fixed4 frag (v2f IN) : SV_Target {
    74.   fixed4 col;
    75.   fixed4 tex, tmp0, tmp1, tmp2;
    76.   // SetTexture #0
    77.   tex = tex2D (_Mask, IN.uv0.xy);
    78.   col = tex;
    79.   // SetTexture #1
    80.   tex = tex2D (_MainTex, IN.uv1.xy);
    81.   col.rgb = tex;
    82.   col.a = col.a;
    83.   // alpha test
    84.   if (col.a < _Cutoff) clip(-1);
    85.   // fog
    86.   #if USING_FOG
    87.     col.rgb = lerp (unity_FogColor.rgb, col.rgb, IN.fog);
    88.   #endif
    89.   return col;
    90. }
    91.  
    92. // texenvs
    93. //! TexEnv0: 01010000 01010000 [_Mask]
    94. //! TexEnv1: 01010000 01040004 [_MainTex]
    95. ENDCG
    96.  }
    97. }
    98. }
    Notice
    _MainTex_ST
    is already being used, so the tiling and offset should already work.
     
  3. hellcaller

    hellcaller

    Joined:
    May 19, 2010
    Posts:
    381
    Thank U!!
     
  4. hellcaller

    hellcaller

    Joined:
    May 19, 2010
    Posts:
    381
    Sorry for bothering again. So i managed modify tiling in this shader via script. Now i'm trying to do the same with rotation of the main texture. So i need to insert this snippet into above shader:
    Code (CSharp):
    1. struct v2f
    2.             {
    3.                 float2 uv : TEXCOORD0;
    4.                 float4 pos : SV_POSITION;
    5.             };
    6.  
    7.             float4x4 _TextureRotation;
    8.  
    9.             v2f vert (float4 pos : POSITION, float2 uv : TEXCOORD0)
    10.             {
    11.                 v2f o;
    12.                 o.pos = UnityObjectToClipPos(pos);
    13.                 o.uv = mul(_TextureRotation, float4(uv,0,1)).xy;
    14.                 return o;
    15.             }
    But as a shader noob i've got no idea how to do it(
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    There are several threads on rotating UVs on the forum. Search for one of those. Or read up on 2D rotations.
     
    hellcaller likes this.