|Core in version||4.5|
|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|
A 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.
Anisotropic filtering is an advanced filtering technique that takes more than one sample point and blends them together. Exactly how this is done is implementation-dependent, but the control is a specific value: the maximum number of samples that can be taken of the texture. More samples may slow down performance, but increase image quality. Then again, it may not, depending on the angle you're looking at the surface. Implementations only take extra samples when needed.
To use anisotropic filtering, set the GL_TEXTURE_MAX_ANISOTROPY_EXT 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 a 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 added to the bias specified in one of the texture accessing functions in GLSL), which is used to select the image. 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.
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 with glTexParameteri. 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.
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. This does not apply to 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 defines 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 with GL_BORDER_COLOR.
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, 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.
Note that the border color is a 4-component color, so you must use the v version of the function to provide all four components.