Color space issue with Collada models in editor?

Good morning everybody,

I have a Collada model with colored Lambert materials imported fine in the three.js editor. The only issue is that the colors of the model in the three.js editor don’t quite match the original colors (i.e. the hex values set in the .dae file which I can preview correctly on my Mac with the built-in Preview app).

Any idea why these happens and how to fix it ?

You can find attached a screen shot of the model rendered with correct colors with the built-in macOS Preview app (color of triangular facade is brown) and a screen shot of the result of the import in the three.js editor (color of triangular facade is an ugly yellowish-brown).

Thank you in advance for the help!

Xavier


Anybody has an idea ?

Maybe @donmccurdy ? You wrote my bible in color management for three.js.

Or maybe @Mugen87 ? As you are the owner of the ColladaLoader.

Thank you guys for the help, because it looks like either I am missing something or this is a quite important bug, I think.

The problem is that the editor assumes a sRGB workflow (unlike the official Collada examples). However, ColladaLoader does not configure its textures to be in sRGB space. The more modern GLTFLoader does this differently.

I’m not sure how Collada treats color spaces though. When I remember correctly, the format does not specify color spaces and assumes everything to be in linear space.

Thank you for the reply. Indeed, the Collada standard doesn’t specify color spaces, unfortunately…

So now I get it for the editor, I have to convert my colors before feeding them in the color selector of the editor. (For whoever is interested, I used this online tool.)

But your answer doesn’t solve the issue with my web app. I asked the question about the editor as it was easy to reproduce it for anybody. But actually I asked the question because I got stuck on my web app with color conversions. I imagined the issue was related to color spaces, as the title of my post indicates, but I tried to convert the colors and still didn’t manage to achieve a correct color.

Your answer gave me confidence that my methodology and my understanding of color management in three.js was correct and that the issue was just a bug in my code. So I looked at it more in depth and identified my issue. I was traversing the children of the Collada loaded model and converting the color of all the children materials. But some materials were reused in the model I used and I was converting their color multiple times, resulting in very wrong colors (too dark or too bright).

I now keep track of the materials I already converted the color and apply the conversion only to the ones I didn’t already :

const alreadyConvertedMaterials: Material[] = [];
building.traverse((child) => {
  if (isObjectRenderable(child)) {
    if (Array.isArray(child.material)) {
      child.material.forEach((m) => {
        if (!alreadyConvertedMaterials.includes(m) && hasMaterialColor(m)) {
          m.color.convertSRGBToLinear();
          alreadyConvertedMaterials.push(m);
        }
      });
    } else if (!alreadyConvertedMaterials.includes(child.material) && hasMaterialColor(child.material)) {
      child.material.color.convertSRGBToLinear();
      alreadyConvertedMaterials.push(child.material);
    }
  }
});

Let me know if you see any optimisations in this code.

NB: isObjectRenderable is a typescript utility function to check if a child has a geometry and a material(s) and hasMaterialColor is a typescript utility function to check if a material has a color.

1 Like