Trying to implement github bloom

Hello,
Trying to implement bloom in three js using three.js/webgl_postprocessing_unreal_bloom_selective.html at 191a1ef699a5d53de2cd645c667e7fee184a18fd · mrdoob/three.js · GitHub

I’m getting a large red plane in front with black everywhere else , or, if finalComposer.addPass( finalPass ); is disabled, it just looks normal, without any bloom effect.
Is there a minimum three js version needed? I believe I’m using 129.
Thank you,
Jim

Here are the links to the failed and working screenshots:
normal view, with bloom off: https://scontent-lga3-1.xx.fbcdn.net/v/t39.30808-6/291789922_10220929781941029_8123652435574873713_n.jpg?_nc_cat=108&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=LN3CISKowAgAX9qWE4J&tn=i8S_vLP6o8fXBrEm&_nc_ht=scontent-lga3-1.xx&oh=00_AT9QFOagZlPGgUpflExR4gIQVyX4yoflCRT6qu3TjclzVw&oe=62C741A8

fail to red and black, with bloom on: https://scontent-lga3-1.xx.fbcdn.net/v/t39.30808-6/291171692_10220929760420491_7843779091932940070_n.jpg?_nc_cat=100&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=LoayV9RA3iwAX85zlWf&_nc_ht=scontent-lga3-1.xx&oh=00_AT-5dB4pF9U7WAmZrwrzl6cdfaYLpzHkRNxCC2C8UxONMg&oe=62C81FE7

Below is the relevant code, using a php cache and window vars since render, animate, renderBloom and other functions are loaded first in this case. Don’t use orbit controls here.

// Tween.js script here - doesn't show correctly
// script type="module" - doesn't show correctly
$cache .= 'import * as THREE from "../three.js/build/three.module.js";';  // CURRENT, working
$cache .= 'import { VRButton } from "../three.js/examples/jsm/webxr/VRButton.js";';  // CURRENT, working
$cache .= 'import { XRControllerModelFactory } from "../three.js/examples/jsm/webxr/XRControllerModelFactory.js";';  // CURRENT, working
$cache .= 'import { XRHandModelFactory } from "../three.js/examples/jsm/webxr/XRHandModelFactory.js";';  // CURRENT, working
$cache .= 'import {GLTFLoader} from "../three.js/examples/jsm/loaders/GLTFLoader.js";';  // CURRENT, working
$cache .= 'import {OBJLoader} from "../three.js/examples/jsm/loaders/OBJLoader.js";';  // CURRENT, working
$cache .= 'import {MTLLoader} from "../three.js/examples/jsm/loaders/MTLLoader.js";';  // CURRENT, working

// bloom, new
if ($bloom_strength) {
//$cache .= 'import Stats from "../three.js/examples/jsm/libs/stats.module.js";';
$cache .= 'import { GUI } from "../three.js/examples/jsm/libs/dat.gui.module.js";';
$cache .= 'import { EffectComposer } from "../three.js/examples/jsm/postprocessing/EffectComposer.js";';
//$cache .= 'import { EffectComposer } from "https://threejs.org/examples/jsm/postprocessing/EffectComposer.js";';
$cache .= 'import { RenderPass } from "../three.js/examples/jsm/postprocessing/RenderPass.js";';
$cache .= 'import { ShaderPass } from "../three.js/examples/jsm/postprocessing/ShaderPass.js";';
$cache .= 'import { UnrealBloomPass } from "../three.js/examples/jsm/postprocessing/UnrealBloomPass.js";';

$cache .= 'const ENTIRE_SCENE = 0, BLOOM_SCENE = 1;';  // orig

$cache .= 'window.bloomLayer = new THREE.Layers();';
$cache .= 'window.bloomLayer.set( BLOOM_SCENE );';

$cache .= 'const params = {';
$cache .= 'exposure: 1,';
$cache .= 'bloomStrength: '.$bloom_strength.',';
$cache .= 'bloomThreshold: 0,';
$cache .= 'bloomRadius: 0,';
$cache .= 'scene: "Scene with Glow"';
$cache .= '};';

$cache .= 'window.darkMaterial = new THREE.MeshBasicMaterial( { color: "black" } );';
$cache .= 'window.materials = {};';

}

