DDS Textures

Skorche Wrote:Outdated? There are still good reasons to load (or save) textures with premultiplied alpha. It's the only good way that I know of to avoid fringes when scaling textures.

Yes, when scaling up images premultiplied alpha removes the artifacts of interpolation between opaque and transparent pixels. However that does not necessitate premultiplication when saving out the image. It can be done at load, a flag passed to quartz perhaps, and it's really just a hack anyway.

The better solution is having the correct colors in the transparent pixels to begin with. Extruding the opaque color values out through the transparent is an easy way of achieving this.

The majority of problems I've had with fringes have been when myself or a user has unknowingly had a pre-multiplied image and the software or API used has not been treating it as such. Hence the reason I claim it does more harm than good.

I never save as premultiplied, I multiply on load when I want it. I don't actually even know how to save an image as premultiplied with any of the tools that I have.

You mention smearing the edge pixels, but how in general is this possible? Photoshop can't do it as it RLEs the completely transparent areas. Also, this requires a special extra step when saving the image.

I'll file a grievance to Apple about premultiplication in Quartz. I would like if everybody else here did as well. The significant bit here, as I see it, is that Quartz claims support for non-premultiplied graphics ( there's a parameter you can pass "kCGImageAlphaLast" I think ) which according to the docs gives you non-premultiplied data. But on 10.3 and 10.4 at least this prevented you from getting a context.

Anyway, there's nothing wrong with premultiplied data. I use it in particle systems for "burn" blending which is awesome.

There's nothing wrong with premultiplication in a compositing model, which is what Quartz enforces when you create a bitmap context to draw into. For reference, see this table.

But image data can be premultiplied, or not, depending what you're doing with it. If you're not compositing, and just loading an arbitrary 4-channel chunk of data (for example, a normal map + specular map) then you really don't want your data to be destroyed by the premultiplication. Quartz supports non-pre-multiplied images, there's just no way to access the data without compositing.

Just wanted to say that I've enjoyed this discussion, it's turned my general anger at pre-multiplication into a more well formed opinion. It's a problem that doesn't have an easy solution.

Skorche, photoshop does on occasion extrude color out through transparent areas, I haven't managed to figure out under exactly what circumstances though. I was really saying that the maths involved is easy. Perhaps a tool is needed.

A few interesting things to do with this thread and my rants...

- pngcrush will remove gamma information and other rubbish from png files. You can get it from http://pngcrush.darwinports.com/ using MacPorts, and get rid of all the crap by running "pngcrush -rem cHRM -rem gAMA -rem iCCP -rem sRGB [inputFile] [outputFile]"

- GraphicConvertor allows you to see what color values you have in transparent pixels. From memory you just discard the alpha channel.

- rmagick (ruby bindings for ImageMagick), once you manage to install it is great for doing exactly what you want with images using ruby. The composite function will happily add an alpha channel to an image without premultiplying it.

If you want to export from PS but don't want to lose color values where alpha=0, you can use the levels palette to bump your minimum alpha from 0 -> 1. Admittedly, this isn't ideal since maybe you really do want alpha=0 at some points. But in my experience this works well enough.

There's also a plugin for PS, "SuperPNG", which produces very high quality PNG output without killing color data, etc.

reubert Wrote:Skorche, photoshop does on occasion extrude color out through transparent areas, I haven't managed to figure out under exactly what circumstances though. I was really saying that the maths involved is easy. Perhaps a tool is needed.

With it you can easily make an action to solidify your image and create an alpha channel. It works perfectly for all mipmap levels. When I get around to it I'm going to try and make a script in Unity that automatically does this on texture import. (aka whenever you hit Save in Photoshop ) I don't at the moment know what their algorithm is, but I have some ideas to try.

I know it's been a month, but for a quick update, as of this morning I have a functional DDS Quicklook plugin. It didn't take a month to write! I had other things to do...

In fact, it took only about 3 hours from start to finish. Most of that was trying to figure out why my generator was being ignored by Launch Services. I'm not 100% certain, but it seemed to have to do with UTIs. Declaring the DDS UTI in a standalone quicklook generator Info.plist didn't work -- I had to write a viewer app which declared the dds UTI and relevant inheritance metadata. Then, LS recognized the bundled quicklook plugin as a handler for the public.dds UTI.

I want to polish it a little -- the viewer app is a little sparse. But when it's ready I'll post it ( with source of course ) here.

For what it's worth, it's times like this that I remember how much I like Cocoa. I just subclassed NSCustomBitmapImageRep, filled in some boilerplate. Once that's done, NSImage ( in the same process only ) transparently supports DDS files. Awesome.

Technically, it's a viewer app. But it defines the dds UTI and bundles a quicklook plugin. As far as I can tell, it works great. Plus, full source is included if you're interested in quicklook or stuff like subclassing NSCustomBitmapImageRep.