glslvulkan

Is there supposed to be interpolation when using a usampler2D?


I'm sampling a R16_UINT image in the shader with a usampler2D. I do:

uvec4 upix_color = texture(usampler2D(utextures[nonuniformEXT(idx_of_height_map)], samplers[0]), result.uvs);

But it seems the values do not come back filtered/interpolated, as this image shows:

enter image description here

enter image description here

I know that an R16 grayscale image can also be R16_UNORM, in which case it's read as a normalised float, and I know that integers may be harder to interpolate, but integers in the range 0 to 65,535 should be able to be interpolated.


Solution

  • OpenGL

    In OpenGL, interpolation (linear filtering) is not supported for integer textures. In fact, trying to configure this would result in an incomplete texture. From the OpenGL 4.5 specification, Section 8.17:

    Using the preceding definitions, a texture is complete unless any of the following conditions hold true:

    • ...
    • The internal format of the texture is integer (see table 8.12) [...] and either the magnification filter is not NEAREST, or the minification filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST.
    • ...

    (Text reordered for clarity.)

    In other words, for integer textures, the filtering parameters must be set to nearest neighbor filtering.


    This is also expressed on the Khronos website in less techincal terms:

    Integer color formats [...] do not support linear filtering. As such, the GL_TEXTURE_MAG_FILTER sampling parameter must be GL_NEAREST, and GL_TEXTURE_MIN_FILTER must be either GL_NEAREST or GL_NEAREST_MIPMAP_NEAREST.

    Vulkan

    In Vulkan, an implementation may support interpolation (linear filtering) for integer textures, but it is not required to. From the Vulkan 1.4.310 specification, Section 48.3:

    Implementations must support at least the following set of features on the listed formats. For images, these features must be supported for every VkImageType [...].
    ...
    The following tables show which feature bits must be supported for each format.

    In the table that follows, it shows that VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT (i.e. support for linear filtering) is not supported for integer image formats, including VK_FORMAT_R16_UINT. In theory, you could use GetPhysicalDeviceFormatProperties to query whether interpolation is available on the implementation. However, I would expect this to (almost) never be the case, as floating point interpolation for textures is typically implemented in hardware, but integer interpolation isn't.