How do GL_TEXTURE_MIN_LOD, GL_TEXTURE_MAX_LOD and LOD_BIAS work?
To check it visually, i have created 6*6 texture with mipmapping and for values > 0.5 for MIN_LOD I get a 3*3 texture irrespective of values for MAX_LOD. If I change LOD_BIAS it does not affect my o/p. I am not able to figure out how it works exactly.
Can anyone explain it by stating an example?
Edit:
I am creating mipmap levels manually so that I can observe which level it is picking up. Here is my code:
glTexImage2D(target, 0, GL_RGBA,9 ,9, 0, GL_RGBA, GL_BYTE,subpix);
glTexImage2D(target, 1, GL_RGBA,4 ,4, 0, GL_RGBA, GL_BYTE,&subpix[4]);
glTexImage2D(target, 2, GL_RGBA,2 ,2, 0, GL_RGBA, GL_BYTE,&subpix[10]);
glTexImage2D(target, 3, GL_RGBA,1 ,1, 0, GL_RGBA, GL_BYTE,&subpix[18]);
glSamplerParameterf(sampler,GL_TEXTURE_MIN_LOD,0.862);
glSamplerParameterf(sampler,GL_TEXTURE_MAX_LOD,0.99);
glSamplerParameterf(sampler,GL_TEXTURE_LOD_BIAS,0.0);
In this case I am expecting it would take 2nd mipmap level which is of 2*2 but It chooses 1st mipmap level of 4*4. When I set min lod < 0.5, It takes 0th level of 9*9. And it this happens irrespective of the value set to max lod.
First some references:
TEXTURE_MIN_LOD Sets the minimum level-of-detail parameter. This floating-point value limits the selection of highest resolution mipmap (lowest mipmap level). The initial value is -1000.
TEXTURE_LOD_BIAS specifies a fixed bias value that is to be added to the level-of-detail parameter for the texture before texture sampling. The specified value is added to the shader-supplied bias value (if any) and subsequently clamped into the implementation-defined range - bias max bias max , where bias max is the value of the implementation defined constant GL_MAX_TEXTURE_LOD_BIAS. The initial value is 0.0
So if you are surprised by the mipmap selection, I suggest following steps (not necessarily in order):
Create mipmaps by hand so that they are visually distinctive from each other
Verify your mipmaps are supplied correctly.
Verify that your LOD_BIAS setting doesn't just put all of the values outside the range, making the sampler effectively always use the maximum or minimum LOD.
Searching around this, I've found textureQueryLod . It might also be of some interest to you to aid debugging.
Related
What value does the LOD parameter take for texturelod? The spec I found doesn't mention it at all. Is it a percentage or an index value with a percent. If the later is the case, is there a way to get the number of mipmaps the texture has so that I would be able to use a percentage?
The LOD parameter specifies the mipmap level, rounded to the nearest whole number. Remember that OpenGL specifies mipmap levels, such that 0 is the largest, with increasing numbers going smaller.
However, the LOD specified here will always be relative to the current GL_TEXTURE_BASE_LEVEL of the texture. So if you use textureLod(..., 0), and the base level is set to mipmap 2, then you will select from mipmap level 2. You also cannot select mipmaps outside of the GL_TEXTURE_MAX_LEVEL range; the system will automatically clamp the specified parameter appropriately.
What value does the LOD parameter take for texturelod? The spec I found doesn't mention it at all. Is it a percentage or an index value with a percent. If the later is the case, is there a way to get the number of mipmaps the texture has so that I would be able to use a percentage?
The LOD parameter specifies the mipmap level, rounded to the nearest whole number. Remember that OpenGL specifies mipmap levels, such that 0 is the largest, with increasing numbers going smaller.
However, the LOD specified here will always be relative to the current GL_TEXTURE_BASE_LEVEL of the texture. So if you use textureLod(..., 0), and the base level is set to mipmap 2, then you will select from mipmap level 2. You also cannot select mipmaps outside of the GL_TEXTURE_MAX_LEVEL range; the system will automatically clamp the specified parameter appropriately.
The idea
I need to create a 2D texture to be fed with resonably precise float values (I mean at least as precise as a glsl mediump float). I want to store in it each pixel's distance from the camera. I don't want the GL Zbuffer distance to near plane, only my own lovely custom data :>
The problem/What I've tried
By using a standard texture as color attachment, I don't get enough precision. Or maybe I missed something ?
By using a depth attachment texture as GL_DEPTH_COMPONENT32 I am getting the clamped near plane distance - rubbish.
So it seems I am stuck at not using a depth attachment even tho they seem to eventually hold more precision. So is there a way to have mediump float precision for standard textures ?
I find it strange OpenGL doesn't have a generic container for arbitrary data. I mean with custom bit-depth. Or maybe I missed something again!
You can use floating point textures instead of a RGBA texture with 8 bit per pixel. However support of these depends on the devices you want to support, especially older mobile devices have a lack of support for these formats.
Example for GL_RGBA16F( Not tested ):
glTexImage2D(GL_TEXTURE_2D, mipmap, GL_RGBA16F, mipmapWidth, mipmapHeight, GL_RGBA, GL_HALF_FLOAT, null);
Now you can store the data in your fragment-shader manually. However clamping still occurs depending on you MVP. Also you need to pass the data to the fragment shader.
There are also 32bit formats.
There are a number of options for texture formats that give you more than 8-bit component precision.
If your values are in a pre-defined range, meaning that you can easily map your values into the [0.0, 1.0] interval, normalized 16-bit formats are your best option. For a single component texture, the format would be GL_R16. You can allocate a texture of this format using:
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, 512, 512, 0, GL_RED, GL_UNSIGNED_SHORT, NULL);
There are matching formats for 2, 3, and 4 components (GL_RG16, GL_RGB16, GL_RGBA16).
If you need a larger range of values that is not easily constrained, float textures become more attractive. The corresponding calls for 1 component textures are:
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, 512, 512, 0, GL_RED, GL_HALF_FLOAT, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 512, 512, 0, GL_RED, GL_FLOAT, NULL);
Again, there are matching formats for 2, 3, and 4 components.
The advantage of float textures is that, just based on the nature of float values encoded with a mantissa and exponent, they can cover a wide range. This comes at the price of less precision. For example, GL_R16F gives you 11 bits of precision, while GL_R16 gives you a full 16 bits. Of course GL_R32F gives you plenty of precision (24 bits) as well as a wide range, but it uses twice the amount of storage.
You would probably have an easier time accomplishing this in GLSL as opposed to the C API. However, any custom depth buffer will be consistently, considerably slower than the one provided by OpenGL. Don't expect it to operate in real-time.
If your aim is to have access to the raw distance of any fragment from the camera, remember that depth buffer values are z/w, where z is the distance from the near plane and w is the distance from the camera. So, it is possible to extract quickly with an acceptable amount of precision. However, you are still faced with your original problem: fragments between the camera and the near plane will not be in the depth buffer.
I am trying to understand how to mipmap texture arrays .From what I understand,texture array is 3 dimensional structure where each texture 2D has a depth param in glTexStorage3D which sets a given texture to some position in the array.But how do I specify number of mipmaps per texture?Can I specify different number of mipmaps per texture?
Is this the right way to do it?
glTexStorage3D(GL_TEXTURE_2D_ARRAY,10,GL_RGBA8,width,height,numTextures);
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_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);
for(int i =0 ; i <numTextures;++i){
glTexSubImage3D(GL_TEXTURE_2D_ARRAY,/*What goes here???*/, 0, 0, 0, width, height, /*What goes here?*/, GL_RGBA, GL_UNSIGNED_BYTE, data);
}
glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
I don't know what to pass into second and 8 parameters of glTexSubImage3D. Should the second param be a number of mipmaps and the 8th - depth of the current texture?
The second param is the mipmap level of the texture you want to load. In your case, since you want to rely on GL to generate the mipmaps, it's 0.
The eighth parameter is the depth. In the case of arrays, that means the number of layers you're passing. For you, it's 1, since you're passing a single layer per iteration of the loop.
The 5th parameter, however, is the offset in depth of where you want to store the data you're passing in. In your case, it's the layer you're loading i.
If I create two textures as
1. srcID
2. destID
Both of type GL_TEXTURE_CUBE_MAP
glTexStorage2D(GL_TEXTURE_CUBE_MAP, 6, GL_RGBA8, 32, 32);
Now "srcID" is filled with all the texture data required.
So what parameters be used in order to copy entire "srcID" to "destID".
Tried many combinations but it always gave error.
This is untested, and purely from studying the man page and spec document:
glCopyImageSubData(srcID, GL_TEXTURE_CUBE_MAP, 0, 0, 0, 0,
destID, GL_TEXTURE_CUBE_MAP, 0, 0, 0, 0,
32, 32, 6);
The least obvious part is how to specify that you want to copy all cubemap faces. The spec says about the target arguments:
All non-proxy texture targets are accepted, with the exception of TEXTURE_BUFFER and the cubemap face selectors described in table 8.19.
This tells me that GL_TEXTURE_CUBE_MAP must be used for those arguments, not specific faces.
Then on how to specify that you want to copy all 6 cubemap faces, this part is relevant (highlight added by me):
Slices of a one-dimensional array, two-dimensional array, cube map array, or three dimensional texture, or faces of a cube map texture are all compatible provided they share a compatible internal format, and multiple slices or faces may be copied between these objects with a single call by specifying the starting slice with srcZ and dstZ, and the number of slices to be copied with srcDepth. Cubemap textures always have six faces which are selected by a zero-based face index, according to the order speciļ¬ed in table 8.19.
So copying all 6 faces should work with using 0 for srcZ and dstZ, and 6 for srcDepth.