Bloom produces moving black patches

Adding <Bloom> to an otherwise working `EffectComposer` chain fills large parts of the frame with black. The black regions are not static, they move and change shape as the camera orbits Removing `` makes them disappear completely.

**Versions**

- `three` 0.171.0

- `@react-threereact-threereact-threact-threereact-threereact-th@react-three.18.0ee@react-three.18.0ea@react-threet-three/fiber` @react-three.18.0

- `@react-three/postprocessing` 2.19.1

- `postprocessing` 6.37.7

- Chrome, WebGL2, Windows 11

**Symptoms**

- Present immediately on load

- Moves/changes with camera orientation

- **Not** affected by window resize

- Changing Bloom’s `intensity`, `luminanceThreshold`, `luminanceSmoothing` or `radius` does not help at any value

- Disabling the `N8AO` pass makes no difference, so it is not an interaction with that

**What I think is happening (would appreciate a sanity check)**

The scene has a skybox sphere textured with a large HDR `.exr`, using `toneMapped={false}`:

const texture = useLoader(EXRLoader, '/Texture/sky.exr');




<mesh rotation-y={-Math.PI / 2}>

  <sphereGeometry args={[radius, 32, 32]} />

  <meshBasicMaterial side={THREE.BackSide} map={texture} color={[0.5, 0.5, 0.5]} toneMapped={false} />

</mesh>

The EXR carries raw radiance, and the sun region in it goes well above the 65504 limit of the half-float frame buffer that `EffectComposer` uses by default. Nothing brings it down before the composer: I set `toneMapping: THREE.ACESFilmicToneMapping` on the canvas, but `EffectComposer` sets `gl.toneMapping = NoToneMapping` while mounted and expects a `` effect in the chain instead, which I dont currently have.

So my guess is those texels reach Bloom as `Inf`, and somewhere in the mipmap blur (a `mix`/lerp between mip levels, `Inf - Inf`, or `Inf * 0`) they turn into `NaN`. That would explain the shape of the artifact: the blur chain downsamples to very small mips, so a single bad texel at the bottom smears across a huge screen area when upsampled, with the blocky edges of a low-res mip.

The camera dependence fits too, orbiting brings different (brighter) parts of the sky into view. The resize independence fits, since resizing doesn’t change which texels are in frame.

**Chain**

<EffectComposer multisampling={0} enableNormalPass>

  <N8AO {...aoProps} />

  <Bloom

    intensity={1}

    luminanceThreshold={1}

    luminanceSmoothing={1}

    radius={0.25}

  />

  <Vignette eskil={true} offset={0.75} darkness={1} />

  <SMAA />

</EffectComposer>

**What I tried**

A small `Effect` inserted immediately before `` to fold non-finite values back into range:



import { forwardRef, useMemo } from 'react';

import { BlendFunction, Effect } from 'postprocessing';

import { Uniform } from 'three';




const fragment = `

uniform float ceiling;




// NaN fails every comparison, so a component that is neither below the ceiling

// nor at/above it can only be NaN. Inf settles at the ceiling.

float sanitize(const in float x) {

  return (x < ceiling) ? max(x, 0.0) : ((x >= ceiling) ? ceiling : 0.0);

}




void mainImage(const in vec4 src, const in vec2 uv, out vec4 dst) {

  dst = vec4(sanitize(src.r), sanitize(src.g), sanitize(src.b), src.a);

}`;




class ClampHDREffect extends Effect {

  constructor(ceiling) {

    super('ClampHDREffect', fragment, {

      // SRC returns the effect output verbatim. Other blend functions route the

      // input through mix(), and mix() with an Inf input yields NaN again.

      blendFunction: BlendFunction.SRC,

      uniforms: new Map([['ceiling', new Uniform(ceiling)]]),

    });

  }

}




const ClampHDR = forwardRef(({ ceiling = 64 }, ref) => {

  const effect = useMemo(() => new ClampHDREffect(ceiling), [ceiling]);

  return <primitive ref={ref} object={effect} />;

});




export default ClampHDR;

Used as:

<ClampHDR />

<Bloom intensity={1} luminanceThreshold={1} luminanceSmoothing={1} radius={0.25} />

Did not work, added this here so that you know that I have tried this already.

I haven’t seen this happen before. Can you make a repro in a codepen or similar?

i think I remember seeing this in a setup I used before, I may be wrong but I recall it being related to the camera far parameter, do you have the camera far set to an insanely large distance? Other things to give a try…

have you tried setting multisampling to anything other than 0?

have you tried using mipmapBlur…

<Bloom
    mipmapBlur

as well as commenting out the radius parameter.

have you tried halfFloatType on the effect composer…

<EffectComposer frameBufferType={HalfFloatType}>