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!
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
<title>Three.js Two Cubes</title>
<style>
body {
margin: 0;
}
</style>
</head>
<body>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.150.0/build/three.module.js",
"three/addons/": "https://unpkg.com/three@0.150.0/examples/jsm/",
"postprocessing": "https://unpkg.com/postprocessing@6.33.3/build/index.js"
}
}
</script>
<script type="module" src="/pmndrsBloomTest3.js"></script>
</body>
</html>
pmndrsBloomTest3.js:
//Imports for standard Threejs
import * as THREE from "three";
//Imports for pmndrs post processing library
import {
WebGLRenderer,
HalfFloatType
} from "three";
import {
SelectiveBloomEffect,
BlendFunction,
EffectComposer,
EffectPass,
RenderPass,
ToneMappingEffect,
ToneMappingMode,
} 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
scene.add(coverPlane);
// // // // // 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
scene.add(redCube);
// // // // // 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
scene.add(greenCube);
// // // // // Create camera
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000,
);
camera.position.z = 5;
// // // // // Create renderer
const renderer = new WebGLRenderer({
powerPreference: "high-performance",
antialias: false,
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// // // // // 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,
});
bloomEffect.selection.add(redCube);
// Try adding this line
//bloomEffect.selection.add(coverPlane);
// // 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));
composer.addPass(TMeffectPass);
// // // // // Animation function
const animate = () => {
requestAnimationFrame(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;
camera.updateProjectionMatrix();
composer.setSize(newWidth, newHeight);
});
// Start animation
animate();