views:

620

answers:

3

What Direct3D render states should be used to implement Java's Porter-Duff compositing rules (CLEAR, SRC, SRCOVER, etc.)?

+1  A: 

I'm haven't used Java too much, but based on the white paper from 1984, it should be a fairly straightforward mapping of render state blend modes.

There are of course more that you can do than just these, like normal alpha blending (SourceAlpha, InvSourceAlpha) or additive (One, One) to name a few. (I assume that you are asking about these specifically because you are porting some existing functionality? In that cause you may not care about other combinations...)

Anyway, these assume a BlendOperation of Add and that AlphaBlendEnable is true.

Clear

SourceBlend = Zero
DestinationBlend = Zero

A

SourceBlend = One
DestinationBlend = Zero

B

SourceBlend = Zero
DestinationBlend = One

A over B

SourceBlend = One
DestinationBlend = InvSourceAlpha

B over A

SourceBlend = InvDestinationAlpha
DestinationBlend = One

A in B

SourceBlend = DestinationAlpha
DestinationBlend = One

B in A

SourceBlend = Zero
DestinationBlend = SourceAlpha

A out B

SourceBlend = InvDestinationAlpha
DestinationBlend = Zero

B out A

SourceBlend = Zero
DestinationBlend = InvSourceAlpha

A atop B

SourceBlend = DestinationAlpha
DestinationBlend = InvSourceAlpha

B atop A

SourceBlend = InvDestinationAlpha
DestinationBlend = SourceAlpha

A xor B

SourceBlend = InvDestinationAlpha
DestinationBlend = InvSourceAlpha

Chaining these is a little more complex and would require either multiple passes or multiple texture inputs to a shader.

Corey Ross
A: 

When I implement the render states for "A" (that is paint the source pixel color/alpha and ignore the destination pixel color/alpha), Direct3D doesn't seem to perform the operation correctly if the source has an alpha value of zero. Instead of filling the target area with transparency, I'm seeing the target area remain unchanged. However, if I change the source alpha value to 1, the target area becomes "virtually" transparent. This happens even when I disable the alphablending render state, so I would presume this is an attempt at optimization that's actually a bug in Direct3D.

Except for this situation, it would appear that Corey's render states are correct. Thanks, Corey!

Neal
A: 

One thing to check, make sure alpha test is off with

AlphaTestEnable = false

If that is on (along with something like AlphaFunction = Greater and ReferenceAlpha = 0), clear pixels could be thrown away regardless of the AlphaBlendEnable setting.

Corey Ross