outputEncoding not handled correctly when using sRGB render target in WebGL2
See original GitHub issueDescribe 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
dev
Platform:
- Device: Desktop
- OS: Linux
- Browser: Chrome
- Three.js version: dev
Issue Analytics
- State:
- Created 2 years ago
- Reactions:1
- Comments:11 (6 by maintainers)
Top 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 >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
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).
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 tothree
.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.
srgb framebuffer. Color is first converted to sRGB space then quantized and displayed. Much smoother.