Subtle colour banding issue, looks like 256 colours when using Bloom with Effect Composer

threejs banding

Struggling to fix this issue, now day 2 of this and I keep running into the same banding issue, with different pass setups.

  renderer.setClearColor('#000000');
  const bloomPass = new UnrealBloomPass(new THREE.Vector2(width, height), 1, 1, 0.75);
  const copyPass = new ShaderPass(CopyShader);
  copyPass.renderToScreen = false;
  bloomPass.renderTargetsHorizontal.forEach((element) => {
    element.texture.type = THREE.FloatType;
  });
  bloomPass.renderTargetsVertical.forEach((element) => {
    element.texture.type = THREE.FloatType;
  });
  const composer = new EffectComposer(renderer);
  composer.renderer.outputEncoding = sRGBEncoding;
  composer.setSize(width, height);
  composer.setPixelRatio(density);
  const normalRender = new RenderPass(scope.scene, scope.cameraManager.camera);
  composer.addPass(normalRender);
  composer.addPass(bloomPass);
  composer.renderer.toneMapping = ACESFilmicToneMapping;

  THREE.ShaderChunk.tonemapping_pars_fragment = THREE.ShaderChunk.tonemapping_pars_fragment.replace(
    'vec3 CustomToneMapping( vec3 color ) { return color; }',
    `#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )
    float toneMappingWhitePoint = 1.0;
    vec3 CustomToneMapping( vec3 color ) {
      color *= toneMappingExposure;
      return saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );
    }`,
  );

env map setup

    cubeTextureLoader.loadAsync([`${map}_px.jpg`, `${map}_nx.jpg`, `${map}_py.jpg`, `${map}_ny.jpg`, `${map}_pz.jpg`, `${map}_nz.jpg`]).then((textureCube) => {
      this.scene.environment = textureCube;
      textureCube.encoding = sRGBEncoding;
      this.scene.background = textureCube;
    });

Is there anything I am missing?

Using ThreeJS 133.1

By the way when i add the following to the end, the entire scene becomes dark so thats why its not in there yet :
composer.addPass(copyPass);

Edit: I realised this always happens when you add unreal bloom pass into the effect composer, it just creates a colour banding

Can you please create your effect composer like so:

const parameters = {
	minFilter: THREE.LinearFilter,
	magFilter: THREE.LinearFilter,
	format: THREE.RGBAFormat,
	type: THREE.FloatType
};

const renderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, parameters );

const composer = new EffectComposer( renderer, renderTarget );

Any improvements?

Don’t do that. When using post processing don’t touch outputEncoding but apply a gamma correction pass at the end of the pass chain like so:

Tone mapping should also be done via post-processing: three.js webgl - adaptive tone-mapping

2 Likes

Totally lost on this now.


banding 2

Thanks for your help.

Adding the render target, cant see a noticeable difference visually.

  const renderTarget = new WebGLRenderTarget(width, height);
  const composer = new EffectComposer(renderer, renderTarget);
  const normalRender = new RenderPass(scene, cameraManager.camera);
  const adaptiveToneMapping = new AdaptiveToneMappingPass(true, width);
  adaptiveToneMapping.needsSwap = true;
  const gamma = new ShaderPass(GammaCorrectionShader);
  composer.addPass(normalRender);
  composer.addPass(adaptiveToneMapping);
  composer.addPass(bloomPass);

Adding GammaCorrectionShader causes banding and looks like a toonshader, without GammaCorrectionShader the scene looks very dark.
Adding AdaptiveToneMapping doesnt do anything. Scene still looks dark.

I should add I was using Varunesc postprocessing npm package before switching back to THREE after an update, should I switch back? Is the THREE effect composer pipeline buggy?

Later in the day I will create a jsfiddle sample