|Core in version||4.6|
|Core since version||3.3|
|Core ARB extension||ARB_sampler_objects|
It also has glBindSampler, which takes a texture unit index (on the half-open range [0, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS) ) and a sampler object. Unlike most other OpenGL objects however, you do not need to bind sampler objects to modify them. The functions to set state in them take sampler objects as parameters. You only bind a sampler object to a texture image unit when you wish to use it, not just to change it.
To set a parameter on a sampler object, use one of these functions below:
void glSamplerParameter[if]( GLuint sampler, GLenum pname, T param); void glSamplerParameter[if]v( GLuint sampler, GLenum pname, T *params ); void glSamplerParameterI[i ui]v( GLuint sampler, GLenum pname, T *params );
pname specifies the name of the parameter being set. param(s) is the value to set into that parameter. The valid pname parameters and params for them are defined below.
When a sampler object is bound to a texture image unit, the internal sampling parameters for a texture bound to the same image unit are all ignored. Instead, the sampling parameters are taken from this sampler object.
All of the following parameters can be used with the glTexParameter* set of functions. You could say that a texture object contains a sampler object, which you access through the texture interface.
Filtering is the process of accessing a particular sample from a texture. There are two cases for filtering: minification and magnification. Magnification means that the area of the fragment in texture space is smaller than a texel, and minification means that the area of the fragment in texture space is larger than a texel. Filtering for these two cases can be set independently.
The magnification filter is controlled by the GL_TEXTURE_MAG_FILTER texture parameter. This value can be GL_LINEAR or GL_NEAREST. If GL_NEAREST is used, then the implementation will select the texel nearest the texture coordinate; this is commonly called "point sampling". If GL_LINEAR is used, the implementation will perform a weighted linear blend between the nearest adjacent samples.
The minification filter is controlled by the GL_TEXTURE_MIN_FILTER texture parameter. To understand these values better, it is important to discuss what the particular options are.
When doing minification, you can choose to use mipmapping or not. Using mipmapping means selecting between multiple mipmaps based on the angle and size of the texture relative to the screen. Whether you use mipmapping or not, you can still select between linear blending of the particular layer or nearest. And if you do use mipmapping, you can choose to either select a single mipmap to sample from, or you can sample the two adjacent mipmaps and linearly blend the resulting values to get the final result.
The OpenGL minification settings for these are as follows:
|Param Setting||Linear within mip-level||Has mipmapping||Linear between mip-levels|
Filtering textures that use the sRGB colorspace may be sRGB correct or it may not. Linear interpolation in a non-linear colorspace like sRGB will not produce correct results. The OpenGL specification recommends, but does not require that implementations covert samples to linear RGB before filtering. They may do filtering in sRGB space, then convert to linear. Generally speaking, all GL 3.x+ hardware will do filtering correctly.
Note: On terminology. This discussion has refrained from using the common filtering terms "bilinear" and "trilinear." This is for a good reason; these terms are often misunderstood and do not carry over to all texture types.
Take the term "bilinear". This term is used because it refers to linear filtering in 2 axes: horizontally and vertically in a 2D texture. A monolinear would be filtering in one axis, and thus trilinear is filtering in 3 axes.
The problem is that what constitutes "bilinear" depends on the texture type. Or specifically, its dimensionality. Setting GL_TEXTURE_MAG_FILTER and MIN_FILTERs to GL_LINEAR will create monolinear filtering in a 1D texture, bilinear filtering in a 2D texture, and trilinear in a 3D texture. In all cases, it is simply doing a linear filter between the nearest samples; some texture types simply have more nearest samples than others.
Unfortunately, what most people think of as "trilinear" is not linear filtering of a 3D texture, but what in OpenGL terms is GL_LINEAR mag filter and GL_LINEAR_MIPMAP_LINEAR in the min filter in a 2D texture. That is, it is bilinear filtering of each appropriate mipmap level, and doing a third linear filter between the adjacent mipmap levels. Hence the term "trilinear".This is easily confused with what is just GL_LINEAR for 3D textures. That is why OpenGL and this discussion does not use these terms.
|Core in version||4.6|
|Core since version||4.6|
|Core ARB extension||ARB_texture_filter_anisotropic|
Anisotropic filtering is an advanced filtering technique that takes multiple samples, blending the results together. Exactly how this is done is implementation-dependent, but control over the feature is specific: the user provides a maximum number of samples that can be taken of the texture during any one texture fetch. Note that this is the "maximum" number of samples; a particular texture fetch may take fewer samples. Hardware generally attempts to determine the best number of samples to take, clamped to the user-provided maximum.
To use anisotropic filtering, set the GL_TEXTURE_MAX_ANISOTROPY_EXT sampling parameter. This parameter is floating-point, and can be set between 1.0f and an implementation-defined maximum anisotropy (queried with GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT). Any value greater than 1.0f counts as a use of anisotropic filtering.
Anisotropic filtering is not a replacement for mipmaps or mipmap filtering. For best results, combine anisotropic filtering with a GL_LINEAR_MIPMAP_LINEAR minification filter.
There is a pair of sampling parameters that affect the mipmap image selection: GL_TEXTURE_MAX_LOD and GL_TEXTURE_MIN_LOD (floating-point values). The way these work in mipmap selection is quite complicated; the specification goes into full detail about it. These selection clamping parameters will not cause sampling outside of the texture's mipmap range specified by GL_TEXTURE_BASE_LEVEL and GL_TEXTURE_MAX_LEVEL.
The mipmap image selection process can be adjusted coarsely by using the GL_TEXTURE_LOD_BIAS sampling parameter. This bias will be added to the mipmap LOD calculation, as well as the bias provided by one of the texture sampling functions in GLSL. This LOD calculation is used to select the mipmap level or pair of mipmap levels to sample from. A positive bias means that larger mipmaps will be selected even when the texture is viewed from farther away. This can cause visual aliasing, but in small quantities it can make textures a bit more sharp.
These selection clamping parameters will not cause sampling outside of the texture's mipmap range specified by GL_TEXTURE_BASE_LEVEL and GL_TEXTURE_MAX_LEVEL.
Depth textures (textures that have a depth component image format) can be sampled in one of two ways. They can be sampled as a normal texture, which simply retrieves the depth value (with filtering applied). This will return a vec4 containing a single floating-point value.
They can also be fetched in comparison mode. This means that sampling from the texture requires a value to compare to those pulled from the texture; this value is called the reference value. The result of the comparison depends on the comparison function set in the texture. If the function succeeds, the resulting value is 1.0f; if it fails, it is 0.0f. Swizzling can be used, but only the R component of the swizzled result will be returned. So it's not very useful.
When linear filtering is used, the actual returned value is implementation-defined. However, the value will be on the range [0, 1] and will be proportional to the number of neighboring texels that pass the comparison based on the single given value. In effect, it performs linear filtering on the results of fetching from the nearest texels in the texture. This is commonly called "Percentage Closer Filtering".
If the texture is a normalized integer depth format, then the reference value is clamped to [0, 1], to match the values from the texture. Otherwise, the value is not clamped.
Using this mode requires two special settings. First, the sampler used in GLSL must be a shadow sampler. Second, the texture used in that sampler must have activated depth comparison mode. Attempting to use a texture without comparison with a shadow sampler, or vice-versa, will result in an error upon rendering.
To set the texture to comparison mode, set the GL_TEXTURE_COMPARE_MODE texture parameter to GL_COMPARE_REF_TO_TEXTURE. The comparison function to use when comparing the reference to the texture is set with the GL_TEXTURE_COMPARE_FUNC texture parameter. Acceptable values are GL_NEVER (always fails), GL_ALWAYS (always succeeds), GL_LESS, GL_LEQUAL, GL_EQUAL, GL_NOT_EQUAL, GL_GEQUAL, and GL_GREATER. The comparison works as follows:
ref OPERATOR texture
Where ref is the reference value given to the texture lookup function by GLSL, and texture is the value fetched from the texture. So GL_LESS will be true if the reference value is strictly less than the value pulled from the texture.
Edge value sampling
Normalized texture coordinates are not limited to values between 0.0 and 1.0. They can be any floating-point number. When a texture coordinate is not within the [0, 1] range, a heuristic must be employed to decide what the color value will be.
Each dimension of a texture can have a different heuristic. These are set by setting the texture parameters GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T, and GL_TEXTURE_WRAP_R, where S, T, and R are the first 3 texture coordinates in order. The possible heuristics are:
- GL_REPEAT: the texture coordinate wraps around the texture. So a texture coordinate of -0.2 becomes the equivalent of 0.8.
- GL_MIRRORED_REPEAT: the texture coordinate wraps around like a mirror. -0.2 becomes 0.2, -1.2 becomes 0.8, etc.
- GL_CLAMP_TO_EDGE: the texture coordinate is clamped to the [0, 1] range.
- GL_CLAMP_TO_BORDER: the texture coordinate is clamped to the [0, 1] range, but the edge texels are blended with a constant border color.
- GL_MIRROR_CLAMP_TO_EDGE (requires OpenGL 4.4 or ARB_texture_mirror_clamp_to_edge): the texture coordinates are clamped to the [-1, 1] range, but the negative coordinates are mirrors of the positive. This effectively makes the texture twice as big through mirroring, but clamps to the edge beyond that.
This also applies to Rectangle Textures, except that the range at which they apply edge sampling is based on the texel width/height of the texture, not the normalized [0, 1] range. Sampling modes are irrelevant for Buffer Textures, as they must use the texelFetch sampling functions and thus cannot sample outside of the texel range of the texture.
The GL_CLAMP_TO_BORDER requires a color that edge texels are blended when texture coordinates fall outside of the valid area of the texture. When this this edge mode is used, a border color must be set by setting the GL_BORDER_COLOR parameter.
The border color can be provided in floating-point values, Normalized Integers, or non-normalized integers, using the various forms of glSamplerParameter/glTexParameter. Note that the border color is a 4-component color, so you must use the v version of the function, and you must provide all four components in a single call.
When using the fv function, the color will be stored as a float. When using iv, the color will be converted to a float via signed normalization. Since the components are GLint 32-bit integers, the range is from [-231, 231). When using the Ii or Iui forms, the color will be stored as signed or unsigned integers, as appropriate.
The border color will then be converted to a value appropriate for the Image Format of the texture when it is actually used.
Seamless cubemap fetching
As an OpenGL extension, seamless cubemap filtering can be manipulated on a per-texture or per-sampler object basis. Note that if you use the global version, it will still globally force seamless behavior on all cubemaps.
This is governed by a simple boolean sampler parameter, GL_TEXTURE_CUBE_MAP_SEAMLESS. Setting it to 0 turns it off for that texture/sampler; setting it to any other value causes accesses to the cubemap to be seamless.