Sign in to follow this  

Premultiplied Alpha: Creating/Loading Textures In Practice

This topic is 3868 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've read the resources and everything I can find on this site and others about using premultiplied alpha textures. However, I can't find a good resource that says how to create/set the texture up! Do I need to create the textures with premultiplied alpha (something that appears to be either non-intuitive or difficult, and Photoshop is not available). Should I be doing the premultiply in code when I load the texture? Should I be rendering with a shader instead? Does DirectX handle it when I load the texture with the DXT2/4 values? (I understand those are disappearing in DX10, so that is probably not what I'm looking for; also because TomF says not to) I understand the rendering pipeline and how to set up the device/render states for premultiplied alpha, I just need to know how to get the texture to the proper state for it. My specifics: Using C# with Managed DirectX 9. Our current textures are TGA/PNG, generally with alpha channels. Trying to use premultiplied alpha textures for our particle systems (for fire/smoke/etc.,.) Again, I need a non-Photoshop solution. Resources I've already looked at: http://home.comcast.net/~tom_forsyth/blog.wiki.html#%5B%5BPremultiplied%20alpha%5D%5D http://www.td-grafik.de/ext/xfrog/alpha/index.html http://www.gamedev.net/community/forums/topic.asp?topic_id=428576

Share this post


Link to post
Share on other sites
First thing to realize is that you need 5 channels of information to fully utilize the potential of the premultiplied alpha format:
R, G, B = Color channels
A = Normal alpha blend channel, dest = lerp(alpha, source, dest)
Add = Additive, dest = dest + source * Add

Combining them equals the following equation (alpha blend first, then add):
dest = source * alpha + dest * invAlpha + source * add
or (add first, then alpha blend)
dest = (dest + source * add) * invAlpha + source * alpha

Simplified:
dest = source * (alpha + add) + dest * invAlpha
or
dest = dest * invAlpha + source (add * invAlpha + alpha)

For the first equation it's easy to see that (alpha + add) could be greater than one, wich could cause problems.
For the second version there's no way that the (add * invAlpha + alpha) could become greater than one, so I'd choose that version.

As for the textures, I would make a small tool that takes a standard alpha blend texture (RGBA) and an alpha only texture (optional) that controls the additive component as input and creates a new RGBA as output, i.e:

CoolFireTexture_rgba.tga <= Color and "normal" alpha blend channel.
CoolFireTexture_add.tga <= Greyscale containing additiveness.

for every pixel
temp = CoolFireTexture_add.a * (1 - CoolFireTexture_rgba.a) + CoolFireTexture_rgba.a;
output_rgba.r = CoolFireTexture_rgba.r * temp
output_rgba.g = CoolFireTexture_rgba.g * temp
output_rgba.b = CoolFireTexture_rgba.b * temp
output_rgba.a = CoolFireTexture_rgba.a




Just my 2c,
Disclaimer: I'm very tired and could be very wrong... :)

Edit: Spelling..

Share this post


Link to post
Share on other sites
Premultiplied alpha is just precomputing part of the alpha blending equation.

The equation starts out as C0 = C1 * A + C2 * (1 - A)

Since C2 (the background) is always changing and the A depends on what you're blending with, you can't really precompute that part of the equation.

However, since C1 and A are part of the same image, you can do that computation anytime beforehand and keep the value around and then the equation becomes C0 = C1p + C2 * (1 - A) and you save a tiny bit of computation.

It doesn't really matter when or where you premultiply the color values by the alpha - any time before rendering is "pre". It could be part of your loading code, or part of a preprocessing utility, or anywhere else you want.

Share this post


Link to post
Share on other sites
Thanks for the responses! I had a lot of success with this today. I'll try to remember to post some screenshots and code segments tomorrow to round out the thread.

Share this post


Link to post
Share on other sites

This topic is 3868 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this