Godot: texelFetch() not behaving properly

Created on 28 Aug 2019  路  7Comments  路  Source: godotengine/godot

Godot version:
3.1.1 stable

OS/device including version:
Ubuntu 18.04.3 LTS

Issue description:
I was using the texelFetch method from GLSL for a shader when I suddenly noticed that the fetched pixels' colors were not identical to the original ones from the texture. Testing with a simple LUT image, most of the colors were being fetched darker than they really were (below are 2 images for comparison).

After some struggle, I noticed that the same shader is working as expected in both Windows and Mac. It might have something to do with Linux drivers or even updates, since it was working some days ago.

Screenshot from 2019-08-28 00-16-27
Original Image

Screenshot from 2019-08-28 00-24-58
TexelFetched Image

Steps to reproduce:

  • Open the reproduction project below and run the main scene
  • Toggle the 'TexelFetchImage' node's visible property to true/false. It should be equal to the "OriginalImage" node's colors.

    • Windows/Mac: Both images are equal

    • Linux: the 'TexelFetchImage' node renders a darker image

Minimal reproduction project:
repro_texelfetch.zip

bug rendering

Most helpful comment

Still happening

Workaround functions for GLSL:

float srgb_to_linear(float srgb) {
    if(srgb <= 0.0031308) {
        return srgb * 12.92;
    } else {
        return pow(srgb, 1.0 / 2.4) * 1.055 - 0.055;
    }
}

vec3 vsrgb_to_linear(vec3 srgb) {
    return vec3(srgb_to_linear(srgb.r), srgb_to_linear(srgb.g), srgb_to_linear(srgb.b));
}

All 7 comments

I think this may be expected behaviour. texelfetch() is supposed to be used for accessing textures as if they are general purpose buffers, so there should be no SRGB conversion. However, when using texture() it is assumed that you are accessing the texture as an image so SRGB conversion is applied.

_edit:_ I am able to reproduce the difference on my Windows computer.

_editedit:_ Looks like this may be an OpenGL bug after all. Apparently texelfetch() doesn't do proper SRGB conversion on sRGB framebuffers. I can't find anything about it documented, but I have found some discussion that seems to hint in that direction.

I can confirm since @thiagoamendola is my coworker and I tested his project on both my computers. With Linux the texture is darker, with AMD or Nvidia graphics. Tested on Windows with AMD and it doesn't show the issue.

I tried to reproduce this issue with a Ubuntu 18.04 LTS Live USB and the issue is not present there!聽It might have something to do with Mesa implementation of OpenGL.

ubuntu18043
_My current Ubuntu 18.04.3 with darker texture_

ubuntu1804liveusb
_Ubuntu 18.04 LTS Live USB with normal texture_

Do you know any forum/issue tracker where I can report this? Maybe Ubuntu's one?

@thiagoamendola maybe you can report on Mesa itself: https://www.mesa3d.org/bugs.html

Still happening

Workaround functions for GLSL:

float srgb_to_linear(float srgb) {
    if(srgb <= 0.0031308) {
        return srgb * 12.92;
    } else {
        return pow(srgb, 1.0 / 2.4) * 1.055 - 0.055;
    }
}

vec3 vsrgb_to_linear(vec3 srgb) {
    return vec3(srgb_to_linear(srgb.r), srgb_to_linear(srgb.g), srgb_to_linear(srgb.b));
}

I have this problem too in Godot 3.2.1, Windows 10 64 bits,
OpenGL ES 3.0 Renderer: GeForce GTX 1060 6GB/PCIe/SSE2.

texelFetch results are darker, even on textures that were created procedurally.
In the case of imported textures, changing import options has no effect.

I'm not sure if I can use a workaround here because the texture I'm sampling has very precise values in it (indexes from 0 to 255), so I can't afford any approximation.

Was this page helpful?
0 / 5 - 0 ratings