|
![]() Note: page contains many images; may take longer than usual to load. Powerful raytracing has been available on the desktop for a while now. Today's PCs even have enough memory to load up the high resolution textures useful for geographic viusalizations. However, if you're not getting all the texture quality you deserve from your raytracer, then the information below should help. We use POV-Ray™ for our examples, but the techniques should be applicable to other raytracers.
Of Pixels and Texels If you attach a bitmap picture to an object (in our case, a simple flat rectangle), and just have your raytracer render it with default settings, odds are you'll get something like this:
![]() While the map's content might actually be that noisy, the indecipherable text and broken border lines are a giveaway that something is wrong: texture pixels (texels) are being dropped. This problem is formally known as aliasing, which means that a high-frequency signal (such as our texture, which in this case has several times greater resolution than the display window) is being converted too bluntly into the low-frequency signal we need for display. Every sixth or so texel winds up unchanged onto the screen, pretending to represent the information from its neighbouring texels, hence the "alias" term. Without the colors from the neighbouring texels, the rendering just can't look right. It's like we're looking through a grid and seeing only every other part of the texture. If you've played video games, you're probably familiar with the term mipmapping. This is a texel averaging technique that blends texels together to antialias them. However, mipmapping works for games since games use scanline rendering and the scenery is often moving. In a raytracer, it gets awkward to figure out the correct mipmap levels when secondary rays are cast by reflective objects, and mipmaps don't really hold enough data to handle special cases, such as when lots of texels map to a single screen pixel. You've probably seen how slanting surfaces in games lose detail too quickly, especially in the distance. Anisotropic mipmap filtering helps, but it still leaves room open for other artifacts that can spoil a still image. In a perfect world, raytracers would cast four camera rays to represent the corners of a screen pixel to figure out what part of an object's surface lies within the pixel. The diagram below shows a screen pixel that maps onto a sphere's limb (we're exaggerating the scale here to be obvious, but a sufficiently small sphere would find itself viewed this way).
![]() This projected screen pixel would then be mapped onto the texture. Below, we have a simple black-and-white low-resolution bitmap applied to the sphere, and with the projected screen pixel, we can tell which texels lie inside it (and should therefore be used to compute the screen pixels' color):
![]() Here's the projected screen pixel transformed into texture space, with the contained texels shown more clearly:
![]() Now all that's needed is, for each texel, to compute how much of it lies within the polygon, and use that amount to adjust its contribution when averaging all the contained texels together. In this particular case, we have 17 white texels, 12 partial white texels, 7 black texels and five partial black texels. Overall the final color is light gray. Now, multiple polygon intersection is a lot of work just to calculate the color of one screen pixel. It's particularly brutal if most of the texture is far from the camera and lots of texels fit within each screen pixel. So far we have an idealistic brute-force approach that, fortunately, can be approximated easily, elegantly, and much faster, and without using any extra memory for mipmapping or dealing with mipmap limitations. While brute force would be nice, it's best left to those who want idealized renders to use as test targets for more practical algorithms. If your image editor supports good downward resampling, you can perform a flat brute-force texel averaging which will give you a good quality yardstick to compare with your renderer (in our DEMedit tool, for example, just load up a bitmap and press R).
Why, Just Turn on Antialiasing, of Course Any production raytracer offers antialiasing of screen pixels. By shooting multiple camera rays for each one, we can hit objects in the same area as our projected screen pixel, sample individual texels and average them as part of the antialiasing process. It's as if we had increased the resolution of our screen and forced the texture resolution to match closer to it. Better still, if any of our rays hit different objects, their color contributions are automatically averaged correctly. We don't have to worry about splitting the screen pixel projection into multiple polygons and related nastiness. Here's the same texture as before, this time with antialiasing enabled (using POV-Ray's default settings). For our purposes, we'll stick to non-recursive AA.
![]() Okay, it's better, but two things stand out: the background is still pretty noisy, and the text in the foreground is still very choppy. What gives? A common beginner's mistake is to use the wrong amount of light. In our case, the scene is too bright (or has too much gamma correction), and this compounds the problem by increasing contrast, which causes POV-Ray's default antialiasing optimizer to cast less rays than normal. We also need to increase the antialiasing (i.e., supersampling) effect, but having the correct lighting has to take precedence or it will make our efforts in vain.
![]() Finally! Now we're getting somewhere. Border lines are solid (almost all of them, anyway), the foreground text looks like text, and the maps fade into the background smoothly. The lighting has been lowered a bit, the antialising level has been increased to 9 (which shoots a maximum of 81 rays per pixel), and the contrast threshold for the AA optimizer has been lowered to 0.1 from 0.3. Usually, 0.3 is an acceptable value, but you may find lower values make a useful difference. If you want utmost quality, use a threshold value very close to zero instead of zero; otherwise you'll wait while dead pixels such as the background, blank sky, or map margins take their sweet time being fully antialiased.
Don't Forget the Foreground Raytracers usually also support texture interpolation, which governs how to handle the case when a single texel covers many screen pixels. Even a high-res texture can find itself in this situation if your camera has moved close to the ground. The examples below show the effect of varying POV-Ray's imagemap interpolate option from 0 (none) and 2 (bilinear):
Well, that's it. Just one last picture showing a different angle, but with the same sloped setup to correctly assess foreground and background texture render quality. If you're using aerial photos, the easy rule of thumb is, hold out for the it-feels-like-you're-flying-above-the-actual-terrain effect. :)
![]() |
Copyright Daylon Graphics Ltd.