A simple example:
#version 450
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
vec4 SourceSize;
} global;
#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;
void main()
{
gl_Position = global.MVP * Position;
vTexCoord = TexCoord;
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 1) uniform usampler2D Source;
void main()
{
// 1. Calculate integer texture coordinates (to avoid floating-point precision errors)
ivec2 texCoord = ivec2(vTexCoord.xy * global.SourceSize.xy);
// 2. Sample the four independent RGBA channels
uvec4 rgbaUint = texelFetch(Source, texCoord, 0).rgba;
// 3. Convert integers in the range 0~255 to normalized floating-point numbers in the range 0.0~1.0
vec4 rgba = rgbaUint / 255.0;
FragColor = rgba;
}
Expected result: The image is output as is. However, the brightness of each RGB channel is abnormally high.

A simple example:
#version 450
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
vec4 SourceSize;
} global;
#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;
void main()
{
gl_Position = global.MVP * Position;
vTexCoord = TexCoord;
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 1) uniform usampler2D Source;
void main()
{
// 1. Calculate integer texture coordinates (to avoid floating-point precision errors)
ivec2 texCoord = ivec2(vTexCoord.xy * global.SourceSize.xy);
}
Expected result: The image is output as is. However, the brightness of each RGB channel is abnormally high.