sRGB encoding as a postprocess pass

I found out that setting renderer.outputEncoding = THREE.sRGBEncoding doesn’t work when using postprocessing #18451. I’ve been told I need to do the encoding as a postprocess pass but I’m not sure how to do that. Can somebody point me in the right direction or give me some sample code I can use for reference?

Turns out they have a gamma correction shader in https://threejs.org/examples/js/shaders.
Create the pass like this
const gammaCorrectionPass = new THREE.ShaderPass(THREE.GammaCorrectionShader)
and add it as the final pass
composer.addPass(gammaCorrectionPass)
If you set renderer.gammaFactor = 2.2 it simulates sRGBEncoding or so I’ve been told

Is there anything else I need or is this enough?

The gamma correction pass fudges the colors a bit. Anybody know how to fix this?

Screenshot from 2020-01-22 17-16-40

Not really, it’s fairly close but not exactly the same. What we need is an sRGBPass I guess.

It’s not clear from your screenshot what you mean. How are they fudged?

The gradients are harsh. The same model without postprocessing looks much smoother up close.

fudging-outlined
Screenshot from 2020-01-22 17-47-39

Ah yeah, I couldn’t see that on my phone screen earlier, but it’s obvious now.

Can you try @Mugen87’s suggestion in this thread?

Effect Composer Gamma Output Difference

1 Like

That works. Was a merge request made for this?

The gamma correction pass makes the background color lighter. This doesn’t happen with renderer.outputEncoding = THREE.sRGBEncoding. Is anyone working on a sRGBEncoding pass? In the meantime is there a way to exclude the background and other objects from the gamma correction pass?

You’re right. The difference is pretty noticeable.

Composer with gamma correction pass: https://jsfiddle.net/kbgxhodn/
Renderer with sRGBEncoding: https://jsfiddle.net/n80zcu9a/

I think I’m going to have to give up on GammaCorrectionShader as a workaround.

So back to my original question. How do I mimic the result of https://jsfiddle.net/n80zcu9a/ when using EffectComposer to render the scene?

I don’t think the difference should be that noticeable. But in any case, you can just write your own sRGBCorrectionPass.

Use the gammaCorrectionPass as a template:

And you’ll find the LinearTosRGB function here:

You don’t need to redefine the function in the pass, since the pass has access to the function defined in the core. Simply replace LinearToGamma with LinearTosRGB in the GammaCorrectionPass.

1 Like

Okay but the background color still changes. Is that the intended behavior?

composer.renderTarget1.texture.encoding = THREE.sRGBEncoding;
composer.renderTarget2.texture.encoding = THREE.sRGBEncoding;