// try
$cache .= 'window.GLTFLoader = GLTFLoader;';
$cache .= 'window.THREE = THREE;';
$cache .= 'window.OBJLoader = OBJLoader;';
$cache .= 'window.MTLLoader = MTLLoader;';
$cache .= 'window.VRButton = VRButton;';
$cache .= 'window.XRControllerModelFactory = XRControllerModelFactory;';
$cache .= 'window.XRHandModelFactory = XRHandModelFactory;';

// try save these also to window
if ($bloom_strength) {
$cache .= 'window.EffectComposer = EffectComposer;';
$cache .= 'window.RenderPass = RenderPass;';
$cache .= 'window.UnrealBloomPass = UnrealBloomPass;';
$cache .= 'window.bloomStrength = '.$bloom_strength.';';
}

...

// scene
$cache .= 'window.scene = new window.THREE.Scene();';
$cache .= 'window.scene.background = new window.THREE.Color( 0x444444 );';
$cache .= 'window.camera = new window.THREE.PerspectiveCamera( 80, window.innerWidth / window.innerHeight, 0.1, 1000 );';  // for outdoors

...

// renderer
$cache .= 'window.renderer = new window.THREE.WebGLRenderer({ antialias: true });';
$cache .= 'window.renderer.setPixelRatio( window.devicePixelRatio );';
$cache .= 'window.renderer.setSize( window.innerWidth, window.innerHeight );';
if ($bloom_strength)
$cache .= 'window.renderer.toneMapping = THREE.ReinhardToneMapping;';
$cache .= 'window.renderer.outputEncoding = window.THREE.sRGBEncoding;';
$cache .= 'window.renderer.xr.enabled = true;';
$cache .= 'window.renderer.xr.setFramebufferScaleFactor(2.0);';
$cache .= 'window.container.appendChild( window.renderer.domElement );';
}

...

// load object to bloom, cylinder in this case
} elseif ($entity_tag == 'a-cylinder' && $radius_vr && $height) {
$cache .= 'var geometry = new window.THREE.CylinderGeometry( '.$radius_vr.', '.$radius_vr.', '.$height.' );';
$cache .= 'var material = new window.THREE.MeshBasicMaterial( { color: 0x'.substr($color, 1).' } );';
$cache .= 'var mesh = new window.THREE.Mesh( geometry, material );';
if ($x)
$cache .= 'mesh.position.x = '.$x.';';
if ($y)
$cache .= 'mesh.position.y = '.$y.';';
if ($z)
$cache .= 'mesh.position.z = '.$z.';';
if ($r)
$cache .= 'mesh.rotation.x = '.deg2rad($r).';';
if ($ry)
$cache .= 'mesh.rotation.y = '.deg2rad($ry).';';
if ($rz)
$cache .= 'mesh.rotation.z = '.deg2rad($rz).';';
if ($entity_id)
$cache .= 'mesh.name = "'.$entity_id.'";';

if ($vr_parent) {
$cache .= 'var vrParentList = window.scene.getObjectByName("'.$vr_parent.'");';
$cache .= 'if(vrParentList) {';
$cache .= 'vrParentList.add(mesh);';
$cache .= '}';
} else
$cache .= 'window.scene.add( mesh);';
// try bloom here, new, try non-gltf, believe not working either
if ($door_bloom > 0) {
$cache .= 'mesh.layers.enable( BLOOM_SCENE );';
}
}

...

$cache .= set_up_rig($userid, $x, $y, $z, 'return', '', $threejs, $user_y, $user_ry, $vr_parent, $userid_2nd);
// call new fn; try skip js open; nc odd
$cache .= set_up_camera($userid, $x, $y, $z, 'return', $threejs, $http_prefix, $open_inline, $user_ry, $vr_parent, $userid_2nd);

