4.1 Texture Formats

There are several different subtypes of textures, differing by the element type stored, the dimensionality of the texture, and the format of the data. In the following descriptions, T can be any tuple type, and indicates the type stored in a texel and returned upon lookup.

In the future, we hope to support more general element types, such as composite C++ types containing a number of Sh tuple types. For now, however, textures can only store a single tuple channel, although you can always define your own classes to simplify the interface to multi-channel “textures”.

To specify a texture using byte-oriented types (for instance), you must use tuple types with that storage class: ShAttrib3ub , in the case of unsigned byte textures. In addition to taking less space, such textures may also require fewer shader resources to support interpolation and filtering. If a floating-point storage type is used, then a floating-point texture will be allocated, but this is often overkill.

In discussing the various data formats below, we will use the ShTexture name, although this really relates specifically to linearly interpolated and filtered textures. The same data formats are also available for ShArray s and ShTable s.

ShTexture1D<T>(int r):
A 1D texture holding type T. The parameter r gives the size as the number of texels. Hardware textures usually must have sizes that are an integral power of two in order to support MIP-mapping. Once a texture has been constructed, its size cannot be changed.
ShTexture2D<T>(int rs, int rt):
A 2D texture holding type T. The construction parameters rs and rt give the size in texels of the s and t dimensions, respectively. In hardware, 2D textures usually be a power of two in size. Once a texture has been constructed, its size cannot be changed.
ShTextureRect<T>(int rs, int rt):
A 2D texture holding type T. Semantically, this texture type is the same as Texture2D . It uses a rectangular texture type internally, which allows non-square sizes that are not a power of two. However, such texture types usually do not support filtering natively, so shader code may need to be generated to support this functionality. The overhead to support filtering can be high, so use of a TableRect or ArrayRect is recommended whenever possible.
ShTexture3D<T>(int rx, int ry, int rz):
As with 2D textures, these 3D volumetric textures must have resolutions that are a power of two in size. Different platforms may or may not support trilinear interpolation completely in hardware, but the Sh version does (even if it requires additional shader code). Normally, hardware supports 3D textures only with rx, ry and rz being powers of two.
ShTextureCube<T>(int rs, int rt):
Cube maps support six faces which are specified by setting six memories. All of these textures should be the same size, which should be powers of two.

Cube maps are indexed by a 3D vector whose length is ignored. Instead the ray from the origin of the cube in the direction of the given vector is intersected with a cube and one of the six faces is referenced.

Cube maps are useful for environment maps and other functions defined over a sphere. The Sh cube-mapped texture class automatically sets up the correct border conditions and MIP-map levels for cube maps (whenever possible).

Note that on most hardware, rectangular textures are internally indexed by [0,w] [0,h] coordinates, whereas other textures are indexed using [0,1]n coordinates. If you use the “[]” operator on non-rectangular textures, or the “()” operator on rectangular textures, be aware that Sh may have to insert additional scaling code, making the shader slightly slower. Whenever possible, to maximize performance you should use the native access mode for texture lookups.


Note: This manual is available as a bound book from AK Peters, including better formatting, in-depth examples, and about 200 pages not available on-line.