How to use usampler2D?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By nxfs

I’d like to pass a texture of unsigned integers to a custom shader to perform a switch statement based on an id between 0 and 255.

uniform usampler2D lookup_texture;

void fragment() {
	ivec2 texture_coord = ivec2(UV);
	
	uint id = texelFetch(lookup_texture, texture_coord, 0);
    ...

How can I create the lookup texture from a GDNative script?

I have tried to use a R8 texture but it doesn’t work.

lookupTexture.create(size.x, size.y, false, Image.FORMAT_RGB8)
...
lookupImage.set_pixel(63, 63, lookup_value(7))	
...
lookupTexture.create_from_image(lookupImage)
self.material_override.set_shader_param("terrain_lookup", lookupTexture)

func lookup_value(lookup_id):
	return Color(255 + lookup_id << 24)

What works with the above is to use a sampler2D, but I need to perform ugly transformations in the shader, and I am assuming this is wasteful because unnecesary extra data is transferred to the shader:

uniform sampler2D lookup_texture;

void fragment() {
	ivec2 texture_coord = ivec2(UV);
	
	int image_id = int(texelFetch(terrain_lookup, texture_coord, 0).r * 256.0);
        ...

My question is what is the proper way to pass data that can be processed using an usampler2D (or how would you go about passing a 8 bit textures to the shader and extract the 8 bit value as short int in the shade)?

Have you ever found an answer to this? I’d be interested in it. I’m also trying to use a usampler2D (to deal with 16bit integer values); I pass it a FORMAT_RG8 (two 8bit channels) texture and texelFetch yields huge numbers way beyond the 8bit range for every component that is not 0…

archeron | 2020-05-17 15:40

Replying here to say that I, too, am having trouble with this same issue. texelFetch on my FORMAT_R8 texture passed through a usampler3D seems to return values close to 2^31.

Syntaxxor | 2021-10-18 01:40