How to access the automatic mipmap level in the texture shader of a GLSL fragment?

How to determine what level of mipmap was used when sampling the texture in the shader of the GLSL fragment?

I understand that I can manually set a specific level of texture mipmap using the textureLod(...) method:

 uniform sampler2D myTexture; void main() { float mipmapLevel = 1; vec2 textureCoord = vec2(0.5, 0.5); gl_FragColor = textureLod(myTexture, textureCoord, mipmapLevel); } 

Or I could automatically select the mipmap level using texture(...) , for example

 uniform sampler2D myTexture; void main() { vec2 textureCoord = vec2(0.5, 0.5); gl_FragColor = texture(myTexture, textureCoord); } 

I prefer the latter, because I trust the judgment of the driver regarding the corresponding mipmap level more than myself.

But I would like to know what level of mipmap was used in the automatic sampling process to help me rationally try neighboring pixels. Is there a way in GLSL to access information about what level of mipmap was used to automatically select a texture?

+6
source share
2 answers

Below are three different approaches to this problem, depending on which OpenGL features are available to you:

  • As noted in the comments of Andon M. Coleman , the solution in OpenGL version 4.00 and higher is simple; just use the textureQueryLod function:

     #version 400 uniform sampler2D myTexture; in vec2 textureCoord; // in normalized units out vec4 fragColor; void main() { float mipmapLevel = textureQueryLod(myTexture, textureCoord).x; fragColor = textureLod(myTexture, textureCoord, mipmapLevel); } 
  • In earlier versions of OpenGL (2.0+?), You could download the extension with a similar effect. This approach worked for my case. NOTE : the method call is differently queryTextureLod in the extension compared to the built-in ( queryTextureLod vs queryTextureLod ).

     #version 330 #extension GL_ARB_texture_query_lod : enable uniform sampler2D myTexture; in vec2 textureCoord; // in normalized units out vec4 fragColor; void main() { float mipmapLevel = 3; // default in case extension is unavailable... #ifdef GL_ARB_texture_query_lod mipmapLevel = textureQueryLOD(myTexture, textureCoord).x; // NOTE CAPITALIZATION #endif fragColor = textureLod(myTexture, textureCoord, mipmapLevel); } 
  • If loading the extension does not work, you can evaluate the automatic level of detail using the approach suggested by genpfault :

     #version 330 uniform sampler2D myTexture; in vec2 textureCoord; // in normalized units out vec4 fragColor; // Does not take into account GL_TEXTURE_MIN_LOD/GL_TEXTURE_MAX_LOD/GL_TEXTURE_LOD_BIAS, // nor implementation-specific flexibility allowed by OpenGL spec float mip_map_level(in vec2 texture_coordinate) // in texel units { vec2 dx_vtc = dFdx(texture_coordinate); vec2 dy_vtc = dFdy(texture_coordinate); float delta_max_sqr = max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc)); float mml = 0.5 * log2(delta_max_sqr); return max( 0, mml ); // Thanks @Nims } void main() { // convert normalized texture coordinates to texel units before calling mip_map_level float mipmapLevel = mip_map_level(textureCoord * textureSize(myTexture, 0)); fragColor = textureLod(myTexture, textureCoord, mipmapLevel); } 

In any case, for my specific application, I simply calculated the mipmap level on the host side and passed it to the shader, because the automatic level of detail was not quite what I needed.

+17
source

From here :

take a look at the OpenGL 4.2 spec , chapter 3.9.11, equation 3.21. The mip map level is calculated based on the lengths of the derived vectors:

 float mip_map_level(in vec2 texture_coordinate) { vec2 dx_vtc = dFdx(texture_coordinate); vec2 dy_vtc = dFdy(texture_coordinate); float delta_max_sqr = max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc)); return 0.5 * log2(delta_max_sqr); } 
+7
source

Source: https://habr.com/ru/post/971290/


All Articles