Steffen Binas
Steffen Binas

Reputation: 1468

Combine (Blend) two images to a final image, but avoid current content

When layering multiple I have to combine them at least once with an "empty" image or background. But there is nothing like "empty". It's transparent black oder transparent white. Even being completely transparent has a color which is normally ignored when displaying.

I'd like to have the folloing:

Destination = Image1 + Image2

To do this I do in fact this:

Clear(Destination, 0); // Clear it with transparent black
Blend Image1 over Destination
Blend Image2 over Destination

Although Destination is transparent black the black contributes to the final result which is what I'd like to avoid. I could clear the destination with transparent white, but it would only work in this example and produces the same problems with darker images.

Combining Problem

I understand why the result is like it is: The directx blend formular is set like that:

BlendOp = Add;
SrcBlend = SrcAlpha;
DestBlend = InvSrcAlpha;

The alpha of the destination (DestAlpha) isn't accounted at all in this formular. What can I do to implement this everyday problem of blending two images together before rendering them somewhere else?

Upvotes: 1

Views: 2886

Answers (1)

Gnietschow
Gnietschow

Reputation: 3180

Afaik you can't achieve this with normal blending operations, but maybe you could write a appropiate shader to do the blending for you. You render on an extra texture as a rendertarget and set this texture in the pixelshader. Now you branch your writed alpha value, if the background-alpha is zero you write your imagecolor, otherwise there is already an image written on this pixel and you can do the normal alphablending in your shader. With this branch you detect, whether the pixel is empty or written before and then prevent the black color to have any impact. Hope this helps :)

A little example to visualize what I mean:

float4 targetColor = tex2D(backgroundSampler,screen.TexCoord);
float4 diffuse = tex2D(imageSampler,image.TexCoord);
// overwrite black background
if (targetColor.a == 0.0) {
  return diffuse;
}
// do alphablending
return targetColor*(1-diffuse.a)+diffuse*(diffuse.a);

Upvotes: 1

Related Questions