Opacity when creating lightsources

I’m following this thread and monopalle’s code to create lightsources. My goal is to darken the background and then have several lightsources that will move around. I have tried to simplify the code he posted as much as possible, and everything works fine, but for some reason I can’t get the lightsource to show some opacity even if the graphic I use it has that format

This is how it looks:

As you can see everything inside the circle has the same opacity. I would like to get it darker around the edges, just like the graphic that I use. This is the graphic I use:

Anybody knows what I may be missing?

Here is my code:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.Collections.Generic;

namespace Game7
{
    /// <summary>
    /// This is the main type for your game.
    /// </summary>
    public class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        static Vector2 position = new Vector2();
        static Vector2 direction = new Vector2();

        static Texture2D light_gradient;
        static Texture2D stones;

        RenderTarget2D darkness;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            graphics.PreferredBackBufferWidth = 900;
            graphics.PreferredBackBufferHeight = 600;
        }

    
        protected override void Initialize()
        {            
            var pp = GraphicsDevice.PresentationParameters;
            darkness = new RenderTarget2D(GraphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight);

            position = new Vector2(0,0);
            direction = new Vector2(1.5f, 0f);                       

            base.Initialize();
        }


        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);

            stones = Content.Load<Texture2D>("stones");
            light_gradient = Content.Load<Texture2D>("light");
    
        }


        protected override void Update(GameTime gameTime)
        {
            position += direction;
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            //------------- THE DARKNESS--------------------------------------
            //then I draw the darknes to ITS own rendertarget, as in previous post....
            GraphicsDevice.SetRenderTarget(darkness);
            GraphicsDevice.Clear(new Color(0, 0, 0, 200));

            //-------------- LIGHTS IN THE DARKNESS----------------------------------------------------
            //now I blend the lights with the darkness, to give me the basic "black with holes" layer....
            //first set the blendstate,
            var blend = new BlendState
            {
                AlphaBlendFunction = BlendFunction.ReverseSubtract,
                AlphaSourceBlend = Blend.One,
                AlphaDestinationBlend = Blend.One,
            };

            // then draw the lights using the blendstate above...
            spriteBatch.Begin(blendState: blend);            
            spriteBatch.Draw(light_gradient, position, null, Color.Black * 0.3f, 0, new Vector2(0, 0), 1.5f, SpriteEffects.None, 0);                      
            spriteBatch.End();
        




            // set the render target back to the backbuffer..... And draw all the render-targets and textures....
            GraphicsDevice.SetRenderTarget(null);
            GraphicsDevice.Clear(Color.Black);
        
            spriteBatch.Begin();

            //first the raw stone wall....
            spriteBatch.Draw(stones, new Vector2(0, 0), Color.White);
               
            spriteBatch.Draw(darkness, Vector2.Zero, Color.White * 0.96f);            
       
    
            spriteBatch.End();
        
            base.Draw(gameTime);
        }


    }
}

Hi,

  1. try to change you light texture as follows:
  2. draw the light texture with Additive-blend to your lightmap.
  3. draw your scene
  4. set Blend to multiply and draw your lightmap
  5. check your lightmap content using ‘rendertarget.SaveAsPng’, if it does not look OK
Color AmbientCOlor = new Color(32,32,32);

static BlendState BlendMultiply = new BlendState
{
    ColorSourceBlend = Blend.DestinationColor,
    ColorDestinationBlend = Blend.Zero,
    ColorBlendFunction = BlendFunction.Add,
    AlphaSourceBlend = Blend.One,
    AlphaDestinationBlend = Blend.One
};


protected override void Draw(GameTime gameTime)
{
    // Create lightmap
    //
    GraphicsDevice.SetRenderTarget(darkness);
    GraphicsDevice.Clear(new Color(AmbientCOlor, 255));

    // Draw lights
    // 
    spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive);
    spriteBatch.Draw(light_gradient, position, null, Color.White, 0, new Vector2(0, 0), 1.5f, SpriteEffects.None, 0);
    spriteBatch.End();

    ////////////////////////////////////////////

    // Draw scene with lighting to backbuffer
    // 
    GraphicsDevice.SetRenderTarget(null);
    GraphicsDevice.Clear(Color.Black);

    //first the raw stone wall
    //
    spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque);
    spriteBatch.Draw(stones, new Vector2(0, 0), Color.White);
    spriteBatch.End();

    // multiply with lightmap
    //
    spriteBatch.Begin(SpriteSortMode.Deferred, BlendMultiply);
    spriteBatch.Draw(darkness, new Vector2(0, 0), Color.White);
    spriteBatch.End();


    base.Draw(gameTime);
}
1 Like

Thanks so much, Sascha217! That’s exactly what I need. Works great.