I still don't get how UnrealBloomPass works

I can have UnrealBloomPass working in my Three.JS/React Three Fiber experiments, but I’m not fully understanding the logic behind what will glow and what won’t.

Playground link (R3F)

  • What is the relation between bloom pass threshold, emissive color and emissive intensity? Why does blue need a waaay lower threshold / higher intensity than red to glow?
  • Can we keep the original color on the mesh instead of going towards white?
  • What does tone mapping change for emissive materials?
2 Likes

What SHOULD happen here is that a surface begins creating a bloom when its luminance (here meaning, roughly, perceived brightness) exceeds the threshold. Luminance is a weighted sum of linear RGB values, where each component (red/green/blue) has a different weight based on how the human eye perceives that color’s brightness. Typical weights for each component are {0.2126, 0.7152, 0.0722}, applied to Linear-sRGB values, so you might expect to need linear emissive values around 2-10x higher than the threshold, assuming no other light reflects from the surface.

However, that’s not happening in your demo, which I think indicates bugs or version incompatibilities that may need to be tracked down in some combination of the three, three-stdlib, and drei packages… It appears that gamma is being applied before the bloom effect, which means the input colors to the bloom are non-linear, and your threshold is effectively an arbitrary order of magnitude higher than it should be. With that bug happening, it’s guesswork what inputs will trigger bloom. Setting disableGamma={true} on the <Effects /> component seems to help.

Can we keep the original color on the mesh instead of going towards white?

This is an effect of most tone-mapping implementations. If you add the flat attribute to your <Canvas /> component you can disable tone-mapping and prevent it, but this will affect the entire scene. Because bloom is a screen space effect, disabling tone mapping per material does not help here. Usually this desaturation to white is a good thing (look at any image of lightsabers, for example!) but you could also write custom tonemapping to avoid it.

What does tone mapping change for emissive materials?

Tone mapping does not need to be disabled for emissive materials, if that’s what you mean. In general, disable tone mapping if something is already a “fully formed image”, like UI elements overlaying the scene in a HUD, or perhaps a video element playing within the scene.

We do want to delay tone mapping and linear-to-sRGB conversion until after bloom. Your OutputPass is in the correct place for that. The OutputPass step is sometimes called “image formation” because it turns linear RGB [0, ∞] data (good for HDR effects) into an image (good for a human viewer).

Also see:

3 Likes

Here is at least part of the cause:

^This was a good default in older versions of three.js, but because newer versions feature OutputPass (which includes both tone mapping and gamma correction) it’s better to disable this step with <Effects disableGamma={true}. I would guess that future Drei versions might change this behavior.

Filed a ticket:

Thank you @donmccurdy , that is valuable information there. How could one learn about Post Processing? The Three.JS example section is rich with… examples, but the explanation is pretty sparse. Also I guess that this is not Three.js specific, but related to computer graphics in general, am I wrong?