clearColor post-processing with sRGBEncoding

Hello, I think I found a bug in the GammaCorrectionShader. In the example below the scene.outputEncoding is set to sRGBEncoding. In this case, I need the GammaCorrectionShader when using post-processing. It seems like the clear color is not accounted for in this case.

Here is a very basic example to reproduce this: goofy-mclaren-lpsb29 - CodeSandbox

I created two effect composer, one with GammaCorrection and one without.

Rendering without post-processing:

Rendering with post-processing and no Gamma Correction (incorrect rendering of sphere, correct clearColor):

Rendering with post-processing and Gamma Correction (correct rendering of sphere, incorrect clearColor):

Thank you in advance!

If you’re using the post-processing provided by three.js, then the renderer output encoding must be linear —

renderer.outputEncoding = THREE.LinearEncoding;

Note that this is different from a popular external postprocessing implementation, the postprocessing npm package, where there is no GammaCorrectionShader. There you specify renderer.outputEncoding = sRGBEncoding instead, it detects and uses that.

GammaCorrectionShader operates on all pixels on screen alike, and doesn’t know whether the input comes from clear color or something else. So you also need to specify the clear color in the right color space, and that choice depends on whether you’re using post-processing. It needs to be sRGB when writing to canvas, or typically Linear-sRGB when writing to a render target for post-processing. You can avoid needing to deal with that difference by enabling the option below, and it should then behave more like material colors:

THREE.ColorManagement.legacyMode = false;

Related:

1 Like

Thank you @donmccurdy for the thorough reply!

I’ll look into supporting the postprocessing npm package in our application as it seems quite powerful, but I’ll have to do some changes to allow that. It seems a bit unfortunate that three.js does not support this out of the box, when the sRGBEncoding is suggested elsewhere for the outputEncoding.