Arky
Arky

Reputation: 63

When do we need to use renderer.outputEncoding = THREE.sRGBEncoding

I'm a newbie in three.js. I have been learning three.js by trying to make simple scenes and understanding how the official examples work.

Recently I have been looking at https://threejs.org/examples/?q=trans#webgl_materials_physical_transmission, and I couldn't understand what's the exact reason that the code needs to use renderer.outputEncoding = THREE.sRGBEncoding here. In simpler scenarios such as loading JPGs as textures on cubes, the JPG images would look just fine without setting outputEncoding on the renderer.

I tried googling on similar topics such as gamma correction, and stuff like people saying most of the images online are gamma encoded in the sRGB color space. But I couldn't connect all the dots myself...I would be most grateful if anyone can explain this clearly to me.

Upvotes: 6

Views: 8748

Answers (1)

Mugen87
Mugen87

Reputation: 31026

If you do not touch renderer.outputEncoding, it means you use no color space workflow in your app. The engine assumes that all input color values are expected to be in linear space. And the final color value of each fragment is not transformed into an output color space.

This kind of workflow is problematic for different reasons. One reason is that your JPG texture is most likely sRGB encoded as well as many other textures. To compute proper colors in the fragment shader, it's important that all input color values are transformed into the same color space though (which is linear color space). If you don't care about color spaces, you quickly end up with wrong output colors.

For simple apps this detail does often not matter because the final image "just looks good". However, depending on what you are doing in your app (e.g. when importing glTF assets), a proper color space workflow is mandatory.

By setting renderer.outputEncoding = THREE.sRGBEncoding you tell the renderer to convert the final color value in the fragment shader from linear to sRGB color space. Consequently, you also have to tell the renderer when textures hold sRGB encoded data. You do this by assigning THREE.sRGBEncoding to the encoding property of textures. THREE.GLTFLoader does this automatically for all color textures. But when loading textures manually, you have to do this by yourself.

Upvotes: 13

Related Questions