Godot Version
4.4
Question
I have a gray (128, 128, 128) uniform source_color. Texture or just color picker, doesn’t matter. Everything says that this is a (0.5, 0.5, 0.5) color.
Raw values of color says it is.
Simple gd_script:
“var image = texture.get_image()
var color = image.get_pixel(0, 0)
print(color)”
says it is.
But in shader when i do “vec3 image_color = texture(image_texture, UV).rgb” and check values it says ~0.22. And if i do it backwards and create 0.5 color it gives me (188, 188, 188) color.
How can i get accurate colors? What am i doing wrong?
What do you mean by “check values”? I don’t think you can print directly to the console from a shader.
1 Like
a simple check shader would be something like
shader_type spatial;
uniform float Value : hint_range(0.0, 1.0);
uniform vec4 color : source_color;
void fragment() {
vec3 albedo_color = color.rgb;
if (albedo_color .x>=Value ) ALBEDO = albedo_color ;
}
and you set the color to whatever you want and then set the Value. When you see color change it means that you’ve found it. And if you set Value to 0.5 you need color at least 188
I set the color
uniform to a (128, 128, 128, 255) color, and it changes after 0.5. I put an image with the same gray color as a uniform sampler2D
and compared it to Value
and it still changed at 0.5. Where are you getting the 0.22 number from?
As you can see color set to (0.49), so sphere should become green at Value 0.5, but it is 0.215 and it is already green. And it’s not an >/< mistake, at Value 0.21 it’s red
I have your setup replicated and it works as expected. I think something else is the issue.
Did similar check, and got same unexpected behavior. Was able to fix it by changing variable “Value” to vec4 (color).
Code (tested in Godot 3.6):
shader_type spatial;
uniform vec4 Value : hint_color;
uniform vec4 color : hint_color;
void fragment() {
vec3 albedo_color = color.rgb;
ALBEDO = vec3(1.0, 0.0, 0.0);
if (albedo_color.x <= Value.x) ALBEDO = vec3(0.0, 1.0, 0.0);
}
After some experiments, I found out that the value a shader receives can vary significantly depending on various factors. I encountered different values when using the built-in color picker, a PNG texture created in Paint.NET, a PNG created in Blender via baking, a PNG from Blender via compositing, and an Open EXR from Blender compositing.
I didn’t figure out the exact cause of the issue, but I found enough solutions to address it, so I’ll leave them here for future generations.
If all you have is a PNG image and you can’t obtain anything else, you can convert values from sRGB to linear by using pow(color_value, 1.0/2.2)
for a single float value or pow(vecX_color, vecX(1.0/2.2))
for an entire vector. However, the values will not be entirely accurate.
Therefore, if you need an image that contains accurate data, use the Open EXR format instead of PNG.
If you are baking it in Blender, first bake it as usual to a non-color image texture. Then, open the Compositor tab, create an Image node and a Viewer node, and connect them. After that, open the Image Editor tab, select the Viewer Node image, and save it as an .exr file with the codec set to “none.”
1 Like