In my project I want to display 3d objects which sometimes have small LED lights. The idea is, that these small lights need to be emitting some kind of bloom to make it look like they are glowing.
I've tried to apply the UnrealBloom however it is considered for the entire scene and not just for the parts that have the actual emission value (using an emission texture map).. the scene gets very blurry as well.
This is obviously not what I wanted. I only need the little red LED light bulp to glow not the entire object. However I have not yet found a way to tell the engine to only apply the bloom to where the emission map is pointing at.
I'm using a very simple code setup which is almost the same as the UnrealBloom Example:
How can I setup the emission texture correctly and make only the emissive parts of the object glow and prevent the unrealistically shiny surfaces and very blurry visuals?
UPDATE: Editable example of my setup is now available on JSFiddle!
<body style="margin:0px; overflow:hidden;">
<div id="bloom-solution">
<div id="body">
<h2 id="info" style="
color: rgb(255,255,255);
position: fixed;
top: 45%;
left: 50%;
transform: translate(-50%, -50%);
">loading scene, this might take a few seconds..</h2>
<script type="x-shader/x-vertex" id="vertexshader">
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>
<script type="x-shader/x-fragment" id="fragmentshader">
uniform sampler2D baseTexture;
uniform sampler2D bloomTexture;
varying vec2 vUv;
void main() {
gl_FragColor = ( texture2D( baseTexture, vUv ) + vec4( 1.0 ) * texture2D( bloomTexture, vUv ) );
}
</script>
<script type="module">
import * as THREE from 'https://threejs.org/build/three.module.js'
import { OrbitControls } from 'https://threejs.org/examples/jsm/controls/OrbitControls.js'
import { GLTFLoader } from 'https://threejs.org/examples/jsm/loaders/GLTFLoader.js'
import { RGBELoader } from 'https://threejs.org/examples/jsm/loaders/RGBELoader.js'
import { EffectComposer } from 'https://threejs.org/examples/jsm/postprocessing/EffectComposer.js';
import { RenderPass } from 'https://threejs.org/examples/jsm/postprocessing/RenderPass.js';
import { UnrealBloomPass } from 'https://threejs.org/examples/jsm/postprocessing/UnrealBloomPass.js';
// RESOURCES ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
const COLOR_TEXTURE = "https://cdn.jsdelivr.net/gh/MigerRepo/bloom-solution/RecordPlayer_Color.jpeg"
const METALNESS_TEXTURE = "https://cdn.jsdelivr.net/gh/MigerRepo/bloom-solution/RecordPlayer_Metalness.jpeg"
const EMISSION_TEXTURE = "https://cdn.jsdelivr.net/gh/MigerRepo/bloom-solution/RecordPlayer_Emission.jpeg"
const ALPHA_TEXTURE = "https://cdn.jsdelivr.net/gh/MigerRepo/bloom-solution/RecordPlayer_Alpha.jpeg"
const TURNTABLE_MODEL = "https://cdn.jsdelivr.net/gh/MigerRepo/bloom-solution/turntable_a111.glb"
const HDRI_MAP = "https://cdn.jsdelivr.net/gh/MigerRepo/bloom-solution/forest.hdr"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function $(e){return document.getElementById(e)}
const container = document.createElement( 'div' )
document.body.appendChild( container )
const scene = new THREE.Scene()
scene.background = new THREE.Color( new THREE.Color("rgb(250,244,227)") )
scene.fog = new THREE.Fog( new THREE.Color("rgb(100, 100, 100)"), 10, 50 )
const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 1000 )
camera.position.set( 7, 3, 7 )
const renderer = new THREE.WebGLRenderer( { antialias: true } )
renderer.setPixelRatio( window.devicePixelRatio )
renderer.setSize( window.innerWidth, window.innerHeight )
renderer.toneMapping = THREE.ACESFilmicToneMapping
renderer.outputEncoding = THREE.sRGBEncoding
renderer.shadowMap.enabled = true
renderer.shadowMap.type = THREE.PCFSoftShadowMap
container.appendChild( renderer.domElement )
const controls = new OrbitControls( camera, renderer.domElement )
controls.minDistance = 1
controls.enablePan = true
controls.enableZoom = true;
controls.enableDamping = true
controls.dampingFactor = 0.1
controls.rotateSpeed = 0.5
const directionalLight = new THREE.DirectionalLight( new THREE.Color("rgb(255, 255, 255)"), 1 )
directionalLight.castShadow = true
directionalLight.shadow.camera.top = 4
directionalLight.shadow.camera.bottom = - 4
directionalLight.shadow.camera.left = - 4
directionalLight.shadow.camera.right = 4
directionalLight.shadow.camera.near = 0.1
directionalLight.shadow.camera.far = 40
directionalLight.shadow.camera.far = 40
directionalLight.shadow.bias = - 0.002
directionalLight.position.set( 0, 20, 20 )
directionalLight.shadow.mapSize.width = 1024*4
directionalLight.shadow.mapSize.height = 1024*4
scene.add( directionalLight )
scene.add( new THREE.CameraHelper( directionalLight.shadow.camera ) )
var gltfLoader
var model
var mesh
const pmremGenerator = new THREE.PMREMGenerator( renderer )
pmremGenerator.compileEquirectangularShader()
new RGBELoader().setDataType( THREE.UnsignedByteType ).load( HDRI_MAP, function ( texture ) {
const envMap = pmremGenerator.fromEquirectangular( texture ).texture
scene.environment = envMap
texture.dispose()
pmremGenerator.dispose()
gltfLoader = new GLTFLoader()
gltfLoader.load( TURNTABLE_MODEL, function ( gltf ) {
model = gltf.scene
model.position.y = 1
model.traverse( function ( child ) {
if ( child.isMesh ) {
mesh = child
child.castShadow = true
child.receiveShadow = true
child.material.transparent = true
child.material.envMapIntensity = 1
$("info").style.display = "none";
}
} );
model.scale.set(15,15,15)
scene.add( model )
animate()
} )
});
const animate = function () {
requestAnimationFrame( animate )
controls.update()
renderer.render( scene, camera )
};
window.addEventListener( 'resize', function () {
const width = window.innerWidth
const height = window.innerHeight
renderer.setSize( width, height )
camera.aspect = width / height
camera.updateProjectionMatrix()
} )
</script>
</div>
</div>
</body>