Difference between revisions of "Array Texture"

From OpenGL.org
Jump to: navigation, search
(No longer a stub.)
m (Corrected order of words "level" and "contains" in first paragraph.)
 
(19 intermediate revisions by 5 users not shown)
Line 4: Line 4:
 
}}
 
}}
  
An '''Array Texture''' is a [[Texture]] where each mipmap contains a series of 1D or 2D images of the same size. Array textures are structurally similar to [[3D Textures]] in that they have an effective "depth" component. However, filtering never takes place between the separate textures in the array, and lower mipmaps still have the same number of array layers.
+
An '''Array Texture''' is a [[Texture]] where each mipmap level contains an array of images of the same size. Array textures may have [[Mipmap]]s, but each mipmap in the texture has the same number of levels.
 +
 
 +
The domain of the images in the array depend on the array texture's specific type. Array textures come in 1D and 2D types, with [[#Cubemap arrays|cubemap arrays]] available on some hardware.
 +
 
 +
The high cost of texture switches resulted in a widespread preference for texture atlases (a single texture which stores data for multiple objects). This resulted in fewer texture switching, and thus less overhead. Array textures are an alternative to atlases, as they can store multiple layers of texture data for objects without some of the problems of atlases.
  
 
Array texture are not usable from the fixed function pipeline; you must use a [[Shader]] to access them.
 
Array texture are not usable from the fixed function pipeline; you must use a [[Shader]] to access them.
Line 14: Line 18:
 
== Creation and Management ==
 
== Creation and Management ==
  
1D array textures are created by binding a newly-created texture object to {{enum|GL_TEXTURE_1D_ARRAY}}, then creating storage for one or more mipmaps of the texture. This is done by using the "2D" image functions; the "{{param|height}}" parameter sets the number of layers in the array texture.
+
1D array textures are created by binding a newly-created texture object to {{enum|GL_TEXTURE_1D_ARRAY}}, then [[Texture Storage|creating storage]] for one or more mipmaps of the texture. This is done by using the "2D" image functions; the "{{param|height}}" parameter sets the number of layers in the array texture.
  
 
Every row of pixel data in the "2D" array of pixels is considered a separate 1D layer.
 
Every row of pixel data in the "2D" array of pixels is considered a separate 1D layer.
Line 24: Line 28:
 
Here is a source-code example:
 
Here is a source-code example:
  
<source lang="c">
+
{{snippet|:Example/Texture Array Creation}}
GLuint texture = 0;
+
 
+
GLuint width = 2;
+
GLuint height = 2;
+
GLuint levelCount= 2;
+
 
+
//Read you texels here. In the current example, we have 2*2*2 = 8 texels, with each texel being 4 GLubytes.
+
GLubyte texels[32] =
+
{
+
    //Texels for first image.
+
    0,  0,  0,  255,
+
    255, 0,  0,  255,
+
    0,  255, 0,  255,
+
    0,  0,  255, 255,
+
    //Texels for second image.
+
    255, 255, 255, 255,
+
    255, 255,  0, 255,
+
    0,  255, 255, 255,
+
    255, 0,  255, 255,
+
};
+
 
+
glGenTextures(1,&texture);
+
glBindTexture(GL_TEXTURE_2D_ARRAY,texture);
+
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MIN_FILTER,GL_LINEAR); //Always set reasonable texture parameters
+
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
+
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
+
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
+
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, width, height, levelCount, 0, GL_RGBA, GL_UNSIGNED_BYTE, texels);
+
</source>
+
  
 
Note that, unlike for [[3D Textures]], each mipmap uses the ''same'' number of layers. So if you're allocating 3 mipmaps of a 2D array texture, it would look like this:
 
Note that, unlike for [[3D Textures]], each mipmap uses the ''same'' number of layers. So if you're allocating 3 mipmaps of a 2D array texture, it would look like this:
Line 65: Line 40:
  
 
== Access in shaders ==
 
