May 4, 2012

Alpha-sorting (masking) in Second Life revisited

Recent comments in an open Second Life JIRA that I've been fairly involved with have caused me to take another look at how Second Life treats alpha (transparent) textures. Now this semi-geeky stuff gets pretty anal but it can make a huge difference in how things are rendered in SL. In my case, since I make clothing, I get annoyed that prim skirts with transparencies always fight each other where they overlap.

I wrote an article to explain the issue way back when: Alpha sorting and masking in Second Life.

So this time around, I thought I'd go into a viewer setting called "Automatic alpha masks" which is accessible off your Advanced menu (CTRL-ALT-D / Rendering). There are two choices, Automatic alpha masks (deferred) and Automatic alpha masks (non-deferred).

Basically, what these two do is tell the viewer to treat any alpha as either all 1-bit (deferred) or as a blend (non-deferred). The exact algorithm for detecting the alpha and the cut-offs are not published but you can kind of see the results in the photo above (this comes from SL Universe in a post by Inhandra)

While on the one hand, hair looks better with non-deferred and horrible with deferred, other prims show texture fighting against semi-transparent backgrounds.

BTW, these settings used to be called Fast Alphas but the nomenclature was changed to make the intent more obvious.

So the point of the JIRA mentioned above is that the alphas need to be controlled by the creator, not by an arbitrary setting that may or may not apply to the original creator's intent.

Just to get even more anal about this, I did some photos of my own to show the edging effects of various textures and settings (just thought I'd use a basic Torley Linden color scheme here). These should display as crossed circles just like my old article. I tried 3 different types of textures -- TGA with alpha, PNG with transparency and PNG-8 with 1-bit transparency. To see the effects up close, click the photo to view at full size. I tried this with 256x256 pixel textures and with 1024x1024.
Default viewer settings - 256x256 TGA, PNG and PNG-8 crossed circles.
Automatic alpha mask - Deferred.
Default viewer - PNG
Automatic alpha deferred - PNG
Default viewer - PNG 1024x1024

Automatic alpha deferred - PNG 1024x1024

Obviously the worst of the bunch was the PNG-8 with 1-bit alpha (transparency) which ends up with a white edge when rendered with Automatic alphas on (picture #2). And, to be fair, these hard geometric shapes render the best under automatic alphas. Regardless, there is a fair amount of down-sampling going on in all (thus the jaggies). The down-sampling was why the setting used to be called Fast Alpha -- the smaller images rendered faster. Not so much a factor with today's much better graphics cards.

More subtle images, such as deliberate drop shadows render very poorly with auto-masking. Here's a screen shot from JIRA MAINT-651 showing this effect:

Left - pre-upload, Center - no auto alpha, Right - deferred.
To throw yet ANOTHER monkey wrench into the mix (and exactly what is a monkey wrench??), Lighting and Shadows can break alphas even further depending on what form of masking is in use -- resulting in whole black areas.

So the real solution, which has so far been avoided by Linden Lab, is to allow the creator to upload textures as they choose and designate the alpha type on a per-face basis. Given that fixing the z-buffer sorting issues are probably not going to happen, this really is the second best approach. IMHO.

(Good lord I've become geeky in my 5 years on SL. Eeek!)

As always, corrections and comments are welcome.

UPDATE:

Because of the apparent confusion over the PNG-8 format, I'm adding a few piccies to show what's up with it. :)

First I made a pink circle using a shape with pink fill in Photoshop. Next I SAVED it for Web & Devices using PNG-8, No Dither, Transparency, No Transparency Dither, Matte: None, Colors 256. This brought the output file down to just two colors. Pink (well fuschia really) and transparent. Size of final file was 256x256 pixels.

PNG-8 Source Image (see text above)
PNG-8 texture placed on prim and viewed against black background. Viewer set to normal.

PNG-8 texture placed on prim and viewed against black background. Viewer set to auto alpha mask (non-deferred)

I'm not sure what to make of this except that the auto-masking setting seems to make the image slightly more artifacty. Regardless, nothing changes here. With the auto-mask on, the alphas don't fight each other. Turned off, they do. Which just shows that SL converts the uploaded image with true 1-bit transparency into it's usual messed up format that has to be interpolated to stop the alpha fighting.

BTW, if you're going to use PNG with transparency for clothes or whatever, matte your output into whatever the main color of item is. If it's red, use red as a matte. Blue use blue. Etc. Or use black. This will at least avoid some of the white halo effect. But it won't work quite as well as TGA with alpha blended using something like Solidify in Photoshop.

5 comments:

  1. The Rendering setting is on the Develop Menu, not the Advanced Menu (Version 3.3.1). Interesting I thought this would affect performance - it did, deferred rendering increased my performance from ~40FPS to ~50FPS (Ultra on an nVidia 560ti)

    ReplyDelete
  2. To get rid of the 'halo' or white-edge, you should premultiply the alpha against a color. What this means in simple terms is DON'T USE PNG when you upload to SL. You need to make the image with a matching background color, then create an alpha channel in photoshop. Save the image as a 32-bit TGA.

    http://help.adobe.com/en_US/AfterEffects/9.0/WS3878526689cb91655866c1103906c6dea-7f7ea.html

    http://www.cgdirector.com/quick-tip-straight-alpha-vs-premultiplied-alpha/

    ReplyDelete
  3. @mcapplbee -- The first of the three crossing circles in the first two photos IS a 32-bit TGA masked against the color - there is no white band. Really I do know how to do this stuff. ;)

    Then second of three crossing circles is 24-bit PNG with transparency. No white edge there either since there are no pixels to create a white edge.

    The THIRD of the three crossing circles is an 8-bit PNG with transparency which equals a 1-bit alpha. That's the ONLY format with 1-bit alpha that you can upload into SL -- although SL probably converts it internally to some kind of 32-bit JPEG2000. I was just illustrating the possibilities and testing them. Maybe the captions should have been a little clearer.

    I do want to try something else out just to see if it makes a difference. Probably won't.

    ReplyDelete
  4. @anonymous -- I use Cool Viewer most of the time and Phoenix part of the time so for me, those settings are off the Advanced menu. Not sure where they are in Firestorm. I rarely use the official viewer.

    Interesting that you can get 40 - 50 FPS with a 560 and 3.x viewer. I rarely go above 20 FPS with a 3.x viewer. I'll have to give the official viewer a shot again to see if it's improved. I get 40 FPS with Cool Viewer though.

    ReplyDelete

All thoughts are welcome.