Updating from r140 to r167 and color managament

I am porting a three.js script from r140 to r167. I am totaly newbie with three.js and shader.

Before moving directly to r167 I digged into changes and moved before to r151, then to r152 and finally r167. I moved to r151 because I saw the update to Color management. I succesfully moved to r151 without issues. All looks the same and code was working. Then I update to r152 I find an issue: the object has changed its appearance slightly. Moving to r167 does not change the issue. All is working the same as r152 with this difference in the appearance. So I narrowed the problem down to the update r151 → r152.
The problem is about a fragment shader.

In the original r140 script

  • I am using the default encoding, console.log(this.renderer.outputEncoding) print 3000, so LinearEncoding.
  • I am loading texture without changes to encondig so if I print the encoding I get 3000, so still LinearEncoding.
  • I am defined color like that const color = new THREE.Color('#282021') and, if I get it right, it is treated as if it is already linear and not automatically converted to linear space.

In r152 (and r167) I am doing like that

  • I am using the default colorSpace, now sRGB. If I print it I get srgb.
  • I am default loading texture and if I print the color space is NoColoSpace. I am using textures as normal map, so I think it is correct to leave it as is.
  • I am define color like before with r140.
  • I add to the fragment shader #include <colorspace_fragment> (<encodings_fragment>` in r152).
  • I also add in the ShaderMaterial forceSinglePass: false because before false was default but now true is the default value.

Am I doing it right or not? Am I missing something?

In an attempt to get the same result from the shader I also did some experiments.

With r140 I changed the renderer encoding to THREE.sRGBEncoding, I changed the texture encoding to null instead of LinearEncoding because I am using them for a normal map. I leave the color the same. I got the same result of the original script with r140. Is it possible?

EDIT 1: some more context and details.
Small foreword: I am fan of globe, so in my spare time I am looking for globe I like it, port to the latest three.js version and then port to react-three-fiber. Why? I am just learning three.js and react-three-fiber in this way.

See screenshot to check the difference I am talking about.


If I disable color management THREE.ColorManagement.enabled = false;, stay with the default ColorSpace (srgb-linear), load the texture as before and remove #include <encodings_fragment> from the fragment shader in r152, I get the same result of r140. I do not know if this can help.
If I also change the renderer ColorSpace (this.renderer.outputColorSpace = THREE.LinearSRGBColorSpace;) to srgb-linear nothing change.

Maybe this may help ?

Hello @mjurczyk, thanks for the quickly answer.

I tried that but I am getting in r152 the same result of #include <encodings_fragment>. Could be possible?

Ok, I find something.

In r152 If use the default ColorSpace with color management but define color like that

const color = new THREE.Color();
color.setHex(0x282021, THREE.LinearSRGBColorSpace);

and remove #include <encodings_fragment> I get the same look.

So If I get it correctly, the issue could be in r140 I am define a color with a linear color space and three.js does not convert it but used like that. In r167 the color is define as srgb and then automatically converted to srgb-linear.

What do you think? Sounds right?