Detailed explanation of openGL &GLSL texture() function

Posted by gullit on Thu, 20 Jan 2022 19:26:28 +0100

preface

Generally, when adding textures to 3D projects, you often see functions with texture operations. First, look at a piece of chip shader program: in the chip shader

#version 450 core

out vec4 FragColor;

in vec2 TexCoords;

uniform sampler2D depthMap;
uniform float near_plane;
uniform float far_plane;

// required when using a perspective projection matrix
float LinearizeDepth(float depth)
{
	float z = depth * 2.0f - 1.0f; //Back to NDC 
	return (2.0f * near_plane * far_plane) / (far_plane + near_plane - z * (far_plane - near_plane));
}

void main()
{
	float depthValue = texture(depthMap, TexCoords).r;
//	FragColor = vec4(vec3(LinearizeDepth(depthValue) / near_plane), 1.0f);   // perspective
	FragColor = vec4(vec3(depthValue), 1.0f);  // orthographic
}

. cpp file code

//plane VAO VBO
	unsigned int planeVBO;
	glGenVertexArrays(1, &planeVAO);
	glGenBuffers(1, &planeVBO);
	glBindVertexArray(planeVAO);
	glBindBuffer(GL_ARRAY_BUFFER, planeVBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(planeVertices), &planeVertices, GL_STATIC_DRAW);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
	glEnableVertexAttribArray(2);
	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
	glEnableVertexAttribArray(0);

	// load textures
	// -------------
	unsigned int woodTexture = loadTexture(FileSystem::getPath("resources/textures/wood.png").c_str());

	// configure depth map FBO
	// -----------------------
	const unsigned int SHADOW_WIDTH = 1024, SHADOW_HEIGHT = 1024;
	unsigned int depthMapFBO;
	glGenFramebuffers(1, &depthMapFBO);
	//glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);        // Why not bind framebuffer objects
	// create depth texture
	unsigned int depthMap;
	glGenTextures(1, &depthMap);
	glBindTexture(GL_TEXTURE_2D, depthMap);
	/******* Function: specify a two-dimensional texture image, and the texture maps a part of the specified texture image to each graphic primitive whose texture is active.
		/******* The texture is active when the current clip shader or vertex shader uses the built-in texture lookup function
		/******* Parameter 1:target: Specifies the target texture of the active texture cell. Must be GL_TEXTURE_2D,
		/******* GL_TEXTURE_CUBE_MAP_POSITIVE_X,GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
		/******* GL_TEXTURE_CUBE_MAP_POSITIVE_Y,GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
		/******* GL_TEXTURE_CUBE_MAP_POSITIVE_Z,Or GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
		/******* Parameter 2:level: Specifies the detail level number. Level 0 is the basic image level. Level n is the nth thumbnail reduced image.
		/******* Parameter 3:internalformat specifies the internal format of the texture. Must be one of the following symbolic constants: GL_ALPHA,GL_LUMINANCE,GL_LUMINANCE_ALPHA,GL_RGB,GL_RGBA
		/******* Here we use Base Internal Format: GL_DEPTH_COMPONENT,GL_DEPTH_STENCIL,GL_RED,GL_RG,GL_RGB,GL_RGBA,
		/******* Because we only care about depth map, we define texture format as GL_DEPTH_COMPONENT
		/******* Parameter 4:width: depth map resolution, specifies the width of the texture image. All implementations support 2D texture images with a width of at least 64 texels and cube mapped texture images with a width of at least 16 texels.
		/******* Parameter 5:height: Specifies the height of the texture image. All implementations support 2D texture images at least 64 pixels high and cube map texture images at least 16 pixels high.
		/******* Parameter 6:border specifies the width of the border. Must be 0.
		/******* Parameter 7:format specifies the format of the texture data. Must match internalformat. The following symbol values are accepted: GL_ALPHA,GL_RGB,GL_RGBA,GL_LUMINANCE, and GL_LUMINANCE_ALPHA
		/******* Parameter 8: Specifies the data type of texture data. The following symbol values are accepted: GL_UNSIGNED_BYTE,GL_UNSIGNED_SHORT_5_6_5,GL_UNSIGNED_SHORT_4_4_4_4, and GL_ UNSIGNED_ SHORT_ 5_ 5_ 5_ one
		/******* Parameter 9:data specifies a pointer to image data in memory
		*******/
	glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	// attach depth texture as FBO's depth buffer
	glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);

