0

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?

Steffen Binas
  • 1,463
  • 20
  • 30
  • I'm not sure, whether you can fix this with the fixed function pipeline. Why is it important, that the images are composed in an extra buffer and not directly on the target background? What do you want to achieve? – Gnietschow Dec 10 '12 at 18:14
  • This extra buffer is needed because it's fed as an input into a pixel shader. – Steffen Binas Dec 11 '12 at 08:48
  • It doesn't necessarily need to be done in fixed function pipeline, but AFAIK the blending formular is still fixed. BTW I'm using DirectX9. What I don't like to do is combining two buffers in an separate pixelshader because that would introduce a lot of overhead. – Steffen Binas Dec 11 '12 at 08:54

1 Answers1

1

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);
Gnietschow
  • 3,070
  • 1
  • 18
  • 28
  • Yes this would work, but would make the engine a lot more complicated. Especially if I create effects with multi pass shaders I'd have to do the blending after every pass. – Steffen Binas Dec 11 '12 at 15:13
  • The only other solution I have in mind is to work with premultiplied alpha and additive blending, but this would overexpose the result. – Gnietschow Dec 11 '12 at 15:23
  • Another problem with this approach: I'd get wrong results if I have overlapping geometry with transparency because than the fixed function blend formula would be used for overlapping pixels. – Steffen Binas Aug 15 '13 at 11:56