== Access in shaders ==
{{main|GLSL Sampler}}
+
{{main|Sampler (GLSL)}}
  
 
Texture arrays have separate sampler types: {{code|sampler1DArray}} and {{code|sampler2DArray}}. When accessing them within a shader, you use one extra texture coordinate. So {{code|sampler1DArray}} would use a 2D texture coordinate, while {{code|sampler2DArray}} would use a 3D texture coordinate.
 
Texture arrays have separate sampler types: {{code|sampler1DArray}} and {{code|sampler2DArray}}. When accessing them within a shader, you use one extra texture coordinate. So {{code|sampler1DArray}} would use a 2D texture coordinate, while {{code|sampler2DArray}} would use a 3D texture coordinate.
  
The last coordinate is the layer number to access. For floating-point texture coordinates (when not using texture functions like [[GLSL_Sampler#Direct_texel_fetches|{{code|texelFetch}}]]), the floating-point layer is used to compute the integer layer index by the following function:
+
The last coordinate is the layer number to access. For floating-point texture coordinates (when not using texture functions like [[Direct Texel Fetch|{{code|texelFetch}}]]), the floating-point layer is rounded then clamped to compute the integer layer index by the following function:
  
 
  actual_layer = max(0, min({{param|d}} - 1, floor({{param|layer}} + 0.5)) )
 
  actual_layer = max(0, min({{param|d}} - 1, floor({{param|layer}} + 0.5)) )
  
Here, {{param|d}} is the number of layers in the texture, and {{param|layer}} is the floating-point layer from the texture coordinate.
+
Here, {{param|d}} is the number of layers in the texture, and {{param|layer}} is the floating-point layer from the texture coordinate. For example, to sample at s = 0.4, t = 0.6, for layer 2, use vec3(0.4, 0.6, 2).
 +
 
 +
{{legacy note|Array textures cannot be used with fixed-function OpenGL's texturing systems. You must use shaders to access them.}}
  
 
== Cubemap arrays ==
 
== Cubemap arrays ==
{{main|Cubemap_Texture#Cubemap_array_textures}}
+
{{main|Cubemap Array Texture}}
 +
 
 +
Cubemap textures can be arrayed, if {{require|4.0|texture_cube_map_array}} is available. In a cubemap array texture, each array image is conceptually a cubemap. However, all OpenGL APIs that act on cubemap array textures treat them as being a special case of 2D array textures. Therefore, the number of layers is really 6 * the number of actual cubemaps in the array. It is only within a shader where the layer index provided is the actual cubemap index in the array.
 +
 
 +
== Limitations ==
  
Cubemap textures can come in arrays, if OpenGL 4.0 or {{extref|texture_cube_map_array}} is defined.
+
Array texture sizes are normally limited to the usual {{enum|GL_MAX_TEXTURE_SIZE}} limitation. However, the dimension that represents the number of array levels is limited by {{enum|GL_MAX_ARRAY_TEXTURE_LAYERS}}, which is generally much smaller. OpenGL 4.5 requires that the limit be at least 2048, while OpenGL 3.3 requires it be at least 256.
  
 
[[Category:Textures]]
 
[[Category:Textures]]

Latest revision as of 07:51, 3 June 2015

Array Texture
Core in version 4.5
Core since version 3.0
EXT extension EXT_texture_array

An Array Texture is a Texture where each mipmap level contains an array of images of the same size. Array textures may have Mipmaps, but each mipmap in the texture has the same number of levels.

The domain of the images in the array depend on the array texture's specific type. Array textures come in 1D and 2D types, with cubemap arrays available on some hardware.

The high cost of texture switches resulted in a widespread preference for texture atlases (a single texture which stores data for multiple objects). This resulted in fewer texture switching, and thus less overhead. Array textures are an alternative to atlases, as they can store multiple layers of texture data for objects without some of the problems of atlases.

Array texture are not usable from the fixed function pipeline; you must use a Shader to access them.

Terminology

Each mipmap level of an array texture is a series of images. Each image within a mipmap is called a "layer".

Creation and Management

1D array textures are created by binding a newly-created texture object to GL_TEXTURE_1D_ARRAY, then creating storage for one or more mipmaps of the texture. This is done by using the "2D" image functions; the "height​" parameter sets the number of layers in the array texture.

Every row of pixel data in the "2D" array of pixels is considered a separate 1D layer.

2D array textures are created similarly; bind a newly-created texture object to GL_TEXTURE_2D_ARRAY, then use the "3D" image functions to allocate storage. The depth​ parameter sets the number of layers in the array.

Each 2D row/column sequence of pixel data in the "3D" array of pixels is considered a separate 2D layer.

Here is a source-code example:


V · E

This example code shows how to create a 2D array texture.

GLuint texture = 0;
 
GLsizei width = 2;
GLsizei height = 2;
GLsizei layerCount = 2;
GLsizei mipLevelCount = 1;
 
//Read you texels here. In the current example, we have 2*2*2 = 8 texels, with each texel being 4 GLubytes.
GLubyte texels[32] = 
{
     //Texels for first image.
     0,   0,   0,   255,
     255, 0,   0,   255,
     0,   255, 0,   255,
     0,   0,   255, 255,
     //Texels for second image.
     255, 255, 255, 255,
     255, 255,   0, 255,
     0,   255, 255, 255,
     255, 0,   255, 255,
};
 
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D_ARRAY,texture);
//Allocate the storage.
glTexStorage3D(GL_TEXTURE_2D_ARRAY, mipLevelCount, GL_RGBA8, width, height, layerCount);
//Upload pixel data.
//The first 0 refers to the mipmap level (level 0, since there's only 1)
//The following 2 zeroes refers to the x and y offsets in case you only want to specify a subrectangle.
//The final 0 refers to the layer index offset (we start from index 0 and have 2 levels).
//Altogether you can specify a 3D box subset of the overall texture, but only one mip level at a time.
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, width, height, layerCount, GL_RGBA, GL_UNSIGNED_BYTE, texels);
 
//Always set reasonable texture parameters
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);

Note that, unlike for 3D Textures, each mipmap uses the same number of layers. So if you're allocating 3 mipmaps of a 2D array texture, it would look like this:

glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, format, width, height, num_layers, ...);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, format, width/2, height/2, num_layers, ...);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, format, width/4, height/4, num_layers, ...);

Access in shaders

Texture arrays have separate sampler types: sampler1DArray​ and sampler2DArray​. When accessing them within a shader, you use one extra texture coordinate. So sampler1DArray​ would use a 2D texture coordinate, while sampler2DArray​ would use a 3D texture coordinate.

The last coordinate is the layer number to access. For floating-point texture coordinates (when not using texture functions like texelFetch​), the floating-point layer is rounded then clamped to compute the integer layer index by the following function:

actual_layer = max(0, min(d​ - 1, floor(layer​ + 0.5)) )

Here, d​ is the number of layers in the texture, and layer​ is the floating-point layer from the texture coordinate. For example, to sample at s = 0.4, t = 0.6, for layer 2, use vec3(0.4, 0.6, 2).

Legacy Note: Array textures cannot be used with fixed-function OpenGL's texturing systems. You must use shaders to access them.

Cubemap arrays

Cubemap textures can be arrayed, if OpenGL 4.0 or ARB_texture_cube_map_array is available. In a cubemap array texture, each array image is conceptually a cubemap. However, all OpenGL APIs that act on cubemap array textures treat them as being a special case of 2D array textures. Therefore, the number of layers is really 6 * the number of actual cubemaps in the array. It is only within a shader where the layer index provided is the actual cubemap index in the array.

Limitations

Array texture sizes are normally limited to the usual GL_MAX_TEXTURE_SIZE limitation. However, the dimension that represents the number of array levels is limited by GL_MAX_ARRAY_TEXTURE_LAYERS, which is generally much smaller. OpenGL 4.5 requires that the limit be at least 2048, while OpenGL 3.3 requires it be at least 256.