-
|
|
Premultiplied Alpha - How to implement in XNA?
|
I've finally found out what had been causing some graphical oddities, and now that I'm finally working on my game and using multiple rendertargets and blending, this "smaller" problem is effecting everything - so I need a fix.
After now knowing it has to do with using "premultiplied alpha", I still can't figure out how to get it to work in XNA... so could anyone tell me how the below code should look so as to use premultiplied alpha?
| Sprite_Batch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None); |
| |
| RenderState.SourceBlend = Blend.One; |
| RenderState.DestinationBlend = Blend.InverseSourceAlpha; |
| |
| Sprite_Batch.Draw(); |
| |
| Sprite_Batch.End(); |
Thanks very much.
EDIT: Also, does my setting for SurfaceFormat when creating my render targets matter? Currently it's set to SurfaceFormat.Color...
|
|
-
-
- (10493)
-
Team XNA
-
Posts
7,929
|
Re: Premultiplied Alpha - How to implement in XNA?
|
That code looks right for selecting premultiplied alpha.
What goes wrong when you try this? What exactly are you trying to draw?
XNA Framework Developer -
blog - homepage
|
|
-
|
|
Re: Premultiplied Alpha - How to implement in XNA?
|
Using this method results in removing any part of an image that has a transparent image over it. So lets say I have a feathered circle that's saved as a PNG. Any part of the "feathering" that is over another image results in the image underneith the circle not being drawn - which also leaves a jagged looking edge where the circle should be feathered.
I can try taking a screen capture if neccessary...
EDIT: Actually, I'm wrong. it appears to be rendering the color behind anything transparent as white.
|
|
-
-
- (10493)
-
Team XNA
-
Posts
7,929
|
Re: Premultiplied Alpha - How to implement in XNA?
|
What exactly do you mean "anything underneath the image is not drawn"? Is the topmost sprite being drawn opaque? I think I'm missing some context to understand what you are doing here.
XNA Framework Developer -
blog - homepage
|
|
-
|
|
Re: Premultiplied Alpha - How to implement in XNA?
|
http://www.dcnproductions.com/Misc/Samples/IMG00231.jpg
The above link shows what I get when I do the suggested premultiplying of alpha. However, it does worse than the following (default) method...
http://www.dcnproductions.com/Misc/Samples/IMG00232.jpg
This link shows how XNA naturally (or by default) does alpha. Although smoother, it picks up the red background color (which is what I'm clearing the screen to).
What I'm doing is rendering images (or just cleared screens) to render targets, then rendering the images made from the render targets to the main buffer.
|
|
-
-
- (10493)
-
Team XNA
-
Posts
7,929
|
Re: Premultiplied Alpha - How to implement in XNA?
|
Onions:
What I'm doing is rendering images (or just cleared screens) to render targets, then rendering the images made from the render targets to the main buffer.
Gotcha - I missed the part about you using rendertargets.
Have you read Tom Forsyth's article about premultipled alpha? What you're doing here is what he describe as compositing translucent layers. You can work through the math he presents for the various blending stages to see where you are going wrong. The best way to debug this kind of thing is using PIX: take a single frame capture and use the debug-this-pixel option to examine all the drawing passes, blending operations, inputs, and outputs and understand why your colors are ending up the way they are.
Wild guess: are you clearing your rendertargets properly? What color do you clear them to?
XNA Framework Developer -
blog - homepage
|
|
-
|
|
Re: Premultiplied Alpha - How to implement in XNA?
|
Shawn Hargreaves:
Wild guess: are you clearing your rendertargets properly? What color do you clear them to?
I either clear them like such "GraphicsDevice.Clear(Color.TransparentBlack)" (if I don't want to clear the screen), or like so "GraphicsDevice.Clear(BG_Color)" (where BG_Color is any color I specifiy).
In the two screenshots I showed, I first rendered to a rendertarget a blank cleared screen using the color red. I then rendered everything else you see in the screenshots (2 PNG images) to a rendertarget clearing the screen with TransparentBlack. After that I then render the two render targets (now texture2Ds) to my main buffer - first the red screen, then the 2 PNG images.
EDIT: And yes, I did read over Tom Forsyth's article - however, I'm unsure how to implement what he said into XNA...
|
|
-
-
- (10493)
-
Team XNA
-
Posts
7,929
|
Re: Premultiplied Alpha - How to implement in XNA?
|
What format are your rendertargets?
As I said before, PIX is by far the best way to debug this kind of thing. You can work through on paper what result you would expect for each blending operation you are applying, then look in PIX to see what result you actually got, and pretty quickly hone in one wherever your program is deviating from what you expected.
XNA Framework Developer -
blog - homepage
|
|
-
|
|
Re: Premultiplied Alpha - How to implement in XNA?
|
Shawn Hargreaves:What format are your rendertargets?
As I said before, PIX is by far the best way to debug this kind of thing. You can work through on paper what result you would expect for each blending operation you are applying, then look in PIX to see what result you actually got, and pretty quickly hone in one wherever your program is deviating from what you expected.
I am using SurfaceFormat.Color.
And I will look into this PIX you speak of. Is this a seperate program, or part of XNA/GameStudio?
|
|
-
-
- (10493)
-
Team XNA
-
Posts
7,929
|
Re: Premultiplied Alpha - How to implement in XNA?
|
|
|
-
-
- (110)
-
premium membership
-
Posts
308
|
Re: Premultiplied Alpha - How to implement in XNA?
|
Premultiplied alpha requires an extra step to work correctly:
That step is premultiplying your texture by it's alpha channel. :-)
..
In other words, the areas of the texture that have an alpha of zero should also have a colour of zero. Alpha of 0.5 should have colours half their normal brightness, etc. The screenshot you show seems to suggest you are not changing your texture.
Xen: Graphics API for XNA www.codeplex.com/xen
|
|
-
|
|
Re: Premultiplied Alpha - How to implement in XNA?
|
StatusUnknown:
Premultiplied alpha requires an extra step to work correctly:
That step is premultiplying your texture by it's alpha channel. :-)
..
In other words, the areas of the texture that have an alpha of zero should also have a colour of zero. Alpha of 0.5 should have colours half their normal brightness, etc. The screenshot you show seems to suggest you are not changing your texture.
Would you mind, then, showing me some sample code that would get the result I'm wanting? I'd appreciate it if so.
|
|
-
-
- (110)
-
premium membership
-
Posts
308
|
Re: Premultiplied Alpha - How to implement in XNA?
|
It's nothing to do with the code, it's what you do to the source image...
For example, given the following image:
With the following Alpha Channel:
Then, the pre-mulitplied version has the RGB premultiplied by alpha:
The image retains the alpha channel, it's just the RGB changes.
Xen: Graphics API for XNA www.codeplex.com/xen
|
|
-
-
- (690)
-
premium membership
-
Posts
99
|
Re: Premultiplied Alpha - How to implement in XNA?
|
Hello ,
I would like to play about with pre-multiplied alpha but I'm a bit confused on how you pre-multipy the alpha channel with the source image.
I've got paint shop pro and gimp and was wondering if some one could point me in the right direction on how you would pre-multiply (prem0.png) with (prem1.png) to obtain (prem3.png)
In case anyone was wondering the png I'm refrencing are the ones in the post above.
Thank you.
phill
|
|
-
-
- (10493)
-
Team XNA
-
Posts
7,929
|
Re: Premultiplied Alpha - How to implement in XNA?
|
If you have a tool that supports multiple layers (Photoshop, Gimp, Paint.NET, etc) you can make a copy of your alpha channel on a second layer, then set this to multiply with the main layer.
If I was making a game that used a lot of premultiplied alpha, I'd probably automate this using a custom content processor though. This would be a great use for a custom processor: it would be trivial to make one that premultiplies the texture RGB by the alpha, thus saving the need to manually do this inside your paint program.
XNA Framework Developer -
blog - homepage
|
|
-
-
- (690)
-
premium membership
-
Posts
99
|
Re: Premultiplied Alpha - How to implement in XNA?
|
Thank you very much for you help!
|
|
|