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

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