Open Wierdox opened 2 weeks ago
Indeed, using an sRBG -> Linear conversion function on the input value seems to have fixed my perceived problem. And as I understand it now, I can also use source_color
to convert sampler2D
uniforms; which I had no clue, I thought it was just for the inspector hint to use a color wheel for vec3/4
.
This part of the godot docs makes the conversion importance more clear I think, Docs/ShadingLanguage/Uniforms. It also says that if hdr_2d
is enabled in settings, then the 2D shaders no longer use sRGB as default anymore. And yep, enabling that causes the canvas_item
shader to look like the spatial
one before the 'fix'.
So it seems very intentional then, I just had no clue this was something to worry about. At any rate, now I have to figure out if I want to enable hdr_2d
or not for consistency.
Tested versions
v4.3.stable.official [77dcf97d8], v4.0.stable.official [92bee43ad], v3.5.2.stable.official [170ba337a]
System information
Godot v4.2.2.stable - Windows 10.0.19045 - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 1660 SUPER (NVIDIA; 32.0.15.5612) - AMD Ryzen 5 5600G with Radeon Graphics (12 Threads)
Issue description
I was trying to translate
canvas_item
shaders tospatial
and vice versa, in curiosity for how their performance would differ. Some were fine, but others just seemed to have different coloration and I was confused. Then I tested a basic linear gradient, and it seems thatspatial
isn't linear for some reason?This is the case in both Forward+ and Mobile renderers, but in Compatibility it looks fine!
Here are the identical fragment shaders for both
spatial
andcanvas_item
:Spatial Code
```GLSL shader_type spatial; render_mode blend_mix, unshaded; void vertex() { POSITION = vec4(VERTEX, 1.0); } void fragment() { ALBEDO = vec3(1.0 - SCREEN_UV.x, 0.0, 0.0); //ALBEDO = vec3(1.0 - UV.x, 0.0, 0.0); // The same as above. } ``` *`spatial` shader uses `vertex()` to act as fullscreen, but the bug happens regardless.CanvasItem Code
```GLSL shader_type canvas_item; render_mode blend_mix, unshaded; void fragment() { COLOR.rgb = vec3(1.0 - SCREEN_UV.x, 0.0, 0.0); //COLOR.rgb = vec3(1.0 - UV.x, 0.0, 0.0); // The same as above. } ```Interestingly enough, in Godot 3.5 it's the same thing; GLES3 has the same issue and GLES2 doesn't, even though Godot 4 uses GLES3 for Compatibility(afaik). I have tried many combos of
render_mode
s, but it doesn't seem to fix the problem.This seems like a bug to me, but I wouldn't be surprised if this is intended and I just don't get it.
Steps to reproduce
Open the repro and run
main.tscn
, bug is only apparent when not using Compatibility/GLES2 renderer.Minimal reproduction project (MRP)
ShaderBugRepro.zip, 4.x
ShaderBugRepro3.zip, 3.x