Implementing Porter-Duff Rules in Direct3D

前提是你 提交于 2019-12-08 04:56:31

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.

For the "A in B" case, shouldn't DestinationBlend be Zero?

A in B

SourceBlend = DestinationAlpha
DestinationBlend = Zero

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!

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!