next up previous contents
Next: 1.12 User-Defined Shaders Up: 1. Functionality Previous: 1.10 Texture, Bump, Displacement,

Subsections

1.11 Texture Filtering

mental ray provides two methods for  texture filtering: a fast filtered texture lookup using image pyramids (which are similar to mip-maps but have no restrictions on texture size), and a high-quality filtering method using elliptical projections . Both methods operate on image pyramids. There is a .map image format defined by mental ray that supporting filters.

When standard image files (such as .rgb) are used for filtered texture lookups (both methods), the pyramid must be created by mental ray when the image is accessed. For high-resolution images this can take a long time (sometimes up to a minute), so it is highly recommended to create this image pyramid ``offline'' by mental images' imf_copy utility. When called with the -p option on the command line, it down-filters the source texture image file and writes out the filtered images in memory-mapped image format. If such a file is read with a local filter color texture statement in .mi scene file, the pyramid is read almost instantaneously.

Also, it is recommended to make local copies of the texture files on the machines in order to speed up access. When machines with different byte order are used in the network, there is a performance penalty when using only one version of the pyramid .map file (it has to be byte swapped), so it is recommended to generate the .map file in the native byte order on the respective machines.

The prefiltered .map file containing the pyramid can also be used for standard nonfiltered texture lookups (using a simple local color texture statement), in this case only the first (finest) level of the image pyramid is used.

Now the two methods in detail:

1.11.1 Pyramid Filtering

This method can be used very easily with existing .mi files, it is only necessary to add a ``filter scale'' modifier to the texture load statements in the scene file. Here is an example:

     local filter 0.8 color texture "tex_0" "mytexture.map"

The basic idea behind pyramid filtering is that when a pixel rectangle (the current sampling location) is projected into texture space, mental ray has to calculate the (weighted) average of all texture pixels (texels) inside this area and return it for the texture lookup. Using the average of the pixels, high frequencies which cause aliasing are eliminated. To speed up this averaging, the compression value is calculated for the current pixel location which is the inverse size of the pixel in texture space. For example, if the pixel has a projected size of four texels in texture space, then one texel is compressed to 1/4 in the focal plane (severe compression gives those aliasing artifacts).

It is very costly to project a rectangle to texture space, so usually the quadrilateral in texture space is approximated by a square and the length of one side is used for the compression value. The compression value is used as an index into the image pyramid, and since this value has a fractional part, the two levels that the value falls in between of are looked up using bilinear interpolation at each level, followed by a linear interpolation of the two colors from the level lookups. (mental ray uses also bilinear texture interpolation when no filtering is applied).

Just specifying ``filter scale color texture'' is not sufficient for an exact projection of the pixel to texture space. The  texture shader modifies the UV texture coordinates (either from specified texture surfaces or generated by cylinder projections) according to remapping shader parameters etc. In  mi_lookup_color_texture, mental ray only has the UV texture coordinates, and it is almost impossible to project the pixel corners to texture space since it is not known how to obtain additional UV coordinates or how to remap them. The remapping is done before mi_lookup_color_texture is called.

mental ray's implementation of pyramid mapping therefore adds a vector to the current intersection point in object space and transforms this point into raster space. The length of the offset vector is calculated by dividing the object extent by the texture resolution (the larger value of width and height is used). This approach assumes that texture space corresponds to object space (that is, if the object size is one object unit, the texture fully covers it). If a texture shader applies texture replications, the filter value should be set to the replication count or larger to adjust for this effect. The compression value is calculated as the distance between the raster position mentioned above and the current raster position (state - > raster_x, state - > raster_y).

Since this can not always attain satisfying results, mental ray allows multiplication of a ``user scaling'' value -- the scale value in the filter statement. Using this value, it is possible to reduce blurring (scale < 1) or increase blurring (scale > 1). For example, if the texture is replicated 10 times, which makes it appear smaller in raster space and hence requires more blurring, the filter constant should be multiplied by 10. Since texture projections are handled by shaders and not by the mental ray core, this cannot be done automatically.

Pyramid filtering also works when reflection or refraction is used, but mathematical correctness cannot be guaranteed since mental ray cannot take reflection or refraction paths into account, for the same reason.

1.11.2 Elliptical Projection Filter Lookup

This method was implemented in mental ray in order to provide a very high quality texture filtering, far superior to the pyramid filtering explained above. It eliminates most if not all of the aliasing in high texture frequencies. When using checkerboard textures mapped onto a rectangle, for example, there is much less blurring at the horizon where the texture compression is severe. With mip-mapping as explained above, the blurring at such extreme compressions is sometimes still visible.

The main cause for the excessively blurry-looking images using mip-maps is the approximation of the pixel projection area by a square. With elliptical filtering a circle around the current sampling location is projected to texture space and will give either a circle or an ellipse as a projection shape. Instead of approximating this curve by simple shapes like squares, a direct convolution (averaging) of all texels which are inside the ellipse area is done. Averaging all texels in this area can take quite long, so mental ray uses pyramids of prefiltered textures to accelerate this. There are various parameters explained below which control modification of ellipse shape and level selection in the pyramid.

The most difficult part when elliptical projections are used is that a screen to texture space transformation matrix has to be provided. This matrix is used in the filtering code to transform the circle around the current sampling location to texture space. mental ray provides two helper functions for constructing this matrix when UV texture coordinates are available; see  mi_texture_filter_project in the Writing Shaders chapter. If those are not available and (for example) direct cylinder projective mappings are used, it is much more easier to calculate this matrix.

The following filtering algorithm is applied: first, a circle in the current sampling location is transformed to the ellipse using the provided transformation matrix. Then the eccentricity of the ellipse is calculated (major radius divided by minor radius). If the eccentricity is larger than a specified maximum, the minor radius is adjusted (made larger) to make sure that this eccentricity maximum always holds. The reason for this enlargement is that the direct convolution is done in the pyramid level based on the minor axis length of the ellipse. There is another parameter which specifies the maximum allowed number of texels the minor radius may cover. If that number is exceeded in the finest level (zero), a higher level is used. In the second level, for example, the minor radius as half the size etc. Enlarging the minor radius when the eccentricity is exceeded, basically means that we are going up in the pyramid. So, for very large this ellipses, mental ray is making them ``fatter'' and uses a higher level in the pyramid. Referring to the checkerboard-mapped plane example above, the circle is projected to very large thin ellipses near the horizon, covering thousands of texels, and using the technique above mental ray just makes a few texture lookups in the higher pyramid levels.

There is another parameter which modifies the size of the circle to be projected, usually the radius is 0.5, making it larger introduces more blurring, making it less gives more aliasing.

The projection helper functions expect another parameter which is the maximum offset of the central sampling location to the two other points which have to be selected. The other two points should be inside the pixel, but since mental ray is using the current intersection primitive (the triangle) also for these points to determine the UV texture coordinates, a smaller value than 0.5 (pixel corners) is appropriate since mental ray might hit the triangle plane outside the triangle area. Usually 0.3 gives good results. When the UV coordinates are calculated using cylinder projections, it is possible to obtain the UV coordinates much faster and also much more accurately.


next up previous contents
Next: 1.12 User-Defined Shaders Up: 1. Functionality Previous: 1.10 Texture, Bump, Displacement,
Copyright 2000 by mental images