Why the color palette change from v0.150.1 to v0.152.2

I just upgraded three.js from 0.150.1 → 0.152.2 and I notice a significant color shift in the rendering:

version 0.150.1

version 0.152.2

Is there some new setting I need to configure?



The latest color management pinned post will likely point you in the correct direction for this…

1 Like


renderer.outputColorSpace  = THREE.LinearSRGBColorSpace;

I’m still unable to use the new default color management and still get the bright ‘plastic-toy’ colours I used to achieve in the past. So, setting the outputColorSpace is the only way I know so far.


I have to say, I read the pinned post and found it completely confusing. It is vague on what specifically I must to to change the way I set color to upgrade to the new linear color model. I understand the idea for a linear color model. That is not the issue. What - specifically - must I change? I currently do no setting of anything regarding color.

I want to move to the new model. But that post confuses far more then it explains.

1 Like

same here. they expect me to learn new things and I just dont wanna. Im going to wait for other people to figure it out and then eli5 or just put examples up that I can copy-paste from :pensive:

1 Like

If you’re not setting anything regarding color today, then the sub-section under “I’m still using renderer.outputEncoding = LinearEncoding (previous default)” explains what you need to change. The rest is background.

1 Like

Here is what is confusing. I am now trying to live the linear color life.

  1. I have set the following:
THREE.ColorManagement.enabled = true
renderer.outputColorSpace = THREE.SRGBColorSpace

I see in the documentation the follow:
Ensure that any THREE.ShaderMaterial instances include output color space encoding and tone-mapping, after setting gl_FragColor

How do I actually do this? For example I have this use of a shader material:
const stickMaterial = new THREE.MeshPhongMaterial({ color: appleCrayonColorThreeJS('aluminum') })

Note my method appleCrayonColorThreeJS('aluminum') internally creates a THREE.Color instance which I convert to SRB via: color.convertLinearToSRGB()

My colors are still screwed up. What have I missed.


That doesn’t appear to be a THREE.ShaderMaterial. For THREE.MeshXMaterial you don’t need to worry about GLSL fragments and gl_FragColor.

Note my method appleCrayonColorThreeJS('aluminum') internally creates a THREE.Color instance which I convert to SRB via: color.convertLinearToSRGB()

If the method initializes the color with a CSS or hexadecimal color, then three.js is already converting it from sRGB to linear. I don’t think there is any reason to be converting it in the opposite direction here.

There is some piece of information you are leaving out. I took a closer look at my code. All my color setting goes through this function:

const appleCrayonColorThreeJS = name => {
    return new THREE.Color(appleCrayonColorHexValue(name));

Where appleCrayonColorHexValue(blueberry) converts a string to a hex number that is handed to the color constructor.

According to what you say, I should not have to change anything. But that is not true. The colors are still off. What am I missing? Sigh, this is so maddening …

1 Like

I found the issue. I had to go through more of my color setting functions and add:
color.convertSRGBToLinear() to all the functions that create THREE.Color(r, g, b).

We’re good :+1:t5:

there’s no big secret, or maybe there is. but basically, every project you start from now on is going to look better, more realistic, with more depth and dynamic range, less banding, fewer blown out highlights and blacks. everything old is doomed and will look dumb when brought into the managed color space. that’s how i would explain to a 5yo.

made a small thread about it once, though now that three is doing it ootb there isn’t much to be done:

1 Like

I think the issue has to do with how you transition devs to the new model. My sense is that the documentation does an excellent job of selling the benefits of the transition but a rather poor job - easily fixed with simple, clear, granular examples - with how to get there.

1 Like

I certainly intended for the instructions in the post above to be concrete. The problem is that we don’t know how your application is built – there are many ways you could have been doing things originally, so the same steps will not work for all users. In particular, the solution you found…

color.setRGB( r, g, b ).convertSRGBToLinear()

… will NOT work for everyone reading this thread, because it assumes that your colors were originally sRGB. I’ll try to make the post more clear, but I can’t recommend the code above to everyone, for that reason.

Hmmm. Here is the scenario that led me - solely by experimentation - to arrive at the above:
color.setRGB( r, g, b ).convertSRGBToLinear() approach.

I have some color ramps I use in the molecular visualization app discussed in this post. Nowhere is there and specification of them being in sRGB color space. They are just lists of rgb triples in a file somewhere. They looked wrong using the new linear color model until I made the assumption they were in sRGB and applied the above conversion.

I think a lot of people will be in the same boat as me. They have some rgb triples that look color shifted when rendered in the linear model and will have no idea what to do about it.

This is the scenario you need to create documentation and examples for.

I’ve extended the relevant section of the post with the text below:

three.js now recognizes CSS and hex colors as sRGB. If you’re working with other color syntax, without conversions, you may now need to tell three.js when the values are sRGB.

material.color.setRGB( r, g, b, THREE.SRGBColorSpace );
material.color.setHSL( h, s, l, THREE.SRGBColorSpace );

These sRGB inputs are converted automatically to the working color space, Linear-sRGB, required for lighting and other operations

This is equivalent to using .convertSRGBToLinear().


Very cool. Please note, I’m being a bit picky here because of the overall awesomeness of three.js. I totally understand that moving devs to a linear model is a beast of a challenge. Cheers :+1:t5:

1 Like