I'm building a web ar app that allows users to wear GLTF head models. (https://www.head5.camera/) In order to get the correct lighting on the GLTF, I have set renderer.outputEncoding = THREE.sRGBEncoding
and this works great BUT it also adjusts the lighting of my THREE.VideoTexture
from my video stream. Is there a way to encode just the GLTF but preserve the LinearEncoding? of the rest of the scene. Any help is much appreciated.
Here's an example of what I mean:
The background is lighter than it is supposed to be because it is also being encoded.
Output encoding is a renderer-level setting and cannot be changed for specific objects or materials. Because you can only have one renderer.outputEncoding
, it's necessary that you stick consistently to either a gamma workflow or a linear workflow (background reading).
THREE.GLTFLoader configures materials and textures with the assumption that you're using a linear workflow, and that requires renderer.outputEncoding = THREE.sRGBEncoding
(or equivalent post-processing). It sounds like the rest of your scene is configured for a gamma workflow. To make those consistent you'll probably want to traverse the whole scene (including both glTFs and any other models / textures) and configure the colorspace of the relevant textures.
scene.traverse((object) => {
if (object.isMesh) {
const material = object.material;
if (material.map) material.map.encoding = THREE.sRGBEncoding;
if (material.emissiveMap) material.emissiveMap.encoding = THREE.sRGBEncoding;
if (material.sheenColorMap) material.sheenColorMap.encoding = THREE.sRGBEncoding;
if (material.specularColorMap) material.specularColorMap.encoding = THREE.sRGBEncoding;
}
});
With those changes, sRGB output encoding for a "linear workflow" will look correct. You can also do the opposite – switching these textures to THREE.LinearEncoding
— if you want to use linear output encoding for a "gamma workflow". That might be easier if you have a lot of other content in the scene.