3

I would like to do a simple thing : render a 2d texture to a 2d render target with alpha chanel blending.

So i create my render targer :

renderTarget = new RenderTarget2D(m_graphicsDevice, 200, 200);

then I create my texture :

texture = new Texture2D(_device, 1, 1, false, SurfaceFormat.Color);
Color clr = Color.Red;
// set half transparency on my texture
clr.A = 128;
Color[] bitmap = new Color[1] {clr};
texture.SetData(bitmap);

then I clear my rendertarget white, and draw my texture twice in the render target, with a good scale, and with a multiplicative operation on color and alpha chanel.

graphicsDevice.SetRenderTarget(renderTarget);
graphicsDevice.Clear(Color.White);

BlendState myState = new BlendState();
// multiplicative blending on color
myState.ColorSourceBlend = Blend.Zero;
myState.ColorDestinationBlend = Blend.SourceColor;
// multiplicative blending on alpha
myState.AlphaSourceBlend = Blend.Zero;
myState.AlphaDestinationBlend = Blend.SourceAlpha;

spriteBatch.Begin(SpriteSortMode.Immediate, myState);
// draw my texture twice, with an overlaping part
spriteBatch.Draw(texture, new Vector2(0, 0), null, Color.White, 0, Vector2.Zero, 100, SpriteEffects.None, 0);
spriteBatch.Draw(texture, new Vector2(50, 50), null, Color.White, 0, Vector2.Zero, 100, SpriteEffects.None, 0);
spriteBatch.End();
graphicsDevice.SetRenderTarget(null);

and I draw this render target on screen, with a green background, and a nonPremultiplied renderstate so that alpha value in the texture is applied as transparency.

graphicsDevice.Clear(Color.Green);
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied);
spriteBatch.Draw(renderTarget, Vector2.zero, Color.White);
spriteBatch.End();

the result is as expected :

  • in render target, for pixels belonging to one texture only :

    • red chanel = texture red chanel (1) * render target red chanel (1) = 1
    • green and blue chanel = texture chanel (0) * render target chanel = 0
    • alpha chanel = texture alpha (0.5) * render target alpha (1) = 0.5
    • and this texture drawn above the green background gives a brown color thanks to alpha transparency set to 0.5 (1/2 red + 1/2 green)
  • in render target, for overlaping pixels (so above computation applied twice)

    • red chanel = texture red chanel (1) * texture red chanel (1) * render target red chanel (1) = 1
    • green and blue chanel = texture chanel (0) * texture chanel (0) * render target chanel = 0
    • alpha chanel = texture alpha (0.5) * texture alpha (0.5) * render target alpha (1) = 0.25
    • and this texture drawn above the green background gives a nearly green color thanks to alpha value 0.25 (1/4 red + 3/4 green)

now if I change the renderstate to just let the alpha chanel of the texture be applied, and not letting multiplication on colors :

BlendState myState = new BlendState();
// texture color is ignored, dest color remain unchanged
myState.ColorSourceBlend = Blend.Zero;
myState.ColorDestinationBlend = Blend.One;
// alpha chanel are still multiplied
myState.AlphaSourceBlend = Blend.Zero;
myState.AlphaDestinationBlend = Blend.SourceAlpha;

what I should get is :

  • in render target, for pixels belonging to one texture only :

    • red chanel = 0 * texture red chanel (1) + 1 * render target red chanel (1) = 1
    • green and blue chanel = 0 * texture chanel (0) + 1 * render target chanel (1) = 1
    • alpha chanel = texture alpha (0.5) * render target alpha (1) = 0.5
    • and this texture drawn above the green background should give light green color (1/2 white + 1/2 green)
  • in render target, for overlaping pixels (so above computation applied twice)

    • red chanel = 1
    • green and blue chanel = 1
    • alpha chanel = texture alpha (0.5) * texture alpha (0.5) * render target alpha (1) = 0.25
    • and this texture drawn above the green background should give a more intense green (0.25 * white + 0.75 * green)

and what I get is a plain white texture...

why does the alpha blending computation in my render target stops working when I don't blend colors ? My goal is to only have computation on alpha chanel, without getting the texture color. How can I do that ?

thanks

Kyle Baran
  • 1,793
  • 2
  • 15
  • 30
fbf
  • 711
  • 5
  • 5

1 Answers1

0

You said (and what I get is a plain white texture...) but I get: enter image description here

Wallstrider
  • 856
  • 1
  • 7
  • 22
  • I just rewrote the entire code above in the 'Draw' function, and tried it : I still get a blank texture in the second case (and correct behavior in first case). Did you do something special ? I'm using XNA 4.0 inside Monogame framework – fbf Mar 18 '14 at 18:03
  • Ok, look at your renderTarget width and height. It's 200 x 200. And then look where you draw your textures new Vector2(200, 200) and new Vector2(250, 250) positions. So **the textures drawn outside of renderTarget and didn't appear on renderTarget texture**. Set new Vector2(0, 0) and new Vector2(50, 50) instead. :D – Wallstrider Mar 18 '14 at 18:12
  • 1
    I have used simple XNA 4.0, just copy and paste your code, then changed texture positions, that's all. I can share the project which result image above. – Wallstrider Mar 18 '14 at 18:20
  • 1
    [Here is a link to the project](https://onedrive.live.com/#cid=59802AFBA7F9048E&id=59802AFBA7F9048E%21105) – Wallstrider Mar 18 '14 at 18:33
  • thanks wallstrider, your code does work. I compared every single line with mine, they are the same, but my code does NOT work. The only explanation I see is that I'm not using XNA 4.0 assemblies, but I'm using Xna 4.0 through monogame... looks like the problem is in monogame, not in my code... I'm investigating that way. (and for the texture size & position, these are errors in my post, the problem does not come from that. I fixed the code in my post) – fbf Mar 18 '14 at 20:58
  • Is it an android mono application? Be aware of using shaders they can cause different results as well. – Wallstrider Mar 18 '14 at 23:28
  • I'm running this test on windowsGl app with monogame 3.01 – fbf Mar 20 '14 at 08:31
  • @user3348323 I don't understand what you mean, why are you using XNA assemblies in Monogame? – jgallant Oct 21 '14 at 10:15
  • Problem fixed after i update to latest monogame release. The problem did come from monogame, not xna. – fbf Oct 22 '14 at 12:57
  • 1
    Please post this is an accepted answer to your own question. I just spent a 20 minutes trying to figure out the problem. – James Jan 10 '15 at 03:16