question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

outputEncoding not handled correctly when using sRGB render target in WebGL2

See original GitHub issue

Describe the bug

In #23129, the outputEncoding is calculated differently from before. I believe the previous way is correct.

To Reproduce

See following code and fiddle.

Code


const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.setPixelRatio( window.devicePixelRatio );
document.body.appendChild( renderer.domElement );

const geometry = new THREE.PlaneGeometry( 2, 2 );
const material = new THREE.MeshBasicMaterial();
const mesh = new THREE.Mesh( geometry, material );

const renderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, { encoding: THREE.sRGBEncoding } );

const camera = new THREE.OrthographicCamera();
camera.position.set( 0, 0, 1 );

new THREE.TextureLoader().load( 'https://threejs.org/examples/textures/crate.gif', (texture) => {

  texture.encoding = THREE.sRGBEncoding;

  material.map = texture;
  renderer.setRenderTarget( renderTarget );
  renderer.render( mesh, camera );

  material.map = renderTarget.texture;
  renderer.setRenderTarget( null );
  renderer.render( mesh, camera );

} );

Live example

Expected behavior

dev should behave the same as r136.

Screenshots

r136 image

dev image

Platform:

  • Device: Desktop
  • OS: Linux
  • Browser: Chrome
  • Three.js version: dev

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:11 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
vanruesccommented, Jan 17, 2022

To provide some additional information on the topic:

Storing linear colors in 8bit buffers causes color degradation and banding. Linear colors should only be stored with at least 12 bits of precision per channel to avoid this (reference).

I’ve referred with my comment to FX setups with multiple passes. sRGB should be applied at the end. Intermediate frame buffers should be linear.

This is correct, but it requires HalfFloatType buffers to avoid banding which can have an impact on performance and may not be supported on some devices. Unity stores intermediate results in 8bit buffers for non-HDR post-processing setups by converting colors from linear to sRGB and back to linear (reference, see “Linear color space and non-HDR”). This obviously works best with hardware encoding/decoding support via SRGB8_ALPHA8 buffers, which was only recently added to three.

0reactions
chubei-oppencommented, Jan 18, 2022

To show how the effect looks like in three:

linear framebuffer. Color is quantized in linear space then converted to sRGB space for displaying. Notice the banding effect. image

srgb framebuffer. Color is first converted to sRGB space then quantized and displayed. Much smoother. image

Read more comments on GitHub >

github_iconTop Results From Across the Web

three.js - When do we need to use renderer.outputEncoding ...
One reason is that your JPG texture is most likely sRGB encoded as well as many other textures. To compute proper colors in...
Read more >
WebGLRenderer#outputEncoding – three.js docs
Defines the output encoding of the renderer. Default is THREE.LinearEncoding. If a render target has been set using .setRenderTarget then renderTarget.texture.
Read more >
What's New | Babylon.js Documentation
A browser error preventing the emulator to render scene is now correctly dealt with (RaananW); Added a way to extend the XRSessionInit Object...
Read more >
Three-gpu-pathtracer - npm.io
Path tracing project using three-mesh-bvh and WebGL 2 to accelerate high quality, physically based rendering on the GPU. Features include support for GGX ......
Read more >
three-gpu-pathtracer | Path tracing renderer and utilities for ...
Path tracing project using three-mesh-bvh and WebGL 2 to accelerate high quality, ... MeshBasicMaterial( { map: ptRenderer.target.texture, // if rendering ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found