RGB Artifacts Appearing When Khronos toneMapping enabled

Hi everyone,

I’m encountering an issue when adjusting the scene.imageProcessingConfiguration.exposure value and toneMapping is enabled.

  • When setting scene.imageProcessingConfiguration.exposure = 1;, everything renders fine.
  • When setting scene.imageProcessingConfiguration.exposure = 0.8;, green artifacts appear on the surface.

I don’t know what could be causing this—it came from nowhere :))
Thanks

tldr: This issue happens only on some PCs, while on others, everything works fine
This is how it looks on my pc

I remember I had the same thing but with blue color.

I got 404 on the textures:

But i can see the green dots still…Investigating

cc @sebavan to check as I think he did the Khronos tone mapping.

I spotted nothing wrong at first glance (and be patient Seb is on vacation this week :))

Updated pg, …sorry, I was sabotaged from the inside :))
Yes, no hurry

ok the glsl shader relevant code is:

result.rgb *= exposureLinear;
result.rgb = PBRNeutralToneMapping(result.rgb);
result.rgb = toGammaSpace(result.rgb);
result.rgb = saturate(result.rgb);

To fix it:

result.rgb *= exposureLinear;
result.rgb = saturate(result.rgb); <<<-----
result.rgb = PBRNeutralToneMapping(result.rgb);
result.rgb = toGammaSpace(result.rgb);
result.rgb = saturate(result.rgb);

@Evgeni_Popov / @sebavan thoughts on that?

In my understanding, tone mapping is used to remapp the [0,+oo] input range to [0,1]. So, clamping the input range to [0,1] before doing tone mapping doesn’t look right to me.

[EDIT] It seems the output of PBRNeutralToneMapping can have negative r/g/b components. Adding result.rgb = max(result.rgb, vec3(0.)); after the call gets rid of the green pixels.

oh so maybe then we simply need to saturate before the toGammaSpace?

Looking at the source code of `` from Khronos, it looks like the output should be in the [0,1] range, so we shouldn’t have to saturate the color.

After closer inspection, it seems we have floating-point precision problems:

vec4 applyImageProcessing(vec4 result) {
    result.rgb *= 0.8; // exposureLinear
    // INSERT HERE
    result.rgb = PBRNeutralToneMapping(result.rgb);
    result.rgb = toGammaSpace(result.rgb);
    result.rgb = saturate(result.rgb);
    return result;
}

Adding result.rgb = max(result.rgb, vec3(1e-7)) at the INSERT HERE line makes it work, but not result.rgb = max(result.rgb, vec3(0)). Strange thing is that using 1e-30 instead of 1e-7 makes it also work, whereas 1e-30 can’t be represented with a 32 bits float, so I would expect it to be replaced with 0 (but maybe it’s replaced with the smallest value greater than 0 that can be represented with a 32 bits float)…

Another strange thing is that if I replace 0.8 with exposureLinear (exposureLinear is set to 0.8), it does work with the result.rgb = max(result.rgb, vec3(0)) fix, no need for the 1e-7 value!

Also, some values of exposureLinear (like 0.5) don’t produce green pixels, they don’t need the fix.

So, it looks like floating point operation errors. It could also be specific to some GPUs. @MarianG said it only occurs on some PCs and not on others, maybe a NVidia specific problem (I have a Nvidia GPU)?

[…] New findings: there is no problem with the PG with WebGPU. So, I tested it by setting OpenGL as the ANGLE backend, and it works too (it also works with D3D9, but not with D3D11/D3D11On12)! So, it seems to be an ANGLE problem, perhaps specific to the Nvidia GPU. I’m going to create an issue in the Chromium repo.

3 Likes

Hi, yes, I can confirm it is working on AMD Ryzen 9 5900HX, but it is not working on integrated Intel CPU or dedicated NVIDIA GeForce RTX 4060

1 Like

I created the issue in the Chromium tracker:

https://issues.chromium.org/issues/396060194

1 Like

Again? Well hopefully they will fix it soon :slight_smile:

1 Like