In this post we will make a shader that displays a transparent texture. There are also some reference links regarding rendering order and blending options in Unity 3d.
If you tried to use the previous shader with a texture that is partially transparent, then you noticed that it does not show up correctly. Perhaps you also noticed that this also happens to the most built-in non Transparent shaders. You have to specify to the GPU that you wish to take into account texture transparency, as well as how to blend the pixels that are transparent with the underlying pixels ( what is behind them in space ).
Well, to blend what is in front with what is in back you should have something in back to blend with
It is necessary to schedule somehow the rendering so opaque objects are rendered first and transparent after (so they have what to blend with). This page discusses the rendering order and this page discusses the blending options. Building on the previous example, we will perform the following changes in the Subshader section of the code
SubShader
{
// This tells GPU how to blend the model with the rest
// of the scene, taking into account texture's
Blend SrcAlpha OneMinusSrcAlpha
// This tells GPU to render the shader after the opaque
// Geometry is drawn.
Tags {"Queue" = "Transparent" }
Pass
{...}
So the complete code of the shader will be :
Shader "simple_Transparent_Shader"
{
Properties
{
// This allows to choose the texture from the Editor
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader
{
// This tells GPU how to blend the model with the rest
// of the scene, taking into account texture's
Blend SrcAlpha OneMinusSrcAlpha
// This tells GPU to render the shader after the opaque
// Geometry is drawn.
Tags {"Queue" = "Transparent" }
Pass
{
GLSLPROGRAM
#ifdef VERTEX
// varying is a special type of variable in glsl
// that lets you pass data from the Vertex to
// the Fragment shader
varying vec2 the_uv;
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// Access the first texture unit and retrieve the texture coordinates
// that correspond to the uv coordinates of the given vertice
the_uv = gl_MultiTexCoord0.st;
}
#endif
#ifdef FRAGMENT
// Receive texture data from Unity Editor
uniform sampler2D _MainTex;
// Receive data from the Vertex to
// the Fragment shader
varying vec2 the_uv;
void main()
{
// The pixel color will correspond
// to the uv coords of the texture
// for the given vertice, retrieved
// by the Vertex shader through varying vec2 the_uv
gl_FragColor = texture2D(_MainTex, the_uv);
}
#endif
ENDGLSL
}
}
}