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?
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.
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?
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
.
Okay but the background color still changes. Is that the intended behavior?
composer.renderTarget1.texture.encoding = THREE.sRGBEncoding;
composer.renderTarget2.texture.encoding = THREE.sRGBEncoding;
Performance-wise I’m not sure about this if you have many passes, but instead of adding a pass, I just changed the last line of my CopyShader from
" gl_FragColor = opacity * texel;"
to
" gl_FragColor = LinearTosRGB( opacity * texel );"