# Over saturated GLTF texture

**URL:** <https://discourse.threejs.org/t/over-saturated-gltf-texture/13359>\
**Category:** Questions\
**Tags:** gltf-loader\
**Created:** [March 8, 2020, 2:12am UTC](https://discourse.threejs.org/t/over-saturated-gltf-texture/13359 "2020-03-08T02:12:19Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Heiddo](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/heiddo/32/11844_2.png) [@Heiddo](https://discourse.threejs.org/u/Heiddo)\
**Post date:** [March 8, 2020, 2:12am UTC](https://discourse.threejs.org/t/over-saturated-gltf-texture/13359/1 "2020-03-08T02:12:20Z")

</div>

Hello, I created this model in blender:

 ![Screen Shot 2020-03-08 at 01.56.01](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/2X/6/692ffe8d6f943b741b4668315f1d1f629cad82cf.jpeg)  
 ![Screen Shot 2020-03-08 at 02.00.01](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/2X/f/fa6d9d74cb7efb21135bc5695ff42dbaa86db055.png)  
I imported it into my project using the GLTFLoader but It renders like this in my project:  
 ![Screen Shot 2020-03-08 at 01.58.26](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/2X/1/1b2868f7a03d1e6af31a929eab6b48599a4ae256.jpeg)  
So far I have read responses from @donmccurdy & @Mugen87 on a couple of similar posts. From this I tried including:

- physically correct lights
- sRGBEncoding
- gammaOutput: true
- gammaFactor at 2.2

I currently do all of this at the top of my file like this:

`var renderer = new THREE.WebGLRenderer({ antialias: true, physicallyCorrectLights: true, outputEncoding: THREE.sRGBEncoding, gammaOutput: true, gammaFactor: 2.2});`

And here is my GLTFLoader code:

```
 // Load a glTF resource
    loader.load(
        // resource URL
        'assets/peachpeach2.gltf',
        // called when the resource is loaded
        function ( gltf ) {

                mesh = gltf.scene;
                mesh.scale.set( 20, 20, 20 );
                meshGroup.add(mesh);
                meshGroup.position.x = 0
                meshGroup.position.y = 0
                meshGroup.position.z = 0
                scene.add( meshGroup );
                
                //scene.add( gltf.scene );

                //gltf.animations; // Array<THREE.AnimationClip>
                //gltf.scene; // THREE.Scene
                //gltf.scenes; // Array<THREE.Scene>
                //gltf.cameras; // Array<THREE.Camera>
                //gltf.asset; // Object

        },
        // called when loading is in progresses
        function ( xhr ) {

                console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );

        },
        // called when loading has errors
        function ( error ) {

                console.log( 'An error happened' );

        }
    );
}

```

I think I also saw it mentioned that i should be using model traverse inside of my GLTF to set things like sRGBEncoding etc…but from the few explanations that i’ve read that referenced the traverse method, I struggle to understand the syntax and don’t know how to fit it into the GLTFLoader code I have.

Anyone able to point me in the right direction?

---

<div class="post-metadata">

**Author:** ![donmccurdy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/donmccurdy/32/33209_2.png) [@donmccurdy](https://discourse.threejs.org/u/donmccurdy)\
**Post date:** [March 8, 2020, 7:36am UTC](https://discourse.threejs.org/t/over-saturated-gltf-texture/13359/2 "2020-03-08T07:36:54Z")

</div>

This all looks right. Have you tested the model in any online glTF viewers?

---

<div class="post-metadata">

**Author:** ![Heiddo](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/heiddo/32/11844_2.png) [@Heiddo](https://discourse.threejs.org/u/Heiddo)\
**Post date:** [March 8, 2020, 12:41pm UTC](https://discourse.threejs.org/t/over-saturated-gltf-texture/13359/3 "2020-03-08T12:41:46Z")

</div>

Yeah i tried loading it into your [https://gltf-viewer.donmccurdy.com/](https://gltf-viewer.donmccurdy.com/) and everything was fine. Hmm.

I’m scouring my code trying to think what else it could be. I have an ambient light and a directional light so at 1.1 & 0.1 respectively.

I’m not sure how I would create a live example on fiddle for this because of the custom asset hosting, but here is the full document (it’s not that long): [index.js](https://www.codepile.net/pile/vKqxVqDp)

---

<div class="post-metadata">

**Author:** ![Heiddo](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/heiddo/32/11844_2.png) [@Heiddo](https://discourse.threejs.org/u/Heiddo)\
**Post date:** [March 8, 2020, 12:59pm UTC](https://discourse.threejs.org/t/over-saturated-gltf-texture/13359/4 "2020-03-08T12:59:34Z")

</div>

I have also just realised that i’m using three r105 whilst using gltfloader r92. I’m guessing this could be a cause?

If so - i’m not sure how to locate a gltfloader r105…

---

<div class="post-metadata">

**Author:** ![donmccurdy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/donmccurdy/32/33209_2.png) [@donmccurdy](https://discourse.threejs.org/u/donmccurdy)\
**Post date:** [March 8, 2020, 4:36pm UTC](https://discourse.threejs.org/t/over-saturated-gltf-texture/13359/5 "2020-03-08T16:36:06Z")

</div>

> [@Heiddo](#):
>
> I have also just realised that i’m using three r105 whilst using gltfloader r92. I’m guessing this could be a cause?

That sounds likely to be the issue, yes. If you’re installing them from npm, then both files can be accessed through the npm installation. If you’ve downloaded the library from GitHub, you can use the branch/version dropdown to find r105, then navigate to the `examples/js{m}/loaders` directory:

 ![Screen Shot 2020-03-08 at 9.34.33 AM](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/2X/b/b03b7911e0c261af0b3aa98fec22536e5e400f8c.png)

---

<div class="post-metadata">

**Author:** ![Heiddo](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/heiddo/32/11844_2.png) [@Heiddo](https://discourse.threejs.org/u/Heiddo)\
**Post date:** [March 9, 2020, 2:01pm UTC](https://discourse.threejs.org/t/over-saturated-gltf-texture/13359/6 "2020-03-09T14:01:59Z")

</div>

Frustratingly the problem still persists with r105 being used for both three and gltfloader.

My only solution thus far is compensating for the effect inside of blender. I’ve just been making blender objects that have a darker than usual material color and it’s getting me closer to ‘normal’. I don’t think it’s too efficient to do it this way but will work as a last result if i need the project live.

I’ll keep trying solve this - if anyone in the mean time notices something in my code please let me know.

Thanks 🙂

---

<div class="post-metadata">

**Author:** ![looeee](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/looeee/32/59_2.png) [@looeee](https://discourse.threejs.org/u/looeee)\
**Post date:** [March 9, 2020, 2:53pm UTC](https://discourse.threejs.org/t/over-saturated-gltf-texture/13359/7 "2020-03-09T14:53:44Z")

</div>

> [@Heiddo](#):
>
> var renderer = new THREE.WebGLRenderer({ antialias: true, physicallyCorrectLights: true, outputEncoding: THREE.sRGBEncoding, gammaOutput: true, gammaFactor: 2.2});

I wasn’t aware you could pass the properties into the `WebGLRenderer` constructor like that.

Can you try this?

```js
const renderer = new WebGLRenderer({
   antialias: true,
});

renderer.physicallyCorrectLights = true;
renderer.outputEncoding = THREE.sRGBEncoding;

renderer.gammaOutput = true;
renderer.gammaFactor = 2.2;

```

---

<div class="post-metadata">

**Author:** ![donmccurdy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/donmccurdy/32/33209_2.png) [@donmccurdy](https://discourse.threejs.org/u/donmccurdy)\
**Post date:** [March 9, 2020, 4:29pm UTC](https://discourse.threejs.org/t/over-saturated-gltf-texture/13359/8 "2020-03-09T16:29:32Z")

</div>

It might also help if you could share the `.blend` file, or a similar one with the same issue. You shouldn’t have to compensate in Blender.

---

<div class="post-metadata">

**Author:** ![Heiddo](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/heiddo/32/11844_2.png) [@Heiddo](https://discourse.threejs.org/u/Heiddo)\
**Post date:** [March 12, 2020, 1:48pm UTC](https://discourse.threejs.org/t/over-saturated-gltf-texture/13359/9 "2020-03-12T13:48:24Z")

</div>

Apologies I was head down in other work. From what I can see now - I think some of my lighting was affecting the colour still. So the fix works for the heavy over saturation.

I also needed to get my lights in check to get the final exact replication.

I now have a perfectly represented model, thank you both.

---

<div class="post-metadata">

**Author:** ![adevart](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/adevart/32/7764_2.png) [@adevart](https://discourse.threejs.org/u/adevart)\
**Post date:** [March 12, 2020, 9:12pm UTC](https://discourse.threejs.org/t/over-saturated-gltf-texture/13359/10 "2020-03-12T21:12:29Z")

</div>

I had this problem too. If I manually set a texture’s encoding to sRGBEncoding, it renders really saturated. The default value for a texture is LinearEncoding:

> <https://github.com/mrdoob/three.js/blob/e3d60b17c0497a08ecb166eae799eb5cf6d9e7f5/src/textures/Texture.js#L68>

The GLTFLoader however defaults to using sRGBEncoding:

> <https://github.com/mrdoob/three.js/blob/e3d60b17c0497a08ecb166eae799eb5cf6d9e7f5/examples/jsm/loaders/GLTFLoader.js#L2234>

It’s really confusing trying to get the right appearance, especially when a GLTF shares the same texture as another asset in the scene. It may depend on the load order, which encoding is used. As mentioned in some posts above, it should just be a case of setting the renderer.outputEncoding to sRGBEncoding and everything should look ok but I’ve found it hard to get the output to match the source. If I use settings that fix GLTF objects, it makes other textures look washed out.

I managed to get one of my scenes to looking correct by setting the renderer outputEncoding to Linear as well as the GLTF textures but I don’t think that’s how it’s supposed to be and it didn’t work the same way on another scene.

The most problematic scenes were older ones that were upgraded, newer scenes seemed to work better just with outputEncoding=sRGBEncoding. The way lights behaved seems to have changed since older versions so that definitely seems to have had an effect on it.

---

<div class="post-metadata">

**Author:** ![donmccurdy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/donmccurdy/32/33209_2.png) [@donmccurdy](https://discourse.threejs.org/u/donmccurdy)\
**Post date:** [March 12, 2020, 10:11pm UTC](https://discourse.threejs.org/t/over-saturated-gltf-texture/13359/11 "2020-03-12T22:11:15Z")

</div>

The settings I would recommend using are these:

> <https://gist.github.com/donmccurdy/fefb35c5ba033e7dcd641f9684e47a82>

GLTFLoader configures things with the goal of fitting correctly into that workflow. Other loaders may vary, especially since not all formats even contain enough information to know what colorspace the textures and vertex colors actually are using.

For an older project that you just want to freeze with an older gamma workflow, you could also set _all_ the textures, and `renderer.outputEncoding` to `LinearEncoding`.

---

<div class="post-metadata">

**Author:** ![adevart](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/adevart/32/7764_2.png) [@adevart](https://discourse.threejs.org/u/adevart)\
**Post date:** [March 13, 2020, 7:38am UTC](https://discourse.threejs.org/t/over-saturated-gltf-texture/13359/12 "2020-03-13T07:38:17Z")

</div>

Thanks for posting this guide. The linked article was also really helpful in understanding what’s happening:

[https://blog.johnnovak.net/2016/09/21/what-every-coder-should-know-about-gamma/](https://blog.johnnovak.net/2016/09/21/what-every-coder-should-know-about-gamma/)

The best practises list is interesting. So given that the recommend encoding for maps is sRGB and the texture loader defaults to Linear, all manually loaded textures used for color maps should be explicitly set to sRGB. Perhaps the material classes could choose the encoding automatically unless the user has assigned an encoding type.

The last suggestion about using LinearEncoding for older projects makes sense. That seemed to work but I wasn’t aware of using a gamma workflow. Some textures I use are done in Photoshop, others are baked in 3D software. It’s hard to know if baked maps are gamma-corrected or not, I guess baked albedo maps are linear?

This issue is mentioned here:

> **[How important is it to use correct albedo maps? - 
		
		Unreal Engine Forums](https://forums.unrealengine.com/development-discussion/rendering/24177-how-important-is-it-to-use-correct-albedo-maps)**
>
> For discussions about Materials, Textures, Lighting, Particle Systems, and Post Process Effects.

“The same thing happened to me when exporting a roughness map from Substance Painter. When importing a map that has a very specific value for something like roughness or an alpha map, you should uncheck the sRGB box inside the texture. The same way that normal maps uncheck it by default because the RGB values need to be precise and not gamma corrected like most textures.”

This will take a bit of trial and error in the workflow to get everything right but it will be much easier with this explanation.

---

<div class="post-metadata">

**Author:** ![murgrabia\_bec](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/murgrabia_bec/32/14645_2.png) [@murgrabia\_bec](https://discourse.threejs.org/u/murgrabia_bec)\
**Post date:** [December 18, 2021, 10:33pm UTC](https://discourse.threejs.org/t/over-saturated-gltf-texture/13359/13 "2021-12-18T22:33:02Z")

</div>

This has fixed the issue for me. Thanks !
