Texture in Fragment Shader is different from original Texture

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

Hi

I have a 256x256 Texture created in gdscript filled red.

dynImage.create(256,256,false,Image.FORMAT_RGBAF)  // I tried different formats
dynImage.fill(Color(1,0,0,1))

I now set one pixel to black

dynImage.lock()

for i in range(1): //I tested with bigger ranges, it gets darker
	for i2 in range(1):
		dynImage.set_pixel(i,i2,Color(0,0,0,1))
dynImage.unlock()

make a ImageTexture and “send” it to the shader

imageTexture.create_from_image(dynImage)
material.set_shader_param("myTexture",imageTexture);

in the shader I try to access this pixel.

shader_type canvas_item;

uniform sampler2D myTexture : hint_black;
void fragment(){
	 
	if(int(UV.x*100.0)%2==0)
		COLOR = texture(myTexture,vec2(0,0));
	else
		COLOR = texture(myTexture,vec2(0.1,0.1));

To test if it still has the color black I tried this:

if(texture(myTexture,vec2(0.1,0.1))==vec4(0,0,0,1))
	COLOR = vec4(0,1,0,1);
}

What I receive is this.
Output

If I change the range for i,i2 to 30 it is a black and get’s green by the test.

I tried to acess the pixel in the gd_script with get_pixel → still black as expected

Since I am more or less new to this stuff, I guess I missunderstand something.
My guesses would be, that there is some kind of image compression, I don’t know how to turn off.

What I want to do is to send raw image data to the shader and read the color pixel by pixel afterwards.

I am using Godot 3.1, if that is of importance.

Maybe someone can point out my mistake.

Thank you in advance

I’m glad I found this web site, I couldn’t find any knowledge on this matter prior to. Also, operate a site and if you are ever interested in doing some visitor writing for me if possible feel free to let me know, I’m always looking for people to check out my web site.
geometry dash

sloperun3az | 2019-04-19 12:20

:bust_in_silhouette: Reply From: Godotmus

I have done some shader stuff but I’m not sure about detais with Godot… what kind of settings there are etc.
Anyway, it looks like shader is doing bilinear sampling with the texture, if you take sample/color from vec2(0.1,0.1) it might sample also little bit neighbor pixel… usually if you want hard color borders then sampling must be set something like GL_NEAREST (or whatever is used in Godot) Or somehow texture is automaticly mip-mapped and thus blurred…

Thank you, you are right. It seems to be how I create the ImageTexture.
This works as I expect it.

imageTexture.create_from_image(dynImage,0)

Interesstingly
neither

imageTexture.create_from_image(dynImage,Texture.FLAG_FILTER)

or

imageTexture.create_from_image(dynImage,Texture.FLAG_MIPMAPS)

or

imageTexture.create_from_image(dynImage,Texture.FLAG_REPEAT)

alone or in combination, returns to the pervious “unwanted” effect, only all three

imageTexture.create_from_image(dynImage,Texture.FLAG_REPEAT|Texture.FLAG_MIPMAPS|Texture.FLAG_FILTER)

return to the “unwanted” result.
Maybe something interessting to investigate.

Still thank you, now I can go on to find out, if I can implement my idea.

Innorium | 2019-04-18 07:35

It is a little offtopic to the original post. But in addition I found out you can access the pixle in the shader with.

texelFetch(myTexture,ivec2(1,0),0)

opposit to someting like

texture(myTexture,vec2(1.0/256,0)

or

textureProj(myTexture,vec2(1.0,0),256)

If someone is likeminded then me, I hope it helps.

Innorium | 2019-04-18 13:01