if($bloom_strength) {
$cache .= 'const renderScene = new RenderPass( window.scene, window.camera );';

$cache .= 'const bloomPass = new UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 1.5, 0.4, 0.85 );';
$cache .= 'bloomPass.threshold = params.bloomThreshold;';
$cache .= 'bloomPass.strength = params.bloomStrength;';
$cache .= 'bloomPass.radius = params.bloomRadius;';

$cache .= 'window.bloomComposer = new EffectComposer( window.renderer );';
$cache .= 'window.bloomComposer.renderToScreen = false;';
$cache .= 'window.bloomComposer.addPass( renderScene );';
$cache .= 'window.bloomComposer.addPass( bloomPass );';
$cache .= 'const finalPass = new ShaderPass(';
$cache .= 'new THREE.ShaderMaterial( {';
$cache .= 'uniforms: {';
$cache .= 'baseTexture: { value: null },';
$cache .= 'bloomTexture: { value: window.bloomComposer.renderTarget2.texture }';
$cache .= '},';
$cache .= 'defines: {}';
$cache .= '} ), "baseTexture"';
$cache .= ');';
$cache .= 'finalPass.needsSwap = true;';
$cache .= 'window.finalComposer = new EffectComposer( window.renderer );';
$cache .= 'window.finalComposer.addPass( renderScene );';
// all red
$cache .= 'window.finalComposer.addPass( finalPass );';
}

$cache .= 'animate();';

// js fns

function animate() {
// test ok window.bloomStrength jsa35794: 10
//alert("window.bloomStrength jsa35794: " + window.bloomStrength);
window.renderer.setAnimationLoop( render );
}

function render() {

var indexTip2Pos = window.hand2.joints[ "index-finger-tip" ].position;
// carry out and tween move
if ( TWEEN) TWEEN.update();

// dolly (rig) move, new 2021-08-29 14:25:02 per https://stackoverflow.com/questions/62476426/webxr-controllers-for-button-pressing-in-three-js
dollyMove();

// render scene with bloom - not working, disabling for now
if (window.bloomStrength) {
renderBloom( true );

// render the entire scene, then render bloom scene on top - test w/o, fail to black
window.finalComposer.render();
//return;
//break;
} else
window.renderer.render( window.scene, window.camera );  // working desktop, non vr in hallway
}

function renderBloom( mask ) {

if ( mask === true ) {
// does darken everything if not restored
window.scene.traverse( darkenNonBloomed );
window.bloomComposer.render();
window.scene.traverse( restoreMaterial );

} else {

window.camera.layers.set( BLOOM_SCENE );
window.bloomComposer.render();
window.camera.layers.set( ENTIRE_SCENE );

}

}

// partial php fns - within set up camera:
$cache .= 'window.camera = new window.THREE.PerspectiveCamera( 80, window.innerWidth / window.innerHeight, 0.1, 1000 );';  // for outdoors

you dont need any of the complexity there, you can select with plain old unrealbloom without extra passes, copy shader and all that: Struggling with gltf and lighting - #9 by drcmda

just set bloom threshold to 1, any color on any material that’s breaking into hd range will now glow, everything else won’t.

new THREE.Color( 1, 0, 0 ) // red, won’t glow
new THREE.Color( 10, 0, 0 ) // red, will glow

That looks like a much better solution. Is react required? Been trying to adapt to plain threejs without any luck so far.

An attempt with plain three.js: Struggling with gltf and lighting - #19 by prisoner849

1 Like

No, that is basic Threejs.

  1. Switch off tonemapping, either completely or on the materials that need to glow via toneMapped = false
  2. Set up bloom pass with a threshold of 1, nothing at all will now glow, the effect-composers render target needs to be defined as new WebGLRenderTarget(width, height, {
    type: HalfFloatType,
    format: RGBAFormat,
    encoding: sRGBEncoding
  3. When you want a material to glow you just need to move colors out of rgb 0-1. either with integers: setRGB(10, 10, 10), or by setEmissiveIntensity(10), the higher you go the more intense will the glow be.
1 Like

Was able to get this to work roughly for the computer, though not in VR. Tried this solution for getting the render target to work on Oculus: WebGLRenderTarget doesn't work in WebXR · Issue #18746 · mrdoob/three.js · GitHub but neither .xr or .vr are defined in bloomComposer, and therefore toggling it off, running the render, and toggling vr or xr back on as the solution suggests threw errors and did not work. Is there a way to get bloomComposer to work in VR? thank you

2 Likes