问题
What Direct3D render states should be used to implement Java's Porter-Duff compositing rules (CLEAR, SRC, SRCOVER, etc.)?
回答1:
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.
回答2:
For the "A in B" case, shouldn't DestinationBlend be Zero?
A in B
SourceBlend = DestinationAlpha
DestinationBlend = Zero
回答3:
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!
回答4:
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.
来源:https://stackoverflow.com/questions/62661/implementing-porter-duff-rules-in-direct3d