# Alpha blending between two overlapping semi-transparent shapes

I am working on a 2D lighting system for my game. My approach has been to:

1. Create a transparency quad representing 'darkness'.
2. Create a stencil shader for light sources to clip from the darkness quad.
3. 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)
}

{
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;

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 -> 1 as progressing to outside
float normalizedDistance = 1 - distance; // 1 -> 0 as progressing to outside

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

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

ENDCG
}
}

• I deleted my answer as I think that a blending solution won't fix this problem. I think you probably need to utilize the stencil buffer somehow to avoid writing the darkness to the same area twice. – default Mar 6 '17 at 15:26
• Yes, I have thought the same. I will pursue that idea for the moment. Thanks for trying. – Alex Mar 6 '17 at 15:28
• You could try using Max blending : stackoverflow.com/questions/2143690/… – PaulHK Mar 8 '17 at 6:41

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)
}
{
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
}
}
}