Exported gltf looks odd in other programs?

When I export gltfs using the gltf exporter, I notice that the colors don’t look quite the same as they were when rendered in three.js
They appear washed out and brighter, and it is the case in any program I load them into.
Here are some images attached:

The first image shows the render in three.js as it should look with correct colors (meshbasicmaterial and vertex colors)

This second one shows it exported with meshbasicmaterial

export1

this third one shows exported with meshlambertmaterial

export2
The lambert one appears to have the correct colors for the texture, but the vertex colors look washed out on both exports.
The meshbasicmaterial has the colors blown out(not due to any lights since it doesn’t respond to lights, and it is the same case in any program).
I read that maybe it is related to this: Color management in three.js
but I’m not entirely sure what it is suggesting I do. I want it to stay the same as it looks in three.js so how do I export it so that it maintains that desired look?

edit:
I tried to use the sRGBEncoding, but it still outputs with incorrect colors:


		gltfTextures.push( new THREE.CanvasTexture(gltfCanvas[gltfCanvas.length-1]) ); 
		
		var tIndex = gltfTextures.length-1;
		gltfTextures[tIndex].magFilter = THREE.NearestFilter;
		gltfTextures[tIndex].minFilter = THREE.NearestFilter;
		gltfTextures[tIndex].flipY = false;
		gltfTextures[tIndex].encoding = THREE.sRGBEncoding;
		
		gltfMaterials.push( new THREE.MeshBasicMaterial( { map: gltfTextures[tIndex], alphaTest: 0.01, vertexColors: THREE.VertexColors } ) );

When you view the export, what tool are you using? Are you rendering that in three.js with the same renderer settings you originally had, or something else? Opening the model in https://gltf-viewer.donmccurdy.com/ might be worth a check for comparison.

GLTFExporter should export MeshBasicMaterial and MeshStandardMaterial the best, since they are very close to glTF materials. MeshLambertMaterial will always have at least some shading differences, but ideally the colors won’t be washed out for any of them when color management is correct.

The first image shows the render in three.js as it should look with correct colors (meshbasicmaterial and vertex colors)

What are renderer.outputEncoding and material.map.encoding set to, before export? It’s very likely that anything loading a glTF file is using settings similar to “color management in three.js”, so if your original scene is not configured that way, this may be the source of the difference.

I’m using the default values: renderer.outputEncoding is set to THREE.LinearEncoding.
The screenshots I took were from windows 3d viewer
Here is one from blender:

The right side model has the vertex colors convertSRGBToLinear() before exported, and it seems a bit better but not quite the same. The texture still seems a bit washed out too.

When I load the model with the converted colors it into the gltf-viewer that you linked, it looks almost the same, however there are slight differences, as you can see in the dark area in the middle and also the vertex colors look less smooth on the floor (maybe due to the conversion?)… here’s a image

edit:
I found that I can change the Color Management in Blender. It was set to “Filmic” and when I set it to “Standard” the color of the texture looks accurate.

I guess the differences now are just in the program’s methods of rendering? Though I’m still confused why the vertex colors look slightly different. I’m assuming it’s probably due to the conversion of the data.

The default rendering options of three.js are more of a gamma workflow, that’s an older/legacy rendering setup and most viewers don’t use by default, or may not even offer the option. So you’re starting with an unusual rendering setup, and are kind of trying to reverse engineer the model to account for that during export.

The ideal solution here is to use a linear workflow up front as described in that color management article, it’s much easier to match results before/after that way.

If that’s not possible, then … converting vertex colors sRGB → Linear sounds right. Converting the texture sRGB → Linear might also help, but isn’t as easy to do in three.js and may be better done offline. It could help to try exporting two versions, (1) only with vertex colors, (2) only with textures, to isolate the problem.

Disabling tonemapping (e.g. Filmic) does help, but is a smaller part of the problem.

edit: (deleted message) I made error… rechecking.

edit2:
Okay, thanks for the information…
How do I set three.js to be in a linear workflow? When I convert colors to linear, they don’t look accurate in three.js. When they are sRGB they look accurate.

I convert the vertex colors to linear when exporting, and then when importing back into my three.js program, I have to convert them back to sRGB to get them to display accurately. Is this the correct workflow?

The article here describes everything you should need to do in a linear workflow: Color management in three.js. If you’re using those settings before exporting to glTF, and when viewing after importing the glTF file again, it should look the same before and after. Whether the way it looks the way you want is harder to guess, I can’t see your code, colors, textures, or anything but the screenshots. It may be that some colors need to be changed to look the way you want in the linear workflow.

Alright, thanks. I think I am doing those things listed there.
Only thing I was unsure about was where it said vertex colors should be “stored” in linear colorspace. I wasn’t sure if they needed to be stored that way in the buffergeometry, while it is being used, or if that was only necessary when exporting. But now the way I interpret that after some testing, is that they should be sRGB when they are used, and then when exporting/stored, they should be converted with .convertSRGBToLinear(). and then when loaded, converted back to sRGB. That seems to be how it works from my testing.

The vertex colors are supposed to be stored as linear (and any dedicated glTF viewer will interpret them as such), but they aren’t being changed during import/export at all by default.

Alright, I got it. Thanks :slight_smile: