HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
IMG3D: 3D Texture Images

Table Of Contents

See Also
Deep Shadow/Camera Images

Introduction To 3D Texture Maps

A 3D texture map is similar to a 2D texture. However in addition to having an x and y resolution the texture has a z resolution as well (turning the pixels into voxels).

Like modern 2D images, the 3D texture files can have any number of image channels with arbitrary vector sizes per pixel.

Unlike 2D images, the 3D texture image has a bounding box. The voxel (0, 0, 0) is mapped to the xmin(), ymin(), and zmin() of the bounding box. The voxel at (xres-1, yres-1, zres-1) is mapped to the maximum values of the bounding box. Evaluations of the 3D texture have their lookup position transformed to this bounding box.

The Houdini 3D texture format is a tiled format. When reading voxels from the image, only portions of the file need to be loaded into RAM at one time. This makes it possible to read very large images. On the other hand, it means that writing the images can be problematic. Often, the data you want to write to the file is not tiled, which makes it difficult to process.

The 3D texture format can store "tags" in the texture file. These tags are arbitrary and can be used to store auxiliary information. Users can query these tags from VEX using the teximport() function.

Reading a 3D Texture

The IMG3D_Manager class is used to read data from a 3D texture. Each instance of an IMG3D_Manager is able to read values from a single channel of a 3D texture.

To read multiple channels, the best approach is to have an IMG3D_Manager for each channel to be read.

Opening the Texture

To open a 3D texture the texture file needs to be opened, but the channel also needs to be opened:

fp.openTexture(disk_filename);
fp.openChannel(channel_name);

Querying Properties of the Texture

After the file is open (before the channel is open), it is possible to query properties of the texture.

IMG3D_Manager::getCorner() // Get the corner of the bounding box
IMG3D_Manager::getSize() // Get the size of the bounding box
IMG3D_Manager::getRes() // Get the resolution of the image
IMG3D_Manager::getNChannels() // Return number of image channels
IMG3D_Manager::getChannelName() // Query the name of the channel
IMG3D_Manager::getChannelSize() // Return the number of floats in a channel
IMG3D_Manager::getChannelNumber() // Look up channel index based on name

Reading Channel Values

The IMG3D_Manager class provides several ways of accessing channel data. Most methods will perform filtering of the texture. The filter can be set by calling IMG3D_Manager::setFilter().

  • IMG3D_Manager::sample()
    Evaluate the channel at a given position in space. If the position is outside the bounding box of the texture, the method fails. Otherwise the voxels are filtered and the result is returned in the data buffer passed in. The data buffer should be large enough to hold the channel data.
  • IMG3D_Manager::gradient()
    Computes the gradient of a scalar image channel. The result buffer should be able to store 3 floats.
  • IMG3D_Manager::integrate()
    Integrate the map from one position to another. This performs a more efficient integration process than ray-marching through the 3D texture.
  • IMG3D_Manager::intersect()
    Treat a scalar channel as an iso-surface, finding the intersection point of a ray at a given density of the the iso-surface.

In addition, it's possible to load an entire channel at one time by calling IMG3D_Manager::loadUntiledChannel().

See Also
standalone/i3ddsmgen.C

Writing a 3D Texture

As mentioned in the introduction, the 3D texture format is a tiled format. The native process for writing 3D textures is to allow the IMG3D_Manager to call an evaluation callback. This is appropriate when the generation function is procedural and there's no issue with random access of the 3D image.

However, in many cases, it isn't feasible to fill a texture in random order. So, like the IMG3D_Manager::loadUntiledChannel(), it's possible to create a 3D texture with a flat image by calling IMG3D_Manager::fillUntiledTexture().

To create an 3D texture, you must first call IMG3D_Manager::createTexture(). This specifies the bounding box, resolution and a compression.

Once the 3D texture has been created, you can call either:

The sample file standalone/i3dsphere.C shows a very simple example of creating a 3D texture.