The issue seems to be that you are applying lighting to an object which should not be affected by it. It makes no logical sense that something in the local scene should be able to affect the sky, like the shadows in your sample do during the day. I think this doesn't make logical sense but perhaps it does make aesthetic sense.
If I have understood correctly what you want, then you should consider the following method:-
Break your system into two sets; things you want affected by lighting and things you don't want affected.
Render the set of light affected objects to a stencil buffer (for implementation details see this tutorial).
- You should add this to the system that currently renders the scene and simply enable and disable writing to the stencil buffer depending on whether you want lighting on the object you are currently drawing.
Use this stencil buffer when rendering the lighting buffer to only draw to areas that you want shadows (pixels occupied by objects we want illuminated).
What this will do is make sure that you only render lighting to pixels which are used to display an object affected by lighting and not pixels being used to display the sky.
At the end your draw method should resemble (code taken from here);
var a = new AlphaTestEffect(graphics.GraphicsDevice) {
Projection = m
};
var s1 = new DepthStencilState {
StencilEnable = true,
StencilFunction = CompareFunction.Always,
StencilPass = StencilOperation.Replace,
ReferenceStencil = 1,
DepthBufferEnable = false,
};
var s2 = new DepthStencilState {
StencilEnable = true,
StencilFunction = CompareFunction.LessEqual,
StencilPass = StencilOperation.Keep,
ReferenceStencil = 1,
DepthBufferEnable = false,
};
// not drawing to the stencil buffer here
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, a);
// draw all NON-light affected objects here
foreach (Sprite s in nonIlluminatedSprites)
{
spriteBatch.Draw(s.texture, s.rectangle, Color.White);
}
spriteBatch.End();
// drawing to the stencil buffer here...
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, s1, null, a);
// draw all light affected objects here
foreach (Sprite s in illuminatedSprites)
{
spriteBatch.Draw(s.texture, s.rectangle, Color.White);
}
spriteBatch.End();
// using the mask here
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, s2, null, a);
// Blend the light buffer with scene here
spriteBatch.Draw(lightBuffer.texture, Vector2.zero, Color.White);
spriteBatch.End();
Note: while a sky/mountain backdrop might not be affected by shadows you may want to have shadows cast on other background objects; such as the background walls when the game is an interior location like a house. So you might want to split the background into two things, background objects and sky/mountain backdrop.
Alternative Method
In a comment it was mentioned that the stencil buffer approach was being slow. This shouldn't be the case if generated in the same pass as rendering the main game objects as it should add very little overhead. However, there may be another method in this particular case.
If you are using a pixel shader to render all scene objects then add a new "float illuminate" attribute. Before the draw call for a non-illuminated object set this attribute to 1 and before the draw call for illuminated objects set it to 0. Then, in the pixel shader, set the alpha channel of the lighting buffer to this value.
This should mean that when you blend using alpha blending at the end of your rendering pass the lighting buffer will have transparent areas where we don't want illumination applied on the screen.
Note: I may have the 1 and 0 round the wrong way. I get this wrong most of the time and wrote this assuming that 1 means "completely transparent".