Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Semi-transparent textures are rendered differently with postprocessing #27184

Closed
giusepperaso opened this issue Nov 13, 2023 · 3 comments
Closed

Comments

@giusepperaso
Copy link
Contributor

giusepperaso commented Nov 13, 2023

Description

If I try to render a png/webp where some pixels have partial transparency, the image is rendered incorrectly if postprocessing is enabled

I have tried with several images, it is mostly evident when the image has some form of semi-transparent "halo"

In the live example, click the button to switch between normal renderer and effect composer, so you will see the difference: the image is rendered correctly only if postprocessing is disabled

Some more info:

  • changing the type in the render target does not help
  • using GammaCorrectionShader instead than OutputPass does not change anything
  • if we remove color correction at the end, the result is even worse
  • smaa is used in the sandbox only as an example, to show what happens if we remove color correction and we have another pass other than renderpass; instead than smaa we could have put anything else like glitchpass etc..

Reproduction steps

  1. create a plane with a texture, the texture should be a transparent png where some pixels have partial transparency (>0.1 - 0.9<)
  2. apply some postprocessing into a scene
  3. at the end of the pipeline apply color correction (it is necessary most of the time anyway)

Code

(maybe just look at the live example)

const composer = new EffectComposer(renderer, target);
composer.addPass(new RenderPass(scene, camera));
composer.addPass( new SMAAPass( window.innerWidth * renderer.getPixelRatio(), window.innerHeight * renderer.getPixelRatio() ) );
composer.addPass(new OutputPass());
(new THREE.TextureLoader()).load("./texture.png",
  function(texture) {
    texture.colorSpace = THREE.SRGBColorSpace;
    const material = new THREE.MeshBasicMaterial({ transparent: true, map: texture });
    scene.add(new THREE.Mesh(new THREE.PlaneGeometry(7,7), material));
  }
)

Live example

Screenshots

No response

Version

0.157.0

Device

Desktop, Mobile

Browser

Chrome, Firefox, Safari, Edge

OS

Windows, MacOS, Linux, Android, iOS

@WestLangley
Copy link
Collaborator

Likely a duplicate of #23019.

@Mugen87
Copy link
Collaborator

Mugen87 commented Nov 14, 2023

To make it short: The blending of the post processing is actually the correct one. The problem is the inline sRGB encode when rendering directly to screen and then perform the blending.

@WestLangley WestLangley changed the title Semi-transparent textures are rendered incorrectly with postprocessing Semi-transparent textures are rendered differently with postprocessing Nov 14, 2023
@giusepperaso
Copy link
Contributor Author

giusepperaso commented Nov 14, 2023

Thanks, looking at this comment I managed to kinda solve my problem, but I think this will work only for an unlit scene

THREE.ColorManagement.legacyMode = true
renderer.outputColorSpace = THREE.LinearSRGBColorSpace;

// then for the texture
texture.colorSpace = THREE.LinearSRGBColorSpace;

codesandbox with the solution applied

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants