Moving an alpha mask or changing the values within it?

Hello guys. I’ve been using Unity for a few months and I’ve come to a point in my project where I have to write a shader. I’ve dabbled with Unity’s shaders a little bit but I’m stuck trying to figure this out.

What I’m trying to do is reveal only part of a texture using an alpha mask. I will have a normalized variable passed into the shader and I want to use that value to change how much of the texture the alpha mask will be affecting. I am using some code that i found here on the forum to use 2 textures: one as my main, and the other being the separate alpha mask. This map will uses white to represent transparency.

So my question is, is there a way to use the value I pass in to either move the alpha mask to cover more or less of the texture? Or is there a way to write to the mask using a shader, so that anything above the normalized value I passed in becomes fully transparent and everything below will be drawn at full opacity?

Here’s what I have so far:

Shader "Custom/CanvasWithAlphaMask" {
    Properties {
       _MainTex("Base (RGB) Trans (A)", 2D) = "white" {}
       _Color ("Main Color", Color) = (0,0,0,0)
       _Stencil("Stencil Texture (RGB)", 2D) = "black" {}
    }
    Subshader {
       Tags {
         "Queue"="Transparent"
         "IgnoreProjector"="False"
         "RenderType"="Transparent"
       }
 
       CGPROGRAM
       #pragma surface surf Lambert alpha
 
         struct Input {
          float2 uv_MainTex;
         };
 
         half4 _Color;
         sampler2D _MainTex;
         sampler2D _Stencil;
 
        void surf (Input IN, inout SurfaceOutput o) {
           half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
           o.Emission = c.rgb;
           o.Alpha = c.a - tex2D(_Stencil, IN.uv_MainTex).a ;
       }
       ENDCG
    }
}

You’re almost there. But rather than subtracting the mask alpha from the main alpha, you need to use the mask to reject that pixel when it exceeds a certain threshold. The clip intrinsic can be used for that. Add a shader property that represents the threshold. If the mask alpha is less than the threshold, clip/reject that pixel.

Here is a video of the shader whose code you can find below:

Shader "Custom/Transparent Diffuse (Mask cutoff)" {
Properties {
    _Color ("Main Color", Color) = (1,1,1,1)
    _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    _Cutoff ("Mask cutoff", Range(0,1)) = 0
    _MaskTex ("Mask (RGB=unused, A=mask)", 2D) = "white" {}
}

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

CGPROGRAM
#pragma surface surf Lambert alpha

sampler2D _MainTex;
sampler2D _MaskTex;
fixed4 _Color;
fixed _Cutoff;

struct Input {
    float2 uv_MainTex;
};

void surf (Input IN, inout SurfaceOutput o) {
    fixed4 mask = tex2D(_MaskTex, IN.uv_MainTex);
    clip(mask.a - _Cutoff*1.004); // 1.004 = 1+(1/255) to make sure also white is clipped

    fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    o.Albedo = c.rgb;
    o.Alpha = c.a;
}
ENDCG
}

Fallback "Transparent/Diffuse"
}

Thanks, Peter! Worked like a charm! I’ve been stuck on this for days now, you’re my hero! :slight_smile: