Gamma correction on transparent objects

Hi !

Last time I asked a question on this forum, I left with the understanding that:
-r.gammaFactor = 2.2 and r.outputEncoding = THREE.sRGBEncoding is now all you need to apply gamma correction on sRGB color space;
AND
-using an effect composer with some passes (such as FXAA) will ignore the previous fact, which means you need to do the gamma correction in a custom shader pass.

But recently in my project, I had to remove the effect composer and rely on the “native” gamma correction to do what my shader was doing. And everything looked correct, except for anything that had transparency in the scene.
I could reproduce what happens in a codepen, and though the difference here is quite minimal, it makes me wonder: how is the shader function LinearTosRGB doing a different job than the native gamma correction?

Here are the codepen:
With effect composer: https://codepen.io/Kromahtique/pen/BaoQbYM
With native gamma correction: https://codepen.io/Kromahtique/pen/YzypgpE

Hope I’m not being too off the point. The whole subject was completely new to me a month ago.
Thank you,

Kromah

1 Like

So I had actually opened a similar topic some days prior to you: Gamma Correction differences when object is transparent - Questions - three.js forum (threejs.org)

I got a vague answer from Mugen87 that there’s a problem with the library so I’m not sure there a good answer here.

There is a whole bunch of issues in your scene - in particular you are using a total of three different versions of three.js. Probably should avoid that - use skypack instead:

import * as THREE from "https://cdn.skypack.dev/three";

However, once I’ve tidied everything up it seems like the issue does persist. The right hand scene (with postprocessing) is brighter and the effect becomes more obvious the more transparent the material is.

@Mugen87 do you know what’s going on here? There’s no cube camera involved like in CubeCamera washes out the colors · Issue #18942

The scene is just a cube with a MeshBasicMaterial, black background, no lights.

Left, no postprocessing:
Codepen

material.transparent = true;
material.opacity = 0.25;

texture.encoding = sRGBEncoding;
renderer.outputEncoding = sRGBEncoding;

Right, with post.
Codepen

material.transparent = true;
material.opacity = 0.25;

texture.encoding = sRGBEncoding;
renderer.outputEncoding = LinearEncoding;

effectComposer.addPass(new RenderPass(scene, camera));
effectComposer.addPass(new ShaderPass(GammaCorrectionShader));

Now when I change only material.transparent = false in both scenes, they appear to match - I didn’t use an image differ or anything but they appear identical.

2 Likes

I’m afraid I have link to an unrelated issue. This rendering issue seems to be cause by something different.

Yes, it seems the glitch is only noticeably visible with transparent objects. And it seems only when applying a sRGB gamma correction pass. If I remove it and render both fiddles in linear space, there seems to be no issue.

Unfortunately, I could not figure out yet why the gamma correction pass behaves differently compared to the inline color space converison.

2 Likes

I want to bump this issue, not being able to use transparent shaders with post processing is pretty rough.

1 Like
2 Likes