How to combine 2 Shader into 1? Multiply Blend + Transparent Alpha Mask

Hello friend. I need help making a alpha mask shader with multiply blend to the background.
I tired to combine them together by using PASS block, but not success. Would you please give me an idea how to make it?

I’d really appreciate your help! :slight_smile:
Thank you very much!

Transparent Alpha Mask Shader

// Unlit alpha-blended shader.
// - no lighting
// - no lightmap support
// - no per-material color
Shader "Unlit/TransparentAlphaMask" {
Properties {
    _MainTex ("Base (RGB)", 2D) = "white" {}
    _AlphaTex ("Alpha mask (R)", 2D) = "white" {}
}
SubShader {
    Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    LOD 100
    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
    }
}
}

Multiply Blend Shader

Shader "_My/Multiply"
{
    Properties
    {
        _MainTex ("Sprite Texture", 2D) = "white" {}
        _Color ("Tint", Color) = (1,1,1,1)
        [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
    }

    SubShader
    {
        Tags
        {
            "Queue"="Transparent"
            "IgnoreProjector"="True"
            "RenderType"="Transparent"
            // "PreviewType"="Plane"
            // "CanUseSpriteAtlas"="True"
        }

        Pass
        {
            Cull Off
            Lighting Off
            ZWrite Off
            Fog { Color (1,1,1,1) }
            Blend Zero SrcColor
            //AlphaTest Greater .01
            ColorMask RGB
            CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #pragma multi_compile DUMMY PIXELSNAP_ON
                #include "UnityCG.cginc"

                struct appdata_t
                {
                    float4 vertex   : POSITION;
                    float4 color    : COLOR;
                    float2 texcoord : TEXCOORD0;
                };

                struct v2f
                {
                    float4 vertex   : SV_POSITION;
                    fixed4 color    : COLOR;
                    half2 texcoord  : TEXCOORD0;
                };

                fixed4 _Color;

                v2f vert(appdata_t IN)
                {
                    v2f OUT;
                    OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
                    OUT.texcoord = IN.texcoord;
                    OUT.color = IN.color * _Color;
                    #ifdef PIXELSNAP_ON
                    OUT.vertex = UnityPixelSnap (OUT.vertex);
                    #endif

                    return OUT;
                }

                sampler2D _MainTex;

                fixed4 frag(v2f IN) : COLOR
                {
                    half4 prev = IN.color * tex2D(_MainTex, IN.texcoord);
                    return lerp(half4(1,1,1,1), prev, prev.a);
                }
            ENDCG
        }

    }
}

It should be fine to combine those by having two pass blocks. Do make sure the blend settings are inside the pass block for both passes. Since the multiply pass is in the background, this should be the first pass.

Hello, thanks for reply. I tired again, but the result is unexpected… the multiply bend effect is applied to the cutout area only, result as follow:

I want to make the cat image masked by the star shape and multiple to the sky layer.

This is my combined shader. How to correct it?

Shader "_My/AlphaMaskMultiply" {
Properties {
    _MainTex ("Photo PNG", 2D) = "white" {}
    _AlphaTex ("Photo Mask", 2D) = "white" {}
    _Color ("Tint Color", Color) = (1,1,1,1)
}

SubShader {
    Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    LOD 100

    ZWrite Off

    Pass
    {
        // Cull Off
        // Lighting Off
        // ZWrite Off
        // Fog { Color (1,1,1,1) }
        Blend Zero SrcColor
        //AlphaTest Greater .01
        // ColorMask RGB
        CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // #pragma multi_compile DUMMY PIXELSNAP_ON
            // #include "UnityCG.cginc"

            struct appdata_t
            {
                float4 vertex   : POSITION;
                float4 color    : COLOR;
                float2 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex   : SV_POSITION;
                fixed4 color    : COLOR;
                half2 texcoord  : TEXCOORD0;
            };

            fixed4 _Color;

            v2f vert(appdata_t IN)
            {
                v2f OUT;
                OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
                OUT.texcoord = IN.texcoord;
                OUT.color = IN.color * _Color;
                #ifdef PIXELSNAP_ON
                OUT.vertex = UnityPixelSnap (OUT.vertex);
                #endif

                return OUT;
            }

            sampler2D _MainTex;

            fixed4 frag(v2f IN) : COLOR
            {
                half4 prev = IN.color * tex2D(_MainTex, IN.texcoord);
                return lerp(half4(1,1,1,1), prev, prev.a);
            }
        ENDCG

    }

    Pass {
        Blend SrcAlpha OneMinusSrcAlpha
        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
    }
}

}

Ah, that’s actually even easier and can be done in one pass. Just take the multiply shader and adjust it like this:

fixed4 frag(v2f IN) : COLOR
{
   fixed4 prev = IN.color * tex2D(_MainTex, IN.texcoord);
   fixed col2 = tex2D(_AlphaTex, i.texcoord).r;
   //prev = lerp(fixed4(1,1,1,1), prev, prev.a); // I don't think this line is actually needed, but it is in your source
   return lerp(fixed4(1,1,1,1), prev, col2);
}

So remove the second pass and just merge the cutout into the first pass. (Instead of using alpha, you can just blend to white, since multiplying with white does nothing.)

1 Like

I made it. Thank you all. :smile:

Shader "_My/MultiplyAlphaMask" {
Properties {
    _MainTex ("Photo PNG", 2D) = "white" {}
    _AlphaTex ("Photo Mask", 2D) = "white" {}
    _Color ("Tint Color", Color) = (1,1,1,1)
}

SubShader {
    Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "DisableBatching"="True"}
    LOD 100

    ZWrite Off

    Pass
    {
        Cull Off
        Lighting Off
        ZWrite Off
        // Fog { Color (1,1,1,1) }
        Blend Zero SrcColor
        CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            struct appdata_t
            {
                float4 vertex   : POSITION;
                float4 color    : COLOR;
                float2 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex   : SV_POSITION;
                fixed4 color    : COLOR;
                half2 texcoord  : TEXCOORD0;
            };

            fixed4 _Color;

            v2f vert(appdata_t IN)
            {
                v2f OUT;
                OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
                OUT.texcoord = IN.texcoord;
                OUT.color = IN.color * _Color;
                #ifdef PIXELSNAP_ON
                OUT.vertex = UnityPixelSnap (OUT.vertex);
                #endif

                return OUT;
            }

            sampler2D _MainTex;
            sampler2D _AlphaTex;

            fixed4 frag(v2f IN) : COLOR
            {
               fixed4 prev = IN.color * tex2D(_MainTex, IN.texcoord);
               fixed col2 = tex2D(_AlphaTex, IN.texcoord).r;
               return lerp(fixed4(1,1,1,1), prev, col2);
            }
        ENDCG

    }
}

}