Search Unity

RGB Channel Tint Mask w/ Transparency

Discussion in 'Shaders' started by kMBL, May 26, 2013.

  1. kMBL

    kMBL

    Joined:
    May 26, 2013
    Posts:
    2
    We needed a shader that could be used to tint multiple areas of a texture and still have transparency.
    I'm new to writing shaders, but I was able to come up with this (based on various examples I found):

    Code (csharp):
    1. Shader "Custom/LitTransparentTintMask" {
    2.     Properties {
    3.         //Main Color
    4.         _Color ("Main Color", Color) = (1,1,1,1)
    5.         //Main Texture - with alpha for transparency
    6.         _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    7.         //Mask Texure - this texture defines which parts of the main texture are tinted
    8.         _Mask ("Mask (RGB)", 2D) = "white" {}
    9.         //Any parts unerneath red in the mask texture will be tinted this color
    10.         _SWColor1 ("Red Channel", Color) = (1.00,0.00,0.00,1.00)
    11.         //Any parts unerneath green in the mask texture will be tinted this color      
    12.         _SWColor2 ("Green Channel", Color) = (0.00,1.00,0.00,1.00)
    13.         //Any parts unerneath blue in the mask texture will be tinted this color
    14.         _SWColor3 ("Blue Channel", Color) = (0.00,0.00,1.00,1.00)
    15.     }
    16.     SubShader {
    17.         Tags {"Queue"="Transparent" "RenderType"="Transparent"}
    18.         LOD 100
    19.    
    20.         CGPROGRAM
    21.         #pragma surface surf Lambert alpha
    22.         #pragma target 3.0
    23.        
    24.         sampler2D _MainTex;
    25.         sampler2D _Mask;
    26.        
    27.         float4 _Color;
    28.         float3 _SWColor1;
    29.         float3 _SWColor2;
    30.         float3 _SWColor3;
    31.        
    32.         struct Input {
    33.             float2 uv_MainTex;
    34.         };
    35.        
    36.         void surf (Input IN, inout SurfaceOutput o) {
    37.        
    38.             //color from the main texture
    39.             fixed4 base = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    40.             //color from the mask texture
    41.             fixed3 mask = tex2D(_Mask, IN.uv_MainTex);
    42.            
    43.             //masked color - color of the channel in the mask multiplied by the tint color for that channel
    44.             //all non-tined parts are black                                        
    45.             fixed3 tinted = base.rgb * (mask.r * _SWColor1.rgb + mask.g * _SWColor2.rgb + mask.b *_SWColor3.rgb);
    46.             //main color - color of the main texure with the tinted parts subtracted
    47.             //all tinted parts are black
    48.             fixed3 reg = base.rgb - (mask.r * base.rgb + mask.g * base.rgb + mask.b * base.rgb);                  
    49.            
    50.             //add the tinted and non-tinted parts together                              
    51.             o.Albedo = tinted + reg;
    52.             //inlcude the alpha from the main texture for transparency
    53.             o.Alpha = base.a;
    54.         }
    55.         ENDCG
    56.     }
    57.     Fallback "Transparent/Diffuse"
    58. }
    It actually does exactly what we want (and is lit, as a bonus).
    The problem is that it really drops the fps on mobile (iOS).
    Can anyone recommend a way to improve the performance or another way to have tint masks and transparency (with or w/o lighting)?

    Thanks.
     
    Last edited: May 29, 2013
  2. cod

    cod

    Joined:
    Nov 26, 2011
    Posts:
    267
    what about packing SWColor1 2 and 3 in a single Color? So u can declare a single SWColor and then pass it to the surface part
     
  3. kMBL

    kMBL

    Joined:
    May 26, 2013
    Posts:
    2
    Thanks for the reply.
    The SWColors are the colors that the user sets in the editor that control the tint colors, these could be any color, so I don't think combining them work.

    The performance hit on mobile seems to happen in the complex math and swizzling on lines 45 and 48, but I can't seem to think of a more clean way to do those calculations.

    I've commented the code to hopefully help w/ understanding.
     
  4. cod

    cod

    Joined:
    Nov 26, 2011
    Posts:
    267
    I'm not sure, but maybe the problem is using the alpha blending mode, what about a cutout shader? It should run faster on mobiles