Hi guys
I am struggling in getting a selective bloom (maybe I am using the wrong tool for the job or I misunderstood how it works…).
What I want to achieve:
Model blooming the same color as the emissive texture (without manually setting it, so the color is taken straight from the emissive image) AND the rest of the model not blooming.
What I achieved instead:
The full model is blooming and is blooming white not the color of the emissive texture.
As you can see the full model is glowing and is glowing white (I know I set it to 255,255,255 but it seems to make almost no different to set it to another color, not to mention I can’t rely on that I need to rely on the emissive texture color to bloom, what if the texture has two parts where it needs to emit two different colors? setting the emissive color in RGB value won’t be an option…)
As you can see the emissive texture is black and green as desired:
We have models with some separate 3d meshes so that we can (or we thought we could easily) make things selectively bloom…
What I tried (code is not prod ready is just a messy mess trying to achieve the objective):
I tried setting a userData
boolean (isEmissive
) and assigning to that a emissiveIntensity
import { useMemo, useRef, useState } from 'react';
import { useGLTF } from '@react-three/drei';
import { Bloom, EffectComposer, SelectiveBloom } from '@react-three/postprocessing';
import { Resizer, KernelSize } from 'postprocessing';
const ModelViewer = ({ model }) => {
const glb = useGLTF(`./../game/3dModels/${model}.glb`);
const clone = useMemo(() => glb.scene.clone(), [glb]);
const bloomRef = useRef();
const lightRef = useRef();
const lightRef2 = useRef();
useMemo(() => {
const { scene } = glb;
scene.traverse((node) => {
if (node.isMesh) {
const isEmissive = node.userData.isEmissive;
console.log({
name: node.name,
emissive: node.userData.isEmissive,
userData: node.userData,
});
node.castShadow = true;
node.receiveShadow = true;
if (isEmissive) {
node.material.emissiveIntensity = 1;
// TODO: fix this as it needs to come from the emissive texture
node.material.emissive = {
r: 255,
g: 255,
b: 255,
};
} else {
node.material.emissiveIntensity = 0;
}
}
console.log({ node });
});
}, [glb]);
return (
<>
<hemisphereLight ref={lightRef} intensity={0.5} position={[5, 10, 50]} />
<ambientLight ref={lightRef2} intensity={0.5} position={[-5, 1, -10]} />
<primitive object={clone} scale={0.8} ref={bloomRef} />
<EffectComposer>
{/* <Bloom
intensity={1}
luminanceThreshold={0.9} // luminance threshold. Raise this value to mask out darker elements in the scene.
luminanceSmoothing={0.05} // smoothness of the luminance threshold. Range is [0, 1]
height={Resizer.AUTO_SIZE}
width={Resizer.AUTO_SIZE}
/> */}
<SelectiveBloom
lights={[lightRef, lightRef2]} // ⚠️ REQUIRED! all relevant lights
// selectionLayer={23} // selection layer
selections={[bloomRef]}
intensity={0.2} // The bloom intensity.
width={Resizer.AUTO_SIZE} // render width
height={Resizer.AUTO_SIZE} // render height
kernelSize={KernelSize.SMALL} // blur kernel size
luminanceThreshold={0.2} // luminance threshold. Raise this value to mask out darker elements in the scene.
luminanceSmoothing={0.9} // smoothness of the luminance threshold. Range is [0, 1]
/>
</EffectComposer>
</>
);
};
export default ModelViewer;
I also tried to separate the isEmissive meshes and selectively put JUST them in the in the selections
prop of the SelectiveBloom but it didn’t work either.
Any help is welcome…