problem

When I see the functions related to texture operation, I always don't know its meaning and can't understand it. Now let's explain in detail: the following paragraph is the article quoted as the great God ""

Solemnly declare:
Author: psklf
Source: https://www.cnblogs.com/psklf/p/5762308.html
Reprint is welcome, but this statement must be retained without the consent of the author; The original connection must be given in the article; Otherwise, legal responsibility must be investigated!

Sampler (GLSL)

The sampler is usually defined in the Fragment shader, which is a variable of uniform type, that is, this variable is consistent when dealing with different slices. A sampler corresponds to a texture, and the type also corresponds. For example, the sampler of sampler2D ^ corresponds to GL_ TEXTURE_ Texture objects of type 2D. Sampler is a variable, but it has no value, or a special type. It is meaningless to discuss its value, as long as it is clear that it corresponds to the same texture. Where the sampler variable is used in the shader is the texture function. This is a lookup function (I don't know how to translate, my understanding is that this is a search / query function to find the corresponding color information in the texture data with the given texture coordinates), and the color information is displayed on each slice. For example, for a triangle, we just need to pass three texture coordinates to the vertex shader, and then the slice shader will generate texture coordinate interpolation for each pixel, and get the color value of each pixel according to the texture coordinates.

Texture sampling mechanism

Texture Wrapping

Texture coordinates usually range from (0, 0) to (1, 1). What happens if we set texture coordinates outside the range? The default behavior of OpenGL is to repeat this texture image (we simply ignore the integer part of the floating-point texture coordinates), but OpenGL provides more options:

  • GL_REPEAT: the default behavior of the texture. Repeat the texture image.
  • GL_MIRRORED_REPEAT: and GL_REPEAT is the same, except that duplicate images are placed in mirror images.
  • GL_CLAMP_TO_EDGE: the texture coordinates will be between 0 and 1. The excess part repeats the edge of the texture coordinate, that is, the edge is stretched.
  • GL_CLAMP_TO_BORDER: the part beyond is the color of the edge specified by the user.

When generating texture objects, you need to set a series of parameters with glTexParameter(), which is the parameter and the following parameters of Texture Filtering.

Texture Filtering

magnification/minification

The size of the image data constituting the texture is often different from the shape to be pasted. Two cases:

  1. Mapping: the texture image is small and the mapping area is large. You need to enlarge the texture
  2. minification: conversely, if the texture image is large and the mapping area is small, the reduced texture will be displayed

The specific strategies for zooming in and out are as follows:

  • GL_NEAREST: directly select the color of the nearest pixel. When zooming in: because multiple slices will take values on the same texture pixel, the resulting image has large granularity and sawtooth.
  • GL_LINEAR: perform linear interpolation calculation according to the color values of adjacent four pixels to obtain the final color. When zooming in: no aliasing occurs and the display is smoother.

In minification, the above two methods are not ideal. In any case, many picture details will be lost. OpenGL uses Mipmap to solve this problem.

Mipmap

It is a series of textures. The texture behind each is half of the previous one. This series of textures are generated by OpenGL. The image quality is optimized during generation to make it have more details. This series of textures are generated in advance. When the program runs, it only needs to pick out the texture application of appropriate size, rather than processing the image size at run time, which will improve the efficiency.

When OpenGL rendering, two different levels of mipmap will produce an unrealistic rigid boundary. Like normal texture filtering, near and LINEAR filtering can also be used between two different mipmap levels. Specify the filtering method between different mipmap levels. You can use the following four options instead of the original filtering method:

  • GL_NEAREST_MIPMAP_NEAREST: receive the nearest mipmap to match the pixel size, and use the nearest interpolation for texture sampling.
  • GL_LINEAR_MIPMAP_NEAREST: receives the most recent mipmap level and samples using linear interpolation.
  • GL_NEAREST_MIPMAP_LINEAR: linear interpolation between two mipmaps, sampling by nearest neighbor interpolation.
  • GL_LINEAR_MIPMAP_LINEAR: perform linear interpolation on two adjacent mipmaps and sample through linear interpolation.

To sum up, both NEAREST and LINEAR modes can be set for registration and minification; During minification, you can also set the mipmap method, which is more effective. For the implementation of specific algorithms, you can refer to <OpenGL ES specification> 8.13-8.14 of.

Sampler object

A texture object includes two parts of attributes, one part is the specific image information, and the other part is the setting of texture sampling, that is, the different methods mentioned above. These two parts are usually set together when generating texture, but the contents of the latter part can be taken out separately and encapsulated into an object, that is, @ sampler object

Use the GenSamplers() function to create a new sampler object, then bind it with BindSampler(), bind sampler and texture objects, and then call glSamplerParameterf() to set the specific parameters of sampler.

The relationship among texture object, sampler object and program object is shown in the figure below:

In addition, take a look at the position of texture in the whole rendering process of openGL

Official document address

Original text and Translation

Name

texture — retrieves texels from a texture

Take out the texture pixel value on the texture coordinate point in the two-dimensional texture

Declaration

gvec4 texture(gsampler2D sampler,
vec2 P,
[float bias]);

gvec4 texture(gsampler3D sampler,
vec3 P,
[float bias]);

gvec4 texture(gsamplerCube sampler,
vec3 P,
[float bias]);

float texture(sampler2DShadow sampler,
vec3 P,
[float bias]);

float texture(samplerCubeShadow sampler,
vec4 P,
[float bias]);

gvec4 texture(gsampler2DArray sampler,
vec3 P,
[float bias]);

float texture(sampler2DArrayShadow sampler,
vec4 P);

gvec4 texture(gsamplerCubeArray sampler,
vec4 P,
[float bias]);

float texture(samplerCubeArrayShadow sampler,
vec4 P,
float compare);

Parameters

sampler

Specifies the sampler to which the texture from which texels will be retrieved is bound.

Specifies the sampler to which the texture is bound

P

Specifies the texture coordinates at which texture will be sampled.

Specifies the texture coordinates for texture sampling

bias

Specifies an optional bias to be applied during level-of-detail computation.

Specifies the optional deviation applied during detail level calculation. (can be omitted)

compare

When present, specifies the reference for shadow comparisons.

Specifies the reference for shadow comparison when present

Description

texture samples texels from the texture bound to sampler at texture coordinate P. An optional bias, specified in bias is included in the level-of-detail computation that is used to choose mipmap(s) from which to sample.

For shadow forms, when compare is present, it is used as DsubDsub and the array layer is specified in P.w. When compare is not present, the last component of P is used as DsubDsub and the array layer is specified in the second to last component of P.

For non-shadow variants, the array layer comes from the last component of P.

At the texture coordinate p, the texture texture element bound from the texture to the sampler. An optional deviation, specified in the deviation, is included in the detail level calculation to select the mipmap(s) from which to sample.  

For the Shadow form, when compare exists, it is used as DsubDsub, and the array layer is specified in P.w. When compare does not exist, the last component of P is used as DsubDsub, and the array layer is specified in the penultimate component of P.  

For non shadow variables, the array layer comes from the last component of P.  

Version Support

OpenGL ES Shading Language Version
Function Name1.003.003.103.20
texture-
texture (gSamplerCubeArray, samplerCubeArrayShadow)---

See Also

texelFetchtexelFetchOffsettextureGradtextureGradOffsettextureLodtextureLodOffsettextureOffsettextureProjtextureProjGradtextureProjGradOffsettextureProjLodtextureProjLodOffsettextureProjOffsettextureSize

Copyright

Copyright © 2011-2015 Khronos Group. This material may be distributed subject to the terms and conditions set forth in the Open Publication License, v 1.0, 8 June 1999. http://opencontent.org/openpub/.

Topics: OpenGL opengles