Bug in SelectiveBloom on destroying

I have integrated the SelectiveBloom example from the postprocessing library (6.36.0) into an app, and while it runs correctly when viewing, it throws an error every time I navigate away from the page. There seems to be a bug in the SelectiveBloom destroy.
Specifically, the error only happens when viewing the widget and hovering over one of the cubes first, and then you navigate away.

The integrated widget code is nothing special:

export default function App() {
  const [hovered, onHover] = useState(null);
  const selected = hovered ? [hovered] : undefined;
  const lightRef = useRef<any>();

  return (
    <Canvas dpr={[1, 2]}>
      <ambientLight intensity={5.0} ref={lightRef} />
      <Box onHover={onHover} position={[-1, 0, 0]} />
      <Box onHover={onHover} position={[1, 0, 0]} />
      <EffectComposer multisampling={8} autoClear={false}>
        <SelectiveBloom
          selection={selected}
          intensity={2.0}
          luminanceThreshold={0.01}
          luminanceSmoothing={0.025}
          lights={[lightRef]}
        />
      </EffectComposer>
    </Canvas>
  );
}

The stack trace of the error reveals the issue comes from safelyCallDestroy:

Cannot read properties of null (reading 'layers')
TypeError: Cannot read properties of null (reading 'layers')
    at removeLight (http://localhost:3000/static/js/bundle.js:183022:46)
    at http://localhost:3000/static/js/bundle.js:183075:33
    at Array.forEach (<anonymous>)
    at http://localhost:3000/static/js/bundle.js:183075:16
    at safelyCallDestroy (http://localhost:3000/static/js/bundle.js:114233:9)
    at commitHookEffectListUnmount (http://localhost:3000/static/js/bundle.js:114368:15)
    at commitPassiveUnmountInsideDeletedTreeOnFiber (http://localhost:3000/static/js/bundle.js:116109:15)
    at commitPassiveUnmountEffectsInsideOfDeletedTree_begin (http://localhost:3000/static/js/bundle.js:116065:9)
    at commitPassiveUnmountEffects_begin (http://localhost:3000/static/js/bundle.js:115987:15)
    at commitPassiveUnmountEffects (http://localhost:3000/static/js/bundle.js:115975:7)

Upon inspection of the SelectiveBloom code, I think a null check is missing here line 7-8:

...
const addLight = (light, effect) => light.layers.enable(effect.selection.layer);
const removeLight = (light, effect) => light.layers.disable(effect.selection.layer);

const SelectiveBloom = forwardRef(function SelectiveBloom2({
 ...

I’m fairly sure this is a bug… or am i doing something wrong in the use of this component?

SelectiveBloom is deprecated, bloom is selective out of the box and you don’t need anything more than this

<Bloom mipmapBlur luminanceThreshold={1} />

// ❌ will not glow, same as RGB [1,0,0]
<meshStandardMaterial color="red"/>

// âś… will glow, same as RGB [10,0,0]
<meshStandardMaterial emissive="red" emissiveIntensity={10} toneMapped={false} />

// ❌ will not glow, same as RGB [1,0,0]
<meshBasicMaterial color="red" />

// ❌ will not glow, same as RGB [1,0,0], tone-mapping will clamp colors between 0 and 1
<meshBasicMaterial color={[10,0,0]} />

// âś… will glow, same as RGB [10,0,0]
<meshBasicMaterial color={[10,0,0]} toneMapped={false} />

https://codesandbox.io/p/sandbox/bloom-hdr-workflow-gnn4yt

1 Like

Awesome, thanks. I hadn’t realised SelectiveBloom was deprecated - I’m new to three and postprocessing, and it wasn’t clear from the documentation that there was a better way. Thanks again!

1 Like