Multi-texture Shaders

Some applications display multiple 2-D datasets that overlay each other and are layered on an object such as a polygon. When you want to blend the overlying textures in a specific manner, using a shader program provides precise control over how the blending occurs. With a shader multi-texture application, you can specify multiple textures and control how they are displayed relative to each other. Two areas of control are:

  1. Texture blending — the shader program controls how the textures are blended with each other and applies simple blending factors that result in an immediate update of the display. The same update in IDL would require re-blending the image and sending the result to the graphics device. This would be required for each modification.
  2. Texture coordinate mapping — the application can specify a unique set of texture coordinates for each texture, allowing independent control of the positioning of each texture on the object.

However, if you want to uniformly blend images, it may be easier to use traditional IDL methods to create a single image, which can then be used as a texture map. You can combine or "burn" the overlay data into the base image to produce a single image that IDL then displays in the usual, static manner. Suppose your multi-texture example features a map with an overlay of weather data. If the map is an IDL BYTE array with dimensions [3,256, 256] and the cloud data in an IDL BYTE array with dimensions [256, 256], then code to "burn" the clouds into the map might look like:

fmap = FLOAT(map) / 255.0 
fclouds = FLOAT(clouds) / 255.0 
fclouds = TRANSPOSE([ [[fclouds]], [[fclouds]], [[fclouds]] ]) 
map = BYTE((fmap * (1.0-fclouds) + fclouds) * 255) 

This code simply increases the amount of white in the image, proportional to the values of the cloud data, and reduces the map color by the same amount. However, to change the blending the IDL application must re-blend the image and send the results to the graphics device each time a blending factor changes. A shader program can handle such multi-texturing tasks with greater flexibility and performance.

Note
Often data for multiple textures will be correctly sized and positioned to map onto a surface in the same way. However, if you need change the position of one texture in relation to others, see Repositioning Textures.

Uniform Variables and Multi-Texture Shaders

When more than one texture is being layered on a surface or polygon, you do not need to use SetUniformVariable to pass the texture data associated with the primary image object to the shader program. (The primary image is the one to which the shader object is attached). The texture map associated with the primary image object data is automatically contained in the reserved uniform variable _IDL_ImageTexture. However, you do need to use SetUniformVariable to pass any additional textures to the shader program.

Note
If SetUniformVariable references an IDLgrImage object with dimensions that are not a power of 2, the image will be padded to the next largest power of 2. If the dimensions of the IDLgrImage are larger than MAX_TEXTURE_DIMENSIONS (returned by IDLgrWindow::GetDeviceInfo) then the image will be scaled down to MAX_TEXTURE_DIMENSIONS. Keep this in mind when generating texture coordinates to access the texture map.