Selective bloom problem

Hi everyone,

I’m working on a Three.js scene with a 3D model. I want to apply a bloom effect to specific nodes of the model (let’s say node18 and node19). To achieve this, I’ve set these nodes to a different layer (layer 1) while keeping the rest of the scene on the default layer (layer 0).

I’m rendering the two layers separately:

  1. Layer 0: Rendered without bloom.
  2. Layer 1: Rendered with the bloom effect applied.

The bloom rendering itself works fine, but my issue arises when trying to combine the post-processed bloom layer with the regular rendered scene. Using the code below, I can only see the objects in layer 1 (the bloom layer), and the objects from layer 0 disappear.

Here’s my current setup:

export function buildScene() 
{
  initScene();
  initRenderer();
  initCamera();
  initCSSRenderer();
  initSkybox();
  initLights();
  initControls();
  loadModels();
  addEventListeners();

  composerBloom = new EffectComposer(renderer);
  const renderBloom = new RenderPass(scene, camera);
  composerBloom.addPass(renderBloom);

  const bloomPass = new UnrealBloomPass(
    new THREE.Vector2(window.innerWidth, window.innerHeight),
    1.5,   // Intensity
    0.5,   // Radius
    0.1    // Threshold
  );
  composerBloom.addPass(bloomPass);
}

function animate() 
{
  requestAnimationFrame(animate);
  if (controls) controls.update(0.01);

  camera.layers.set(0);
  renderer.autoClear = true;
  renderer.render(scene, camera);

  camera.layers.set(1);
  renderer.autoClear = false; 
  composerBloom.render();

  if (cssRenderer && scene && camera) 
    cssRenderer.render(scene, camera);
}

buildScene();
animate();

What Happens

With the code above, I can only see the objects from layer 1 (bloom), and layer 0 is not visible. It seems like the composerBloom.render() is overwriting the regular render output.

What I Want to Achieve

I’d like to combine the two layers so that:

  • The objects on layer 0 (regular render) appear without bloom.
  • The objects on layer 1 (with bloom) are rendered over the top.

I’m not sure how to properly mix the post-processed bloom pass with the regular render. Any suggestions or insights into how to fix this would be greatly appreciated!

Thanks in advance! :blush:

With modern threejs (webGL2) you can selectively control bloom using the threshold, and the .emissive color of the material.

I find it much easier to control that doing multipass/layering approaches… although i suppose with layering you might be able to squeeze our some quality since you get to render occluded bloomed geometry…

To manually composite bloomed pass with forward pass sounds… Hard.

Alright, I’ll try that tomorrow. So, I’ll only add emissive to the parts of my model where I want bloom and set emissive to 0 everywhere else. It’s the trick?

1 Like

Pretty much. The reason this works now, (and didn’t in the past) is that threejs used to have an “SDR” framebuffer which clamped light intensities to 0 to 1 space… so there wasn’t a way to set the .threshold high enough to reliably exclude intensely lit parts of the scene… (even though sometimes you Do want that… )

Now the lighting pipeline is HDR so values are not clamped… so you can set a bloom threshold to something high like 10… and if you have an emissive color like (15,0,0) (super bright red) you get bloom.

The values you set will vary depending on what the max total light intensity is your scene, but that’s the gist of it.

1 Like