Bloom on renderTarget

Hi guys,
I am actually trying to add a bloom effect to one of my renderTarget’s with R3F,
I actually got this error: Cannot read properties of undefined (reading ‘mask’)
The error seems to come from => composer.render();

Here the logic I use:

const myApp = () => {
  const { gl, scene, camera, size } = useThree();

  const renderTarget0 = useFBO(
    viewport.width * (isTouchDevice() ? touchDeviceDPR : noneTouchDeviceDPR),
    viewport.height * (isTouchDevice() ? touchDeviceDPR : noneTouchDeviceDPR),
    {
      stencilBuffer: false,
      alpha: true,
      samples: 4,
    },
  );

  const renderTarget1 = useFBO(
    viewport.width * (isTouchDevice() ? touchDeviceDPR : noneTouchDeviceDPR),
    viewport.height * (isTouchDevice() ? touchDeviceDPR : noneTouchDeviceDPR),
    {
      stencilBuffer: false,
      alpha: false,
      samples: 4,
    },
  );

  const firstCameraRef = useRef();

  // setup composer & effects
  const [composer, savePass] = useMemo(() => {
    const composer = new EffectComposer(gl, {
      frameBufferType: THREE.HalfFloatType,
    });
    const renderPass = new RenderPass(scene, camera);
    const targetRenderPass = new RenderPass(scene, firstCameraRef);
    const savePass = new SavePass(renderTarget0);

    const BLOOM = new BloomEffect({
      luminanceThreshold: 0.3,
      luminanceSmoothing: 0.1,
    });

    const effectPass = new EffectPass(camera, BLOOM);

    composer.addPass(targetRenderPass);
    composer.addPass(savePass);
    composer.addPass(renderPass);
    composer.addPass(effectPass);
    return [composer, savePass];
  }, [camera, gl, scene, firstCameraRef]);

  useFrame(({ gl, scene, camera }, delta) => {
    gl.autoClear = true;

    if (buddyRef.current != undefined) {
      buddyRef.current.visible = false;
    }
    if (renderScene0.current.render) {
      //... hide & show what i need to see
      gl.setRenderTarget(renderTarget0);
      gl.render(scene, firstCameraRef.current);

      composer.render();
    }

    if (renderScene1.current.render) {
      // ... hide & show what i need to see
      gl.setRenderTarget(renderTarget1);
      gl.render(scene, secondCameraRef.current);
    }



    finalDisplayRef.current.visible = true;
    gl.setRenderTarget(null);
    gl.autoClear = false;
  });

  return(
<>
      <PerspectiveCamera
        ref={firstCameraRef}
        makeDefault={false}
        position={[0, 239.89, 30.679]}
        rotation={[0, 0, 0]}
        near={1}
        far={400}
      />

      <OrthographicCamera
        ref={finalCameraRef}
        makeDefault={true}
        position={[0, 0, 1]}
        near={0}
        far={1}
      />


      <mesh
        position={[0, 0, 0]}
        scale={[viewport.width, viewport.height, 1]}
        ref={finalDisplayRef}
      >
        <planeGeometry />
        <GradientFbmMaterial
          color={"white"}
          /" Here i try to pass my "bloomed" texture to do some fancy transitions with glsl */
          uTex0={savePass.texture}
          uTex1={renderTarget1.texture}
          uResolution={
            new THREE.Vector2(
              viewport.width *
                (isTouchDevice() ? touchDeviceDPR : noneTouchDeviceDPR),
              viewport.height *
                (isTouchDevice() ? touchDeviceDPR : noneTouchDeviceDPR),
            )
          }
        />
      </mesh>
</>
)}

Thanks for your help

The error often means RenderPass or EffectPass is receiving an undefined camera. In your code, you do new RenderPass(scene, firstCameraRef) instead of firstCameraRef.current. Because useRef() starts as { current: undefined }, the pass camera is undefined, causing the “mask” error when composer.render() runs.
To fix:

  1. Use the actual camera object:
const targetRenderPass = new RenderPass(scene, firstCameraRef.current);
  1. Initialize composer after the ref is set (e.g. in a useEffect that depends on firstCameraRef.current), or check for firstCameraRef.current before creating passes.
  2. Use the same approach for EffectPass (e.g. new EffectPass(firstCameraRef.current, BLOOM) if you want the bloom effect on that camera).

Also verify that you’re calling composer.render() only after setting gl.setRenderTarget(...). If the camera is valid but you still get errors, ensure all passes and references (e.g. scene, gl) are consistent.

It’s work! Thank you Heojunfo <3 !