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)
print3000
, soLinearEncoding
. - I am loading texture without changes to encondig so if I print the encoding I get
3000
, so stillLinearEncoding
. - 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 beforefalse
was default but nowtrue
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.