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