Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Global shader uniform color not equal to regular uniform color. #70927

Open
OlivierVanHoutte opened this issue Jan 4, 2023 · 6 comments
Open

Comments

@OlivierVanHoutte
Copy link

Godot version

4.0.beta10

System information

Windows 10 Vulkan

Issue description

image
The shader global color (top left) is the same hex code as the shader uniform (bottom right). But If i create an unshaded sphere, and show the colors next to each other, the shader global color is slightly lighter than the shader uniform color.

image

I thought maybe it's because of my shader code, so I reduced it to as simple as possible.

image
image

Steps to reproduce

Create an empty project.
Add a new shader global color.

Create a new shader material.
Set rendermode to unshaded.
Set the ALBEDO to the shader global color

Create an exact replica of this shader, but set the albedo to a regular shader uniform color.

Make sure both colors have the exacts same hex code.

Minimal reproduction project

test2.zip

@clayjohn
Copy link
Member

clayjohn commented Jan 4, 2023

This may end up being something that is a documented limitation. Right now, you hint to Godot what the source of the uniform is - in this case the source is a color. Godot then decides whether to convert it from sRGB to linear depending on the destination. Spatial shaders convert to linear as lighting happens in linear space. CanvasItem shaders don't convert to linear as 2D rendering happens in sRGB space.

Global uniforms can be used in either, but they map onto the same uniform internally, so they have to be either sRGB or linear in both Spatial shaders and CanvasItem shaders.

My preference would be for global uniforms to always convert to linear when source_color is used (i.e. matching the behaviour in spatial shaders). That way users still have the power to use either linear or sRGB.

@OlivierVanHoutte
Copy link
Author

So a temp fix would be gamma correction by raising your color to pow 2.2 like below.
I like your proposal of making it linear when source_color is used.

image

@clayjohn
Copy link
Member

clayjohn commented Jan 4, 2023

The more exact formula is

ALBEDO = mix(pow((col.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), col.rgb * (1.0 / 12.92), lessThan(col.rgb, vec3(0.04045)));

@huwpascoe
Copy link
Contributor

This may be fixed now #101642

@clayjohn
Copy link
Member

clayjohn commented Feb 5, 2025

This may be fixed now #101642

I don't think so. The global buffer is uploaded in a different function.

See

_fill_std140_variant_ubo_value(datatype, 0, p_value, (uint8_t *)&global_shader_uniforms.buffer_values[pos], true); //instances always use linear color in this renderer

@akien-mga
Copy link
Member

I tested and the MRP still shows the issue in current master (80096e9).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants