Alpha blending between two overlapping semi-transparent shapes I am working on a 2D lighting system for my game. My approach has been to:


Create a transparency quad representing 'darkness'.
Create a stencil shader for light sources to clip from the darkness quad.
Create a shader that blends alpha from 0 -> {darkness alpha} to soften the edges of the light source.


This looks like the following:



You can see the problem - the two light source shaders that soften the shadow edges are being blended like normal transparency layers should and causing the colour to intensify. Here is another image without the darkness quad, which might make things a bit clearer:



My question: Is there any sort of alpha blending I can do to make this intersection appear 'normal' i.e. it doesn't intensify the color? If not, is there another approach which could help with this?

Update:

Here is the shader code that generates the fade on the light source - note that the _Radius is set for each light source. 

Properties
{
    _Color("Bottom Color", Color) = (1,1,1,1)
    _Radius("Radius", Float) = 1
}

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

    Cull Back
    Blend One OneMinusSrcAlpha

    Pass
    {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag

        #include "UnityCG.cginc"

        struct appdata
        {
            float4 vertex : POSITION;
        };

        struct v2f
        {
            float4 vertex : SV_POSITION;
            float distance : float2;
        };

        fixed4 _Color;
        float _Radius;

        v2f vert(appdata v)
        {
            v2f o;
            o.vertex = UnityObjectToClipPos(v.vertex);
            o.distance = distance(float3(0, 0, 0), v.vertex);
            return o;
        }

        fixed4 frag(v2f i) : SV_Target
        {               
            float distance = (i.distance / _Radius); // 0 -&gt; 1 as progressing to outside
            float normalizedDistance = 1 - distance; // 1 -&gt; 0 as progressing to outside 

            // 0 -&gt; 0.43
            fixed colorOffset = lerp(0, _Color.a, distance);

            // return alpha 
            return fixed4(0, 0, 0, colorOffset);
        }

        ENDCG
    }
}
I used Stencil Buffer to fixing your problem , you need a way for checking overlapping two or more shapes

 Shader "Custom/SemiTransparent"
{
    Properties
    {
        _Color("Color",Color) = (0,0,1,0.1)
    }
    SubShader
    {
Tags {"Queue"="Transparent" "IgnoreProjector"="true" "RenderType"="Transparent"}
ZWrite Off Blend SrcAlpha OneMinusSrcAlpha Cull Off

        LOD 100

        Pass
        {
            Stencil {
                Ref 0
                Comp Equal
                Pass IncrSat 
                Fail IncrSat 
            }

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            fixed4 _Color;

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = _Color;
                return col;
            }
            ENDCG
        }
    }
}