LCD subpixel rasterization

Know that old “Woz” trick for rendering text on the old Apples? They use it now for ClearType in Windows (Jim Blinn rediscovered it and identified its particular utility for LCDs) and OS X Aqua. I’ll assume you know what I’m talking about for this post, but I’ll post a more detailed explanation or linkage shortly. Seems like a pretty useful idea for vector rendering in general…like for OpenGL?

There are a couple of different approaches.

For the card manufactuers/driver writers: support this mode as a pixel format. This is almost certainly easier said than done, but I can’t think of any reason why this would be difficult to do, and they certainly have the most access/control over things. They could make it almost as fast as regular rasterization. On the other hand, these guys probably have better things to deal with. If the fruit hangs low enough (and enough people “clamor” for it) maybe we’ll get to see this.

OpenGL32.dll/ hackers: make a texture rectangle 3 times wider than the viewport. Render to the texture as a virtual “back buffer.” On SwapBuffers, copy the contents to the front buffer with the appropriate offsets for each color channel. Better yet, resample it into the front buffer using blending or register combiners or whatever. The costs are pretty severe since you have to rasterize at 3x the normal resolution, and you have to worry about the copy/blend instead of a simple swap. On the other hand, I think you’d get some pretty nice looking results since you’re essentially doing a 3x horizontal super-sampling per subpixel.

Application authors: write your application to support this. There are a couple of ways you might be able to deal with the performance problems associated with the library hackery above, particularly if you don’t want to perform the manual supersampling (no supersampling or use the cards multisampling hardware). Render your scene three times: once for each color channel, each time with the appropriate subpixel offsets. You can fight the texture bandwidth problem by actually splitting up your textures into the components. I’m not sure which is faster: using ColorMask and rasterizing directly to the framebuffer or rasterizing into three seperate 1-channel textures and combining them at the end.

There are a couple of other details here and there that I’m sure I’ve missed, but this is the best I can do in one post. I keep meaning to try this out myself, but I don’t always have access to LCDs with digital connections to new/fast 3-D accelerators, and I’m usually busy doing stuff for “the man” (aka work), which mercifully usually involves OpenGL/graphics stuff.

Tell me what y’all think.


As promised:

The talk in my previous post about splitting up textures into their components reminded me of this other idea I had. Might as well get them all out.

Image compression schemes generally use a color space other than RGB. This is because the human eye is not equally sensitive to red green and blue. Instead, they use things like the NTSC YUV color space or the LAB color space. I think they frequently use a YRB (luminance red blue) colorspace. The human eye is much more sensitive to gradations in light/dark than in color. What if you encoded textures keeping this in mind?

Instead of storing textures in RGB8, store them as two textures: one for the luminance/brightness/value at full resolution, and another for color at half or quarter resolution. The color texture can be encoded in a different texture format, like 5551, 332, palettized, or compressed. You could save alot of texture memory and bandwidth at the cost of using more texture fetch units. Depending on what you’re doing, this might be a good trade-off.


I think it’s a good idea to have an opengl texture format for the LAB colorspace, then you can use it to do some special effects way easier than with RGB.