Linear filtering for Texture3D not working, while nearest filtering works

Hello, I’m a little bit desperate while trying to get the linear filtering work for GL_TEXTURE_3D.
I use this for volume rendering.

I searched in the community for a while, but did not found anything that suits my problem.

While everything works fine for NEAREST filtering, GL_LINEAR, GL_NEAREST_MIPMAP_LINEAR or GL_LINEAR_MIPMAP_LINEAR instead are not working.

The “texture()” function in my fragment shader for a “usampler3D” returns zero.

The 3D data is 256 x 256 x 256 in size, filled up with UInt8 values.

I would be glad if someone could tell me what I’m doing wrong.

Here is the code I use to setup the GL_TEXTURE_3D:

NVIDIA GeForce GT 720/PCIe/SSE2
OpenGL 4.6.0 NVIDIA 471.41
Available Extensions: GL_AMD_multi_draw_indirect GL_AMD_seamless_cubemap_per_texture GL_ARB_arrays_of_arrays GL_ARB_base_instance GL_ARB_bindless_texture GL_ARB_blend_func_extended GL_ARB_buffer_storage GL_ARB_clear_buffer_object GL_ARB_clear_texture GL_ARB_clip_control GL_ARB_color_buffer_float GL_ARB_compatibility GL_ARB_compressed_texture_pixel_storage GL_ARB_conservative_depth GL_ARB_compute_shader GL_ARB_compute_variable_group_size GL_ARB_conditional_render_inverted GL_ARB_copy_buffer GL_ARB_copy_image GL_ARB_cull_distance GL_ARB_debug_output GL_ARB_depth_buffer_float GL_ARB_depth_clamp GL_ARB_depth_texture GL_ARB_derivative_control GL_ARB_direct_state_access GL_ARB_draw_buffers GL_ARB_draw_buffers_blend GL_ARB_draw_indirect GL_ARB_draw_elements_base_vertex GL_ARB_draw_instanced GL_ARB_enhanced_layouts GL_ARB_ES2_compatibility GL_ARB_ES3_compatibility GL_ARB_ES3_1_compatibility GL_ARB_ES3_2_compatibility GL_ARB_explicit_attrib_location GL_ARB_explicit_uniform_location GL_ARB_fragment_coord_conventions GL_ARB_fragment_layer_v

-------------------------------------------------------------------------------------------------------------------------------

var LTex : GLuint;
var LPrevTex : GLuint;

/// filled up somewhere else
var LBuffer : PByte;

glGetIntegerv(GL_TEXTURE_BINDING_3D, @LPrevTex);

glActiveTexture(GL_TEXTURE0);

glGenTextures(1, @LTex);
glBindTexture(GL_TEXTURE_3D, LTex);
try
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
  
  // 
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	
  glPushClientAttribDefaultEXT(GL_CLIENT_PIXEL_STORE_BIT);
  try
    // GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE for data = 256 x 256 x 256 of Byte (UInt8)
    glTexImage3D(GL_TEXTURE_3D, 0, GL_R8UI, 256, 256, 256, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, LBuffer);
  finally
    glPopClientAttrib();
  end;
  
  glGenerateMipmap(GL_TEXTURE_3D);
finally
  glBindTexture(GL_TEXTURE_3D, LPrevTex);
end;

You can’t use linear filtering with integer textures. The magnification filter must be GL_NEAREST, the minification filter must be GL_NEAREST or GL_NEAREST_MIPMAP_NEAREST. Otherwise, the texture is considered incomplete.

2 Likes

Thank you.
I was not aware of that fact.

For float textures linear filtering works?
I read I have to activate an extension in the shader? Or does it work out of the box?

Yes.

No extension is required. Floating-point textures behave like (signed or unsigned) normalised textures. Normalised values and floating-point values are both treated as approximations to real numbers; integers aren’t.

Interpolation isn’t supported for integers. Integer textures don’t support linear filtering, and blending is disabled if the fragment shader output is an integer value or the framebuffer attachment is an integer texture.

If you want to use filtering on the texture, it should probably be R8 (i.e. 8-bit unsigned normalised) rather than R8UI (8-bit unsigned integer).

Thanks for the explanation.
I really appreciate it. I’ll fix my code.