Search code examples
c++glsltexturesvulkan

Sampling values in fragment shader from a R16_UINT-3D texture in Vulkan


I am using the texture tutorial from Sascha Willems and it works without any problems. Then I change the texture from a 2D texture to a 3D texture unsigned 16 bits.

I set the correct depth and then change these values:

VK_FORMAT_BC3_UNORM_BLOCK -> VK_FORMAT_R16_UINT
VK_IMAGE_TYPE_2D -> VK_IMAGE_TYPE_3D
and just one component ->   view.components = { VK_COMPONENT_SWIZZLE_R };

In the shader:

sampler2D -> sampler3D

But all the values I get from texture(volumeTexture, textPos).r are now zero. What I want to do is to upload a UINT16 image but sample it as float from the fragment shader.

If I open RenderDoc the texture looks good.

pastie.org/private/i7dqw7pm0snkbf40eyywg

This is what I did in opengl:

  const auto& glType           = GL_SHORT;
  const auto& glFormat         = GL_LUMINANCE;
  const auto& glInternalFormat = GL_LUMINANCE16F_ARB;
  const auto& glClampMode      = GL_CLAMP_TO_EDGE;

Solution

  • This is what I did in opengl:

    OpenGL's pixel transfer functionality is required to accept unpleasant or slow things. Vulkan's does not.

    What you did in OpenGL was force the driver to convert every pixel from a 16-bit unsigned, normalized fixed-point value to a 16-bit IEEE-754 floating-point value. Almost certainly, this conversion was done on the CPU.

    Vulkan doesn't have training wheels, and Vulkan drivers don't do your work for you. Vulkan has formats, and the specification states exactly what they mean. If your data does not match the format you eventually want to use, then its on you to do the conversion.