I cannot show as expected color after upgrade to r118 from r110

Hi,
I have update my project to threejs r118 from r110.
After update, I am struggling in color management.
Please see screenshot.
On r110:

On r118:

Here are some code for youtube model.


    self.glRenderer = new THREE.WebGLRenderer({alpha: true, antialias: true, preserveDrawingBuffer: true});
    self.glRenderer.setPixelRatio( window.devicePixelRatio );
    self.glRenderer.setSize(width, height);
    self.glRenderer.autoClear = false;
    self.glRenderer.shadowMap.enabled = true;
    self.glRenderer.shadowMap.type = THREE.PCFSoftShadowMap;
    self.glRenderer.outputEncoding = THREE.sRGBEncoding;
    self.glRenderer.physicallyCorrectLights = true;

.....
   var w = 10;
    var h = 10;

    var iconGeometry = new THREE.PlaneGeometry(w, h);
    var iconMaterial = new THREE.MeshBasicMaterial({ side: THREE.DoubleSide });
    
    if(!iconMaterial) {
        return callback(null);
    }
    iconMaterial.transparent = true;

    var iconMesh = new THREE.Mesh(iconGeometry, iconMaterial);

    iconMesh.name = 'icon';
    var iconURL = AREditor.path + '/editor/images/youtube.light.png';
    workspace.imageTexture(iconURL, function(err, result) {
        if(err) {
            console.warn(err);
            return;
        }

        var map = result;
        iconMesh.material.map = map;
        iconMesh.material.map.needsUpdate = true;
        iconMesh.material.needsUpdate = true;
    });


    var t = workspace.textTexture(data.resource.title, conf.fontColor);
    var texture = t.texture;
    var size = t.size;
    var x = w*(size.width/size.height);
    var y = h;

    //var titleMaterial = new THREE.MeshBasicMaterial({ map: texture, side: THREE.DoubleSide });
    var titleMaterial = workspace.decideMaterial(data, { map: texture, side: THREE.DoubleSide });
    if(!titleMaterial) {
        return callback(null);
    }
    titleMaterial.transparent = true;
    titleMaterial.color.set(conf.fontColor);
    var titleGeometry = new THREE.PlaneGeometry(x, y);
    var titleMesh = new THREE.Mesh(titleGeometry, titleMaterial);
    titleMesh.name = 'title';


    var totalWidth = x + w + 2; // 4 is between space
    iconMesh.position.x = -(totalWidth/2 - (w/2))+1;
    titleMesh.position.x = (totalWidth)/2 - x/2-1;


    var bgGeometry = new THREE.PlaneGeometry(totalWidth, h);
    //var bgMaterial = new THREE.MeshBasicMaterial({ side: THREE.DoubleSide });
    var bgMaterial = workspace.decideMaterial(data, { side: THREE.DoubleSide });
    if(!bgMaterial) {
        return callback(null);
    }
    bgMaterial.transparent = true;
    //bgMaterial.depthTest = false; // Always behind order
    bgMaterial.color.set(data.color);

    var bgMesh = new THREE.Mesh(bgGeometry, bgMaterial);
    bgMesh.name = 'group_bg';

    var group = new THREE.Group();
    group.add(bgMesh);
    group.add(iconMesh);
    group.add(titleMesh);
    workspace.scene.add(group);

Used light as DirectionalLight with intensity value to 1.0.

Please help me.

May be related?

Already set as:
self.glRenderer.outputEncoding = THREE.sRGBEncoding;
And I am not use gammaFactor.

Play around with some lighting. Maybe decrease the intensity value of DirectionalLight and appropriate AmbientLight in combination with it and tweak both light according to your need.

It shouldn’t be necessary to play around with lighting when upgrading three.js versions, we don’t intentionally make changes quite that capriciously. :slight_smile:

Really looks to me like your first scene uses a gamma workflow and your second uses a linear workflow. If that’s the case, maybe you should remove the renderer.outputEncoding = sRGBEncoding line?

Aside, I personally think the 2nd looks better, with exception of the Youtube logo. Note that if you are using sRGBEncoding for the output, you should also set texture.encoding = sRGBEncoding for any texture you add to the scene yourself, if it contains color data. In the code you shared, iconMesh.material.map.encoding should be set to sRGBEncoding if the renderer output is sRGB.

If that’s not helping you may need to share a live demo, I think that’s all I can guess by looking at the screenshots.

Dear sir
I not changed my code in r118. Same code were tested on both version.
And I have not use any setting for gamma.
I just make my some converter.
I am happy if you check my code.

const colorWizard = {
    toSRGB: function(object, renderer) {
        if(renderer) {
            if(renderer.physicallyCorrectLights === false) {
                renderer.physicallyCorrectLights = true;
            }
            if(renderer.outputEncoding != THREE.sRGBEncoding) {
                renderer.outputEncoding = THREE.sRGBEncoding;
            }
        }

        this.traverseMaterials(object, function(material) {
            if(material.color) material.color.convertSRGBToLinear();
            if(material.map) material.map.encoding = THREE.sRGBEncoding;
            if(material.emissiveMap) material.emissiveMap.encoding = THREE.sRGBEncoding;
            if(material.map) material.map.needsUpdate = true;
            if(material.emissiveMap) material.emissiveMap.needsUpdate = true;
            material.needsUpdate = true;
        });
    },

    toLinear: function(object, renderer) {
        if(renderer) {
            if(renderer.physicallyCorrectLights === true) {
                renderer.physicallyCorrectLights = false;
            }
            if(renderer.outputEncoding != THREE.LinearEncoding) {
                renderer.outputEncoding = THREE.LinearEncoding;
            }
        }

        this.traverseMaterials(object, function(material) {
            if(material.color) material.color.convertLinearToSRGB();
            if(material.map) material.map.encoding = THREE.LinearEncoding;
            if(material.emissiveMap) material.emissiveMap.encoding = THREE.LinearEncoding;
            if(material.map) material.map.needsUpdate = true;
            if(material.emissiveMap) material.emissiveMap.needsUpdate = true;
            material.needsUpdate = true;
        });
    },

    traverseMaterials: function (object, callback) {
        object.traverse(function(node) {
            if (!node.isMesh) return;
            const materials = Array.isArray(node.material)
                ? node.material
                : [node.material];
            materials.forEach(callback);
        });
    }
};

// For Linear color
colorWizard.toLinear(object, renderer); // renderer is optional!
// For sRGB color
colorWizard.toSRGB(object, renderer); // renderer is optional!

Is it right?
If that’s, I think, need to add colorWizard to THREE object as one properties.
How about think?
Is right my code?

physicallyCorrectLights is not really related to colorspace, I think you can eliminate that as a cause here.

Sorry, I can’t guess whether your code is doing the right thing because I don’t know what the rest of the scene contains. I would suggest sharing the code in a form that allows others to run it, e.g. as Code Sandbox or a .ZIP.