Pmndrs Post Processing: Selective Bloom renders differently on Chrome vs Firefox

This is a question concerning the usage of the pmndrs postprocessing library. In my scene, I have loaded an HDRI and a model of a car. Id like to implement selective bloom in order to mimic the glow of the brake lights. I added the red light bulb mesh to the bloom effect using the following line:


This allowed the object to bloom but I noticed that the whole HDRI background is blooming like crazy. I did some digging and people proposed that I increase the threshold to a high value so that nothing blooms, and then push colors on materials I want to bloom over the threshold. So that’s what I did, heres the material of the brake lights which I assign to the mesh “lights_rear_bulb”

    const brakeLightMaterial = new THREE.MeshBasicMaterial( {
          toneMapped: false,
          color: new THREE.Color().setRGB(400, 0, 0)

And heres the setup of the bloom:

    const bloomEffect = new SelectiveBloomEffect(scene, camera, {
        intensity: 10,
        mipmapBlur: true,
        luminanceThreshold: 50, 
        luminanceSmoothing: 0.25,
        radius: 0.2,
        resolutionScale: 4,

So the threshold is 50, but I noticed that if I push the red color to 51 or 60, no bloom was happening, only until I reached 400 was the bloom effect present. Am i doing this right? Or does anyone have another recommended method of achieving what im trying to achieve: basically, having bloom ONLY for the mesh “lights_rear_bulb”
My main question has to do with the fact that im getting different results on different browsers. The mesh “lights_rear_bulb” is behind a mesh called “lights_rear_glass” which represents the glass cover of the rear lights. The bloom effect passes through it when I use Chrome or Edge, but it gets blocked when I use Firefox. I’ve added images for clarification. Any idea whats happening there? Is there other big differences I should be aware of when it comes to these popular browsers?

I created a simple scene to try and find the issue, I would appreciate if people from the community would give me feedback on their thoughts and observations.

The scene has to cubes: one green non-blooming cube and one red blooming cube. The bottom half of the scene is covered by a glass plane. This mimics the scenario of rendering the brake lights of a car.
My goal is to have the blooming of the red cube pass through the glass plane, and also to have the same results across all browsers. At the moment, I am not getting the same results on chrome and firefox, and for both of them, the blooming is not passing through the glass. I have included two ways to define the red cube: either through the emissive method, or through the color method. I have also included a commented line which includes the glass cover in the bloom pass. If you uncomment this line, the bloom passes through the glass on chrome but not on firefox. I am curious to hear your thoughts, thanks in advance! :smiley:


<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8" />
      content="width=device-width, initial-scale=1.0"
    <title>Three.js Two Cubes</title>
      body {
        margin: 0;

        <script type="importmap">
            "imports": {
            "three": "",
            "three/addons/": "",
			"postprocessing": ""

		<script type="module" src="/pmndrsBloomTest3.js"></script>


//Imports for standard Threejs
import * as THREE from "three";

//Imports for pmndrs post processing library
import { 
} from "three";

import {
} from "postprocessing";

// // // // // Create scene
const scene = new THREE.Scene();

// // // // // Create glass cover 
var coverMaterial = new THREE.MeshPhysicalMaterial( {
    color: 0xffffff, metalness: 0, roughness: 0, transmission: 0.99
  } );
var planeGeometry = new THREE.PlaneGeometry(10, 5); // You can adjust the size as needed
var coverPlane = new THREE.Mesh(planeGeometry, coverMaterial);
coverPlane.position.y = -2.3; // Half of the plane's height
coverPlane.position.z = 1

// // // // // Create red cube (GLOWING)
const redGeometry = new THREE.BoxGeometry();

// // Glowing Material: Color Method
// const redMaterial = new THREE.MeshBasicMaterial( {
//     toneMapped: false,
//     color: new THREE.Color().setRGB(400, 0, 0)
//   });

// // Glowing Material: Emissive Method
const redMaterial = new THREE.MeshStandardMaterial({
    toneMapped: false,
    emissive: "red",
    emissiveIntensity: 400

const redCube = new THREE.Mesh(redGeometry, redMaterial);
redCube.position.x = -2; // Position to the left

// // // // // Create green cube (NON-GLOWING)
const greenGeometry = new THREE.BoxGeometry();
const greenMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const greenCube = new THREE.Mesh(greenGeometry, greenMaterial);
greenCube.position.x = 2; // Position to the right

// // // // // Create camera
const camera = new THREE.PerspectiveCamera(
  window.innerWidth / window.innerHeight,
camera.position.z = 5;

// // // // // Create renderer
const renderer = new WebGLRenderer({
  powerPreference: "high-performance",
  antialias: false,
renderer.setSize(window.innerWidth, window.innerHeight);

// // // // // Create Effects

// // Bloom
const bloomEffect = new SelectiveBloomEffect(scene, camera, {
    intensity: 10,
    mipmapBlur: true,
    luminanceThreshold: 50, // had to increase in order to keep out blooming from hdri
    luminanceSmoothing: 0.25,
    radius: 0.2,
    resolutionScale: 4,


// Try adding this line

// // Tone-Mapping
const TMeffect = new ToneMappingEffect({
    blendFunction: BlendFunction.NORMAL,
    mode: ToneMappingMode.ACES_FILMIC,
    resolution: 256,
    whitePoint: 4.0,
    middleGrey: 0.6,
    minLuminance: 0.01,
    averageLuminance: 0.01,
    adaptationRate: 1.0

const TMeffectPass = new EffectPass(camera, TMeffect);

// // // // // Create Composer
const composer = new EffectComposer(renderer, {
    multisampling: Math.min(4, renderer.capabilities.maxSamples),
    frameBufferType: HalfFloatType

composer.addPass(new RenderPass(scene, camera));
composer.addPass(new EffectPass(camera, bloomEffect));

// // // // // Animation function
const animate = () => {

  // Rotate cubes
  redCube.rotation.x += 0.01;
  redCube.rotation.y += 0.01;
  greenCube.rotation.x += 0.01;
  greenCube.rotation.y += 0.01;

  composer.render(scene, camera);

// Handle window resize
window.addEventListener("resize", () => {
  const newWidth = window.innerWidth;
  const newHeight = window.innerHeight;

  camera.aspect = newWidth / newHeight;

  composer.setSize(newWidth, newHeight);

// Start animation