Unity Alpha



Over the past several years working in Unity many of my projects have involved some kind of mixed reality, augmented reality, transparent MovieTexture, or something of the sort. One custom shader that I have reused a lot for these effects is an unlit alpha mask shader. Alpha masking is simply setting the opacity of a texture’s pixels, usually with a separate texture map.

Cheap flights from Strasbourg to all destinations Looking for best deals on flights from Strasbourg? Find best offers in flights from Strasbourg top airlines at cheapest price with Expedia. Description Tweens the alpha of the CanvasRenderer color associated with this Graphic. Creates a fading effect on a Graphic with a CanvasRenderer attached. Choose an alpha level to fade to, and pick the speed of the fade to see a smooth fade over time.

I’m certainly no Unity shader expert, but creating this shader is relatively straightforward if we start with the right foundation. In this case we’ll be modifying the closest thing to what we want – Unity’s own unlit alpha shader. We’ll start with the completed version and then explain how it was modified from the source.

Unity Shader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// Unlit alpha-blended shader.
// - no lighting
// - no lightmap support
// - no per-material color
Shader 'Unlit/AlphaMask'{
Properties {
_MainTex ('Base (RGB)', 2D)='white'{}
_AlphaTex ('Alpha mask (R)', 2D)='white'{}
}
SubShader {
Tags {'Queue'='Transparent''IgnoreProjector'='True''RenderType'='Transparent'}
LOD 100
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include 'UnityCG.cginc'
struct appdata_t {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f {
float4 vertex : SV_POSITION;
half2 texcoord : TEXCOORD0;
};
sampler2D _MainTex;
sampler2D _AlphaTex;
float4 _MainTex_ST;
v2f vert (appdata_t v)
{
v2f o;
o.vertex= mul(UNITY_MATRIX_MVP, v.vertex);
o.texcoord= TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
fixed4 frag (v2f i): SV_Target
{
fixed4 col = tex2D(_MainTex, i.texcoord);
fixed4 col2 = tex2D(_AlphaTex, i.texcoord);
return fixed4(col.r, col.g, col.b, col2.r);
}
ENDCG
}
}
}

Important: This shader will only work for Unity 4.5 or newer. Earlier versions will be similar but usually output COLOR from the fragment shader instead of SV_Target.

What we do here is:
  1. Start with the built-in Unity unlit alpha shader (version 4.5.1)
  2. Add a texture sampler for an alpha mask
  3. Apply the color channel from the mask texture to the alpha of the main texture

Since we’re using an unlit shader as our base, our texture’s color will be unaffected by scene lighting since it is ignored. In addition the shader will be more efficient than a normal lit shader since it doesn’t have to calculate light or shadows. And as an alpha shader we can assume it already contains the tags, blending, etc. to render transparency properly.

Note: You can find an archive of Unity’s built-in shaders here.

Unity Shader

Unity Alphatomask

Alphatomask

This is the actual name of the shader that Unity will recognize preceded by its folder path which is used for organization. Regardless of the name of a .shader file, once imported it can be added as the shader of a material via the drop down menu as Folder/Name.

Unity Shader

_AlphaTex ('Alpha mask (A)', 2D)='white'{}

Here we expose a new alpha channel texture that defaults to a solid white. This is what allows us to dynamically set a texture in the Unity editor like so:

Unity Shader

This defines a new sampler2D variable linked to our alpha texture property above. It is used to read a pixel color of the texture, given a UV coordinate.

Unity Shader

fixed4 col2 = tex2D(_AlphaTex, i.texcoord);
return fixed4(col.r, col.g, col.b, col2.r);

Here in the fragment shader is where all the magic happens. By this point variable col contains the rgba color channel data from our main texture. We simply added a second variable col2 to store the color data from our alpha texture. Lastly we return a 3rd new color combining the first two, using the rgb from col and the r from col2 as the alpha. This is then returned by the shader as the pixel color drawn to the screen!

Note: We pull from the r channel of our alpha texture because ideally you want your textures to be as small as possible. Usually a full color texture with alpha is 32-bit rgba (8 bits for each color channel). Although, since only one color channel is needed for our alpha mask, we can use an 8-bit single channel gray-scale texture which, when imported into Unity as a default texture type, lives in the r channel.

Unity Alpha Map

Note: The second parameter of tex2D() we are passing a pixel’s UV coordinates. In the example shader we are using the same UV’s as the main texture. If you look up into struct v2f you will see it defined there as TEXCOORD0. If you wanted to use a second UV set for the mask you can define a new variable for it there as well as TEXCOORD1 and then pass that to tex2d() instead.

Concluding..

Hopefully you learned a little something about tweaking shaders. This shader is perhaps the most useful because you can use it to add alpha to a MovieTexture, switch the two and have an animated alpha channel, or even use a MovieTexture for both! There are certainly other uses for it and shaders like it though, like sharing pixel data between multiple images or dynamically modifying a texture’s alpha.

Enjoy!

Unity 2021 Alpha

Ben