Blend Mixing

Hi,
I want to intersect two 2D textures. I have two circles (or two letters), a red one and a blue one. I want my intersection to be black…
My code is very simple:

           graphics.GraphicsDevice?.Clear(Color.White);
           spriteBatch.Begin(sortMode: SpriteSortMode.Immediate, blendState: BlendState.NonPremultiplied);

           spriteBatch.Draw(circle, m_positionBlue, Color.Blue);
           spriteBatch.Draw(circle, m_positionRed, Color.Red);
           spriteBatch.End();

Of course, intersection is not black but a combination of Red and Blue:
image

I have tested a lot of combination of custom blend. How can I make the intersection black ?
Maybe I can use RenderTarget to manipulate my images but with which blending ?

I am using WPF on Windows but I suppose blending will have no difference.

Thanks in advance,

Regards,

Olivier

hm … not sure if it can be done with Blending … it’s a basic formula like

(Source Color * Source Blend) <BlendFunction> (Destination Color * Destination Blend)

what you need is more like an “if”. I can only imagine things that work in two passes … could be as simple as a postprocess color filter, could be as complex as a 1-stage-per-color approach.

But maybe there is some Blending Pro’s who indeed come up with some fancy custom blend mode? If your background is always white initially, there may options but I lack ideas :smiley:

Blend modes work on each color channel separately, so there’s no way in blend modes to make the red channel of one circle affect the blue channel of the other while drawing.

You might be able to do this using the stencil buffer but it’ll depend on how many objects you need to intersect with each other.

I need only the two circles to intersect.
How can I use stencil buffer in this case ?

Stencil may grow too complex, expecially for beginners.

The most easy to code would be to render all your circles to a texture, make a post-process effect to replace every color which is magenta (red/blue mix) with black. Done. Basically a color filter.

Post-Process Effect = Render a fullscreen Quad, read from texture, process, write to target

Perhaps you can create a custom blend state with the right combination of ColorWriteChannels, and Blend functions.

https://docs.monogame.net/api/Microsoft.Xna.Framework.Graphics.BlendState.html#Microsoft_Xna_Framework_Graphics_BlendState_ColorWriteChannels

Yeah, I was wrong in my previous post. If you have a white background, and the circles you’re drawing have 100% alpha, a multiply blend mode will give you black:

            blend = new BlendState
            {
                ColorSourceBlend = Blend.DestinationColor,
                ColorDestinationBlend = Blend.Zero
            };

This is the minimum you’ll need to use as your blend state, you might want to also set the different properties, but the defaults seem to work well in my experiments.

image

There’s a few things that need to be true for this to work:

  1. Your background is white
  2. the things you’re drawing with overlap don’t have any color channels in common(so either you have red with blue, or red with green, or red with blue+green,…)

What this blend mode does is make the color that ends up on your screen a multiplication between the source colour(what you’re drawing) and what is already on the screen(the destination color).

1 Like

It works now ! Great !

Wow! I was expecting the solution to be a bit more complicated than that.

It will need to get more complex very quickly once you go outside of the constraints I listed. The drawn shapes having no overlap in RGB and the background being white is a pretty strong restriction on using a multiply blend mode for this.