Alpha blending behavior difference

Hello,
I’m making a class, that can create textures. Everything was great until I have tested the code on colors with different alpha values. I noticed a wierd behavior in how Monogame draws transparent textures, which is already explained in this thread.

However, I experimented a bit and found out, that a texture I made is drawn differently than the same texture made in photoshop. The texture is a square with color (0, 0, 255, 5).
Here are example pictures, top is the loaded texture, bottom is mine created through code.
On CornflowerBlue:


On white:

On black:

Here is code I used to create the pictures:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace color_test
{
    public class Game1 : Game
    {
        private GraphicsDeviceManager _graphics;
        private SpriteBatch _spriteBatch;
        private Texture2D custom, loaded;

        public Game1()
        {
            _graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            IsMouseVisible = true;
        }

        public Texture2D CreateRectangle(int width, int height, Color color)
        {
            Color[] data = new Color[width * height];
            Texture2D texture = new(GraphicsDevice, width, height);

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    data[y * width + x] = color;
                }
            }

            texture.SetData(data);
            return texture;
        }

        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        protected override void LoadContent()
        {
            _spriteBatch = new SpriteBatch(GraphicsDevice);
            loaded = Content.Load<Texture2D>("shadepng");
            custom = CreateRectangle(200, 200, new Color(0, 0, 255, 5));
            // TODO: use this.Content to load your game content here
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();

            // TODO: Add your update logic here

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);

            _spriteBatch.Begin();
            _spriteBatch.Draw(loaded, new Rectangle(50, 50, 200, 200), Color.White);
            _spriteBatch.Draw(custom, new Rectangle(50, 250, 200, 200), Color.White);
            _spriteBatch.End();
            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }
    }
}

I really have no clue what to do, is something wrong with my code?

1 Like

afaik Spritebatch uses PreMultipliedAlpha as BlendMode per default … not sure if that is what you want, maybe you want AlphaBlend instead. (you can set it in the SpriteBatch Constructor)

For the different colors I can’t really tell, as I dont know what the ContentManager does with the PNG behind the curtain - you can just do a getdata on the loaded one and just look, what color value actually is in the texture after loading …?

Make sure that premultipled alpha in mgcb is off for given asset (ideally for all assets, it’s on by default), then for spritebatch use nonpremultipled blend state and you are good to go.

The color that was loaded is (0, 0, 5, 5) instead of (0, 0, 255, 5) and I double checked that the png had the color I intended. So I changed the values of the other square I made through code to match the new color and than the squares look the same.
The thing is, that now I have to figure out how to work with color given as parameter, to get the same result as if the texture was loaded.

Thank you, that solved majority of the problem, while not changing my function - on black background it looked the same. However they still have a little bit different hue on other backgrounds.


The loaded texture has a greyish color, the custom texture has more blueish color.

Not sure if this helps but Photoshop or has several color models and the default is new. it does affect blending and gradients…

Photoshop now uses Ottosons method of blending (Oklab ) the industry has been doing blending wrong for 20 years…How software gets color wrong

https://twitter.com/bjornornorn/status/1453069681082896394?lang=en

1 Like