OpenImageIO/oiio — pull request #380 by lgritz (2012-06-19 20:56:57+00:00)
Title: Review: make texture filtering test

Sometimes people complain that our filtered texture looks "too blurry." It's very hard to know, visually, except in the case of egregious errors. So I tried to make a careful test to be sure that we are absolutely, positively sampling the right MIPmap levels exactly for the derivatives we are passed.

I added a --filtertest option to testtex (after some refactoring of testtex.cpp), and a new testsuite/texture-filtertest that uses it.

'testtex --filtertest' produces an image where each pixel samples at the center of the source image, and keeps the minor axis of the filter at 1/256, but we vary the eccentricity (i.e. major axis length) as we go left (1) to right (32), and vary the angle as we go top (0) to bottom (2pi).

If filtering is correct, all pixels should sample from the same MIP level because they have the same minor axis (1/256), regardless of eccentricity or angle. If we specify a texture that has a distinctive color at the 256-res level, and something totally different at the 512 and 128 levels, it should be easy to verify that we aren't over-filtering or under-filtering.

And, hey, we have such a texture: ../oiio-images/miplevels.tx. This image is all green (except for black "256" text) on the 256-res level, all red at the 512 level (except for black "512" text), and all blue at the 128 level (except for black "128" text). So, a correct behavior for this test will be to have an all-green appearance. If there is any over-blurring or aliasing, pulling in texels from other MIP levels, you will see non-zero blue or red channel values. Note that we do expect the green level to vary a bit, because some angles and filter major axis sizes will pull in some of the black of the "256" text. That's ok. The important thing is no red or blue (beyond minuscule amounts that would be due to acceptable numerical errors in the filter estimation).

And guess what, the image is in fact all green. The texture filtering code, if it has errors, are not errors which are causing us to select the wrong MIPmap levels.

In light of this, what could cause people to think texture was too blurry? A few theories:

1. We could be getting something else wrong. Computing the wrong eccentricity or filter angle might make certain grazing angles too blurry, but would not give a general appearance of too much blur everywhere. I'll try to find a way to test this as well.

2. It could be that our practice of computing derivatives in the renderer to imply filters that are approximately pixel-wide is too conservative, and if we are sampling geometry with many samples per pixel, we should also reduce the derivatives (at least a bit) to make texture lookups sharper. Note that this would result in much greater texture I/O and could severely harm rendering performance.

3. The filtering may be exactly right, and impossible to make look better, and the users are just plain wrong, expecting an appearance that is not possible without significant aliasing (which may indeed look sharper, but will cause other problems).

4. Could be something else I haven't thought of.