0
votes

Problem is following: I'm rendering sprites to the texture, then I render texture to the screen. Simple, right? However, when I do that, each time sprite gets rendered, it overwrites every pixel it covers, independent of alpha value of its pixels. Example:

enter image description here

Here you can see two sprites with text "ABC". First is rendered in the right top corner and second on top of it with Y offset. As you can see, the second one overrides even those pixels of first sprite that shouldn't be overwritten with background color. When I do the same, but instead of rendering it to texture and then rendering that texture to screen, I render sprites directly to screen, result is as expected and second sprite overwrites only pixels that are supposed to be overwritten.

So, I'm not quite sure what's going on there, because alpha blending is enabled for all render targets and depth test is off for screen and texture rendering. I'm using DirectX11 on Windows Phone 8 - XAML with DirectX interop.

EDIT: Restating a problem a bit: Let's say I clear a texture to red color, so when I render it to screen, I have red screen. Now I render completely transparent (color 0,0,0,0) texture to said red texture. I would expect no change and after rendering to screen, I'd get red screen. This is not the case as when I render transparent sprite, it actually writes (0,0,0,0) color to the texture and I get a red texture with transparent window. So after rendering it to the screen, I can see color screen was cleared to. What's going on?

1
Your approach should work fine. Are you certain that all other pipeline states are identical between the back-buffer-RTV and temporary-texture-RTV cases?MooseBoys
I'm pretty certain. The problem I see, is how it is possible that each pixel completely throws away the previous, to the extend of overwriting background color(the one used to clear render target) with 0 alpha color. Let's say I have red background, final texture is thus red. If I render completely transparent sprite onto it, it should stay completely red, but instead - it renders transparent sprite, so now I have red texture with transparent window!user1760770

1 Answers

3
votes

Your last comment suggests the problem. I assume that both the source textures and intermediate render target have an alpha channel, correct? If so, you need to use the correct blending equation for both color and alpha channels. Typically, the standard equation for blending directly to the back buffer omits correct alpha channel blending because back buffer alpha is usually ignored. I suspect that in your case, the color channel is getting correctly blended, but the last rendered sprite is writing its alpha value directy to the intermediate texture. As a result, those pixels are fully transparent even though they should stay opaque because a previous draw made them opaque. When you subsequently render this texture to the back buffer, the same color alpha blending causes those pixels to contribute nothing to the final image.

This is the correct setting for standard alpha-blended rendering to a texture with transparency:

// dest.rgb = dest.rgb * (1 - src.a) + src.rgb * src.a
SrcBlend = SRC_ALPHA
DestBlend = INV_SRC_ALPHA
BlendOp = ADD

// dest.a = 1 - (1 - dest.a) * (1 - src.a), with some rearranging
SrcBlendAlpha = INV_DEST_ALPHA
DestBlendAlpha = ONE
BlendOpAlpha = ADD

Also, don't forget to clear the intermediate target to transparent before rendering (not opaque black, as is common), assuming you want some parts of the texture to be transparent after rendering.