SHADER: applying pixel color from image to a mesh
Asked Answered
G

7

0

I need help with a shader. I have a mesh that is a plane. it is composed of 10x10 grid of squares. I have a picture that is 10x10 pixels of varying colors. I want each square to have the color of each pixel, but there is a lot of distortion, how do I get rid of the distortion as this very small texture is applied to my mesh?

let me explain:

Basically, I cannot seem to get the right color using texture();
for instance, I tried using ALBEDO = texture( MY_TEXTURE, vec(0,0) );
this should set the entire mesh to the color at pixel 0,0 (top left) of the image. that pixel is red, but I am getting a pink color applied all across the mesh instead. On my texture image, the pixel next to top right is white and I think it is affecting the color.
why isn't texture( MY_TEXTURE, vec(0,0) ); giving me the red I want? how can I get the exact pixel, at 0,0 of my image applied across my texture?

the code bellow is the whole shader I am using.

`shader_type spatial;

uniform sampler2D t_albedo : source_color;

void fragment() {
vec4 albedo_tex = texture(t_albedo, vec2(0,0 );
ALBEDO = albedo_tex.rgb;
}
`

Goodloe answered 16/3 at 9:16 Comment(0)
B
0

Goodloe Disable texture compression in import settings for the texture.

Boswell answered 16/3 at 11:27 Comment(0)
G
0

Boswell i set the import to "lossless" and disabled compression and played with other settings to get something decent.
also, in my shader, i selected the center of the pixel

this all seems to help a lot... but its not enough. some colors are still off...

`
shader_type spatial;

uniform sampler2D t_albedo : source_color;

void fragment() {
ivec2 tSize = textureSize(t_albedo, 1);
//get color value for mapX and mapY positions
float mapX = 1.0/float(4textureSize(t_albedo, 1).x);
float mapY = 1.0/float(4
textureSize(t_albedo, 1).y);
vec2 mapPos = mapPos = vec2(mapX+2.0mapXfloor( UV.x * float(tSize.x)2.0 ), mapY+2.0mapYfloor( UV.y * float(tSize.y)2.0 ) );

//get the color
vec4 albedo_tex = texture(t_albedo,mapPos);

}
`

here is a picture of the result. the initial image and the image on the mesh. notice the color is a bit off??
the red and blue are not same and also above the red we see some red in the black a bit...

Goodloe answered 16/3 at 14:18 Comment(0)
B
0

Goodloe You're probably not sampling pixel centers. For start, try to map the texture directly using only plain UVs and see how it looks and. You may also want to disable linear filtering for the texture.

Note that the final color will be affected by illumination so try adding unshaded flag to shader's render mode.

Boswell answered 16/3 at 18:13 Comment(0)
G
0

Boswell filter_nearest helped a LOT
but im running into another issue. I want to get the exact RGB value at a certain pixel and its not working. Ive re-written a more simpler shader to demonstrate the issue:

`shader_type spatial;
render_mode unshaded;

uniform sampler2D t1_albedo : source_color,repeat_enable, filter_nearest;
void fragment() {
//
vec2 pos = vec2 (4.5/14.0, 3.5/15.0);
vec4 albedo_tex = texture(t1_albedo,pos);
ALBEDO = vec3 (0.0,0.0,0.0);
if( albedo_tex.r >= 0.6)
ALBEDO = vec3 (1.0,1.0,0.0);
}`

here I have a simple shader that applies a black color everywhere.
the image is 14x15 pixel size, with black everywhere and a red pixel at x=4,y=3
I am sampling this texture at vec2 (4.5/14.0, 3.5/15.0); which should give me my red pixel. (4.5, 3.5) the 0.5 to ensure at center of the pixel

my issue is that the red pixel is in fact 204/255 red or 80% red color.
when I put if( albedo_tex.r == 0.8) to show the red I see nothing.
if I put if( albedo_tex.r >= 0.7) still nothing.
only if( albedo_tex.r >= 0.6) then I get the red color show up on my mesh.
but I want this to be more precise. I want to actually read acurately the pixel color data at the position.
I want if( albedo_tex.r == 0.8) to pick up the pixel color of 0.8 red and actually work!

how can I do this? how can I read the color of a texture at position X,Y accurately using a shader?
I could also settle for something like an array of floats or even ints as a variable in the shader.
basically, I want to map colors on a mash. different colors on each triangle depending on a list of values.

my meshes will have hundred of "squares" on them and I want to be able to set/read different colors for each face basically. and get the actual color. not aproximately, but the actual color for that face I want. the data would be saved on an array, or texture or whatever and could be changed later.

Goodloe answered 20/3 at 21:57 Comment(0)
B
0

Goodloe how can I do this? how can I read the color of a texture at position X,Y accurately using a shader?

Use texelFetch() instead of texture()

You may also want to play with other texture import settings, disable mipmaps etc.

Boswell answered 21/3 at 8:3 Comment(0)
G
0

Boswell already tried that and didnt work.

shader_type spatial;
render_mode unshaded;

uniform sampler2D t1_albedo : source_color,repeat_enable;
void fragment() {
ivec2 cell = ivec2( 3, 3 );
float ink_color = texelFetch(t1_albedo, cell, 0).r;
ALBEDO = vec3 (0.0,0.0,0.5);
if( ink_color >= 0.6 )
ALBEDO = vec3 (1.0,0.0,0.0);
}

I also played around with import settings. could get anything to work. here is the texture I am using with red pixel at 3,3

Goodloe answered 21/3 at 8:12 Comment(0)
Q
0

Goodloe for correct color don't use source_color, use hint roughness instead, it will read the texture as linear. Also disable mipmaps and set it to nearest.

Quiet answered 21/3 at 11:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.