CG shaders Alpha Channels and blending

Typical alpha channel usage - for a quad with a leaf texture that has alpha values.

We make sure we're inthe Transparent Queue and also use the Blend function. It takes two arguments, the first multiplies the incoming data (what is on the surface) and the second multiplies the existing data on the framebuffer (whatever is behind the object - Unity renders from back to front). Then both values are added.
In the code example, SrcAlpha x surface colour will give you the surface col where the Alpha is white & zero where the Alpha is black. By multiplying the framebuffer with 1-srcalpha we take the inverse of the alpha map and get inverted results. Now when you add these values they should sit together as if the quad has correct transparency.

If for instance, you had Blend SrcAlpha One, then  you'd have an additive effect of the background on your leaf. I've pasted some info about it below..

Cull Off - tells the shader not to discard the back-face data, which it does by default (why render what isn't there?). This way you can rotate the leaf and see it from both sides. This is more expensive, of course.

We also add "alpha:fade"to the #pragma.. I've pasted some info from the Unity docs below about this.

Shader "Dave/Transparent"{
    Properties{
        _MainTex("Texture",2D) = "black"{}
    }

    SubShader{
        Tags{"Queue"="Transparent"}
        Blend SrcAlpha OneMinusSrcAlpha
        Cull Off
        

   
        CGPROGRAM
        #pragma surface surf Lambert alpha:fade

        sampler2D _MainTex;
        struct Input {
        float2 uv_MainTex;
};

        void surf(Input IN, inout SurfaceOutput o) {
            float4 c = tex2D(_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;

        }
        ENDCG
    }

        Fallback "Diffuse"
}

 An alternative way to write this shader, which i assume is Unity only...Seems to skip all the struct/surface/uv code useful for very simple shaders i guess? -

Shader "Dave/Transparent"{
    Properties{
        _MainTex("Texture",2D) = "black"{}
    }

    SubShader{
        Tags{"Queue"="Transparent"}
        Blend SrcAlpha OneMinusSrcAlpha
        Cull Off
        
       Pass{
            SetTexture [_MainTex] {combine texture}

     }
      
}

 

 

Blend SrcAlpha OneMinusSrcAlpha // Traditional transparency
Blend One OneMinusSrcAlpha // Premultiplied transparency
Blend One One // Additive
Blend OneMinusDstColor One // Soft additive
Blend DstColor Zero // Multiplicative
Blend DstColor SrcColor // 2x multiplicative

Here's a table of the arguments you can use.

.

One The value of this input is one. Use this to use the value of the source or the destination color.

Zero The value of this input is zero. Use this to remove either the source or the destination values.

SrcColor The GPU multiplies the value of this input by the source color value.

SrcAlpha The GPU multiplies the value of this input by the source alpha value.

DstColor The GPU multiplies the value of this input by the frame buffer source color value.

DstAlpha The GPU multiplies the value of this input by the frame buffer source alpha value.

OneMinusSrcColor The GPU multiplies the value of this input by (1 - source color).

OneMinusSrcAlpha The GPU multiplies the value of this input by (1 - source alpha).

OneMinusDstColor The GPU multiplies the value of this input by (1 - destination color).

OneMinusDstAlpha
The last one should read "GPU multiplies value of thie input by(1-dest alpha)

 

 

Transparency and alpha testing is controlled by alpha and alphatest directives. Transparency can typically be of two kinds: traditional alpha blending (used for fading objects out) or more physically plausible “premultiplied blending” (which allows semitransparent surfaces to retain proper specular reflections). Enabling semitransparency makes the generated surface shader code contain blending commands; whereas enabling alpha cutout will do a fragment discard in the generated pixel
shader, based on the given variable.

  • alpha or alpha:auto - Will pick fade-transparency (same as alpha:fade) for simple lighting functions, and premultiplied transparency (same as alpha:premul) for physically based lighting functions.
  • alpha:blend - Enable alpha blending.
  • alpha:fade - Enable traditional fade-transparency.
  • alpha:premul - Enable premultiplied alpha transparency.
  • alphatest:VariableName - Enable alpha cutout transparency. Cutoff value is in a float variable with VariableName. You’ll likely also want to use addshadow directive to generate proper shadow caster pass.
  • keepalpha - By default opaque surface shaders write 1.0 (white) into alpha channel, no matter what’s output in the Alpha of output struct or what’s returned by the lighting function. Using this option allows keeping lighting function’s alpha value even for opaque surface shaders.
  • decal:add - Additive decal shader (e.g. terrain AddPass). This is meant for objects that lie atop of other surfaces, and use additive blending. See Surface Shader Examples
  • decal:blend - Semitransparent decal shader. This is meant for objects that lie atop of other surfaces, and use alpha blending. See Surface Shader Examples

 

Comments

Popular posts from this blog

setting VFX graph properties using C#

scripting custom render texture creation, assignment, shaders