Lingheng Tony Tao

Unity Shader · Part 2.1 of 13 · October 10, 2021

Unity Shader #2.1 Basic Commands

In the process of the render pipeline we do have several other commands for some options.

Face Culling

The backside of a surface is by default culled during the process.

By adding Cull Off before CGPROGRAM, we can turn off the backside face culling.

Pass
{
    Cull Off
    CGPROGRAM
    //...
    ENDCG
}

The other options here:

  • Cull Off: turn off the backside face culling.

  • Cull Back: [Default] cull the backside of a face.

  • Cull Front: cull the frontside of a face.

If we want to set the cull mode in the inspector, we can add a line in the Properties part, and then use Cull[_CullMode].

Properties
{
    [Enum(UnityEngine.Rendering.CullMode)]_CullMode("CullMode", float) = 2
}

Pass
{
    Cull [_CullMode]
    CGPROGRAM
    //...
    ENDCG
}

CullMode:

  • 0: Off

  • 1: Front

  • 2: Back

Time

We can use the _Time parameter to use the time value.

_Time.x/y/z/w: t/20, t, 2t, 3t

_SinTime.w: the sin value of the time

_CosTime.w: the cos value of the time

Alpha Test

In the fragment shader, the clip(n) function has the following behavior:

n < 0: hide the fragment

n >= 0: show the fragment.

We can use the clip() function to realize some resolution/blend/wave effect, and we will do that in future notes.

For blending/semi-transparency, we need to add a Blend command like the Cull above before the CGPROGRAM.

Pass
{
    Blend SrcAlpha OneMinusSrcAlpha
    CGPROGRAM
    //...
    ENDCG
}

Besides OneMinusSrcAlpha, we do have other blending modes. Another frequently used mode is Blend SrcAlpha One.

Also, remember to turn off ZWrite. Otherwise there might be some obvious and serious issues with sorting/rendering order.

Pass
{
    ZWrite Off
    Blend SrcAlpha OneMinusSrcAlpha
    CGPROGRAM
    //...
    ENDCG
}

In some cases we probably need ZWrite to be on, and we will cover these cases in later notes.

Recall the semi-transparent objects should be after 2500 in Render Queue (by default 3000), so we add a Tags{} in SubShader{} part before any Pass{}'s.

SubShader
{
    Tags{"Queue" = "Transparent"}
    Pass
    {
        ZWrite Off
        Blend SrcAlpha OneMinusSrcAlpha
        CGPROGRAM
        //...
        ENDCG
    }
}

Just one more thing to add, if you want to manually set the alpha value of a color (or a float), always make sure that the alpha value does fall in the range of (0,1). You can always use the saturate() function as a safe guard. saturate() makes sure that it does not return any value out of range (0,1).

half alpha = saturate(tex2D(_MainTex, i.uv).r * _Color.a * _Emiss);