niao
July 21, 2020, 1:32am
1
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.
niao
July 21, 2020, 1:42am
3
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.
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.
niao
July 22, 2020, 12:45am
6
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.