My modal is .obj, and it displays well when I use objLoader and mtlLoader . I use obj2gltf to convert my obj modal to gltf. And then it displays more darker with GLTFLoader. what's the problem?
Can other viewers/libs render as you expect? If not, it'd be an obj2gltf issue.
Assuming you're converting to glTF 2.0, obj2gltf is converting to a metal-rough PBR workflow, i.e. THREE.MeshStandardMaterial. This may give different results, and/or look better with an environment map.
As others mention, comparing against various viewers (https://gltf-viewer.donmccurdy.com/, http://sandbox.babylonjs.com/) or including your source and output models would make it easier to help you. It may be an obj2gltf issue.
I am experiencing the same issue. I am not using obj2gltf. If you look at the gltf loader example (https://threejs.org/examples/#webgl_loader_gltf) with GLTFLoader.js r87 vs r88, you will see that the r88 is significantly darker.
@rck1 that is another issue, see https://github.com/donmccurdy/three-gltf-viewer/issues/51. r88 is correct, THREE.GLTFLoader <=r87 had used incorrect texture encoding.
@donmccurdy, thanks for the link and explanation. That makes sense but I was hoping there would be consistency across the image applications that I use and the results that I'm seeing with the GLTFLoader. For instance, looking at the texture in a program like Photoshop and rendered using three.js/GLTFLoader now looks very different. With r87 it looks the same. But the results using JSONLoader (r87 or r88) is still consistent.
@rck1 Base color and emissive textures in glTF are expected to be in sRGB colorspace, not linear. If you're creating textures in Photoshop, you will want to set export options accordingly. glTF-specific tools, like the Blender exporter, should automatically do this conversion (and it would be a bug if they are not).
@donmccurdy I'll double check the color management workflow across all my applications to ensure sRGB colorspace. Thanks for your help with this.
@donmccurdy Thanks for your suggest.The following modal is converted by obj2gltf and show with threejs GLTF viewer. Obviously it's more darker than normal and not expected. And I got some suggests yesterday to return THREE.MeshLambertMaterial in threejs GLTFLoader.js souce code line 299. The modal seemed more lighter than before but still dark.
So I changed the viewer http://sandbox.babylonjs.com/ you told me.Finally I find what I expected.
What should I do with GLTFLoader.js of threejs or is there any way threejs learning from babylonjs?
@donmccurdy I did some digging and think I gained some surface-level knowledge on this topic of color management. I think three.js utilizes linear color space throughout it's pipeline for lighting calculations, etc. So when you flag the map/texture as sRGB, it removes the gamma correction so calculations can correctly be done in linear color space. I think this is the right approach and is followed by most standard 3D applications. However, by default, three.js doesn't gamma correct it's rendering output by default. So removing the gamma correction in sRGB texture results in a darker than intended output.
@Maplesog Try adding the following to your renderer.
renderer.gammaFactor = 2.2;
renderer.gammaOutput = true;
This should perform the proper gamma correction.
What should I do with GLTFLoader.js of threejs or is there any way threejs learning from babylonjs?
@Maplesog it's probably not a threejs problem: the lighting in my viewer is not great, and generally looks too dark for many models. That's just a matter of adjusting the scene lighting, though... You can tweak knobs in the settings, or set up your own scene to make it as bright as you want. I've been meaning to improve the defaults in my viewer, but haven't found something I'm happy with: https://github.com/donmccurdy/three-gltf-viewer/issues/44
Swapping in MeshLambertMaterial will certainly change what you see, but is technically not a shading model supported by the glTF format (currently) so you'd need to do those modifications yourself.
If you're testing in your own scene, make sure to include an envMap
. MeshStandardMaterial tends to look better with that.
Finally, if you can share the model this type conversation is often more productive. If you've only tested the model in my viewer, it might be better to file an issue there... lighting is not dictated by GLTFLoader or three.js, it's up to the viewer application to choose that.
@rck1 thanks, this sounds like it's worth looking into. If you have an example you can share, that would be helpful.
@rck1 It works! @donmccurdy Your suggestion let me have a deeper understanding of the GLTFloader, Thank you very much!
Reopening this, as I do think there may be an issue. I've put more lighting knobs in my viewer, https://gltf-viewer.donmccurdy.com/, with what I hope are reasonable defaults, to help sort this out.
With all default settings (directIntensity=0.8
, ambientIntensity=0.3
), here is a comparison of texture encodings.
| sRGB | Linear |
|---|---|
| | |
This example is pretty representative of the glTF-Sample-Models catalog — they all look better lit, and maybe a little washed out, with THREE.LinearEncoding left as the default. Per glTF 2.0 spec, these textures are supposed to be sRGB. And with default lighting in several other viewers, the same model looks reasonable:
| viewer | preview |
|---|---|
| three.js | |
| babylon.js | broken? |
| qtek | |
| sketchfab | |
Original: https://sketchfab.com/models/f2f13a8630004b1c82730d8b9ffa0e1f
If I leave the default THREE.LinearEncoding on, our result looks quite close to Sketchfab. So... what's going on here? 😕
no more gamma?
WebGLRenderer.gammaInput
and WebGLRenderer.gammaOutput
have been removed with R112
. This is mentioned in the migration guide:
https://github.com/mrdoob/three.js/wiki/Migration-Guide#r111--r112
Instead of doing this:
renderer.gammaFactor = 2.2;
renderer.gammaOutput = true;
do this:
renderer.outputEncoding = THREE.sRGBEncoding;
I'm finding my textures display darker despite setting
renderer.outputEncoding = THREE.sRGBEncoding;
They were correct in r111.
I've also tried
mesh.material.metalness = 0;
renderer.physicallyCorrectLights = true;
Without success.
Please ask at the forum for help. It's also recommended to share a live example that demonstrates your issue.
Most helpful comment
@donmccurdy I did some digging and think I gained some surface-level knowledge on this topic of color management. I think three.js utilizes linear color space throughout it's pipeline for lighting calculations, etc. So when you flag the map/texture as sRGB, it removes the gamma correction so calculations can correctly be done in linear color space. I think this is the right approach and is followed by most standard 3D applications. However, by default, three.js doesn't gamma correct it's rendering output by default. So removing the gamma correction in sRGB texture results in a darker than intended output.
@Maplesog Try adding the following to your renderer.
renderer.gammaFactor = 2.2;
renderer.gammaOutput = true;
This should perform the proper gamma correction.