Mixing two scenes with either glowing and non-glowing objects

I have one Renderer object and two scene objects. One scene contains the objects that should not be processed by the unrealbloom post-processing pass and the other scene contains all “glowing” objects.

Now I thought I could do:

const THREED_Composer = new THREE.EffectComposer( THREED_Renderer );
const THREED_RenderPass = new THREE.RenderPass( THREED_Scene, THREED_Camera );
const THREED_RenderPassGlow = new THREE.RenderPass( 
    THREED_SceneGlow, THREED_Camera );
const THREED_BloomPass = new THREE.UnrealBloomPass(
    new THREE.Vector2(window.innerWidth, window.innerHeight), 0.5, 0.5, 0.4);
//THREED_BloomPass.renderToScreen = false; ???
THREED_Composer.addPass( THREED_RenderPassGlow );
THREED_Composer.addPass( THREED_BloomPass );
THREED_Composer.addPass( THREED_RenderPass );

The goal was to first render the glowing objects and then render the non-glowing objects over them. I want the non-glowing objects to be able to obscure the glowing objects.

My animate function looks like this:

function animate()
{
    if(GLOBAL_FocusLost)
        return;
    requestAnimationFrame(animate);
    update();
    THREED_Composer.render();
}

Ultimate goal:
I want to have glowing monolith in the midst of a room that can be obscured by all other objects.

I tried to read my way through the documentation but I think that I do not understand it enough.

Cheers. Any help is very much appreciated!

there’s two ways to do this.

the easier method is simple but limited. render the glow stuff first, if you can get away with it: https://codesandbox.io/s/r3f-selective-bloom-7mfqw

the second one is messy, you can to render the scene twice, once with an override material, then use a shader to merge them: https://codesandbox.io/s/r3f-selective-bloom-1bult

just disregard the declarative stuff, the math is the same.

generally i’d recommend checking out the postprocessing lib by varunesc. it is usually faster than jsm effects and it’s a little bit more high level - the bloom effect for instance supports selective bloom ootb.

3 Likes

Hi drcmda,

thank you for your help! Before I try the postprocessing library, I would just like to know why the following code does not work:

THREED_Renderer.setSize( HTML_containerWidth, HTML_containerHeight );
THREED_Renderer.shadowMap.enabled = true;
THREED_Renderer.shadowMap.type = THREE.PCFShadowMap;
THREED_Renderer.outputEncoding = THREE.sRGBEncoding;
THREED_Renderer.autoClear = false;
THREED_Renderer.autoClearDepth = false;
HTML_container.appendChild( THREED_Renderer.domElement );

const THREED_Composer = new THREE.EffectComposer( THREED_Renderer );

// normal renderpass for basic scene:
const THREED_RenderPass = new THREE.RenderPass( THREED_Scene, THREED_Camera );
THREED_RenderPass.clear = false;
THREED_RenderPass.clearColor = false;
THREED_RenderPass.clearDepth = false;
THREED_RenderPass.renderToScreen = true;

// renderpass for scene with one pink cube in the middle of the scene
const THREED_RenderPassGlow = new THREE.RenderPass( THREED_SceneGlow, THREED_Camera );
THREED_RenderPassGlow.renderToScreen = true;
THREED_RenderPassGlow.clear = false;
THREED_RenderPassGlow.clearColor = false;
THREED_RenderPassGlow.clearDepth = false;

THREED_Composer.addPass( THREED_RenderPass );
THREED_Composer.addPass( THREED_RenderPassGlow );

Whatever I do, the composer always shows the last render pass and ONLY the last renderpass.
I do not understand why this is the case. It seems like the clear or autoclear properties do not work at all.

/cc

So, since I found no good documentation (just minified examples without comments), I guess I need to have to write this myself.

New plan:

  • Render normal scene
  • Save color buffer somewhere (?) as a copy
  • Clear color buffer but keep depth buffer
  • Render bloom scene
  • Apply bloom
  • Blend the previously saved color buffer

But how do I save the color buffer? And how do I mix it with the EffectComposer?

The source code of this example does precisely what you are trying to achieve

https://threejs.org/examples/#webgl_postprocessing_unreal_bloom_selective

Hi @drcmda

The issue with the first approach is that the render order of the non-glowing elements seem to be taking precedence always. The non-glowing elements are always drawn above their glowy counterpart.

Is there a way to fix this. So that the depth of each object is preserved.

Is that what you meant when you said that that “if you could get away with it” ? :smiley:

https://codesandbox.io/s/r3f-selective-bloom-7mfqw

Thanks!

@Mugen87 and everyone Hey, hope you’re well - I implemented a selective bloom for my scene. I set up a simple animation to rotate the bloomed object in the render function, which works fine by itself, but when I use the Orbit Control to look at the object from a different angle, the performance decreases from 55 FPS to about 10-15 FPS, thus creating visual lags.

So, the rotation & selective bloom by themselves is fine, and the orbit control angle changes + selective bloom is fine too. But all three together really seem to cause some havoc.

Would anyone know why exactly that might be? I understand that the bloom effect and other post processing libraries essentially “paint” over the initial scene a duplicate scene with the intended effect, but I am not sure if the performance issues I am encountering are to be expected or are related to my code.

Please let me know if I should share a fiddle.