HDR Screen Bloom - BloomPost
A screen post-processing effect, also known as highlight overflow, that creates an optical effect; parts of the screen with brightness higher than a threshold value will diffuse into surrounding pixels and gradually decrease with distance, creating a glowing and hazy effect.
ts
//Initialize the engine
let engine = await Engine3D.init();
engine.setting.render.postProcessing.bloom.downSampleStep = 5;
engine.setting.render.postProcessing.bloom.downSampleBlurSize = 5;
engine.setting.render.postProcessing.bloom.downSampleBlurSigma = 1.0;
engine.setting.render.postProcessing.bloom.upSampleBlurSize = 5;
engine.setting.render.postProcessing.bloom.upSampleBlurSigma = 1.0;
engine.setting.render.postProcessing.bloom.luminanceThreshole = 1.0;
engine.setting.render.postProcessing.bloom.bloomIntensity = 1.0;
// Add a BloomPost
let postProcessing = this.scene.addComponent(PostProcessingComponent);
postProcessing.addPost(BloomPost);
//Start rendering
let view = new View3D();
view.scene = this.scene;
view.camera = this.camera;
engine.startRenderView(view);Configuration parameters for engine.setting.render.postProcessing.bloom.
| Parameter | Type | Description |
|---|---|---|
enable | boolean | enable |
downSampleStep | number | Number of downsampling passes |
downSampleBlurSize | number | Downsampling blur range |
downSampleBlurSigma | number | Downsampling blur computation exponent |
upSampleBlurSize | number | Number of upsampling passes |
upSampleBlurSigma | number | Upsampling blur range |
luminanceThreshole | number | Threshold for the Bloom highlight region |
bloomIntensity | boolean | Final bloom brightness boost factor |
Generally, we can control the object's bloom effect by adding an emissive texture and color to its material:
ts
let mat = new LitMaterial();
mat.emissiveMap = engine.res.whiteTexture;
mat.emissiveColor = new Color(1.0, 0.0, 0.0);
mat.emissiveIntensity = 3;ts
import { View3D, DirectLight, Engine3D, PostProcessingComponent, LitMaterial, HoverCameraController, KelvinUtil, MeshRenderer, Object3D, PlaneGeometry, Scene3D, SphereGeometry, CameraUtil, BoxGeometry, TAAPost, AtmosphericComponent, GTAOPost, Color, BloomPost } from '@orillusion/core';
import * as dat from 'dat.gui';
class Sample_Bloom {
lightObj: Object3D;
scene: Scene3D;
engine: Engine3D;
async run() {
this.engine = await Engine3D.init({
setting: {
shadow: {
shadowSize: 2048,
shadowBound: 500
}
}
});
this.scene = new Scene3D();
let sky = this.scene.addComponent(AtmosphericComponent);
sky.sunY = 0.6;
let mainCamera = CameraUtil.createCamera3DObject(this.scene, 'camera');
mainCamera.perspective(60, this.engine.aspect, 1, 5000.0);
let ctrl = mainCamera.object3D.addComponent(HoverCameraController);
ctrl.setCamera(0, -15, 500);
await this.initScene();
sky.relativeTransform = this.lightObj.transform;
let view = new View3D();
view.scene = this.scene;
view.camera = mainCamera;
this.engine.startRenderView(view);
let postProcessing = this.scene.addComponent(PostProcessingComponent);
let post = postProcessing.addPost(BloomPost);
this.renderBloom(post, true);
}
public renderBloom(bloom: BloomPost, open: boolean = true, name?: string) {
name ||= 'Bloom';
let GUIHelp = new dat.GUI();
GUIHelp.addFolder(name);
GUIHelp.add(bloom, 'downSampleBlurSize', 3, 15, 1);
GUIHelp.add(bloom, 'downSampleBlurSigma', 0.01, 1, 0.001);
GUIHelp.add(bloom, 'upSampleBlurSize', 3, 15, 1);
GUIHelp.add(bloom, 'upSampleBlurSigma', 0.01, 1, 0.001);
GUIHelp.add(bloom, 'luminanceThreshole', 0.001, 10.0, 0.001);
GUIHelp.add(bloom, 'bloomIntensity', 0.001, 10.0, 0.001);
}
async initScene() {
{
this.lightObj = new Object3D();
this.lightObj.rotationX = 45;
this.lightObj.rotationY = 110;
this.lightObj.rotationZ = 0;
let lc = this.lightObj.addComponent(DirectLight);
lc.lightColor = KelvinUtil.color_temperature_to_rgb(5355);
lc.castShadow = true;
lc.intensity = 3;
this.scene.addChild(this.lightObj);
}
{
let mat = new LitMaterial();
let floor = new Object3D();
let mr = floor.addComponent(MeshRenderer);
mr.geometry = new PlaneGeometry(400, 400);
mr.material = mat;
this.scene.addChild(floor);
{
let wall = new Object3D();
let mr = wall.addComponent(MeshRenderer);
mr.geometry = new BoxGeometry(5, 260, 320);
mr.material = mat;
wall.x = -320 * 0.5;
this.scene.addChild(wall);
}
{
let wall = new Object3D();
let mr = wall.addComponent(MeshRenderer);
mr.geometry = new BoxGeometry(5, 260, 320);
mr.material = mat;
wall.x = 320 * 0.5;
this.scene.addChild(wall);
}
{
let wall = new Object3D();
let mr = wall.addComponent(MeshRenderer);
mr.geometry = new BoxGeometry(320, 260, 5);
mr.material = mat;
wall.z = -320 * 0.5;
this.scene.addChild(wall);
}
{
{
let litMat = new LitMaterial();
litMat.emissiveMap = this.engine.res.whiteTexture;
litMat.emissiveColor = new Color(0.0, 0.0, 1.0);
litMat.emissiveIntensity = 0.6;
let sp = new Object3D();
let mr = sp.addComponent(MeshRenderer);
mr.geometry = new SphereGeometry(15, 30, 30);
mr.material = litMat;
sp.x = 68;
sp.y = 15;
sp.z = -15;
this.scene.addChild(sp);
}
{
let litMat = new LitMaterial();
litMat.emissiveMap = this.engine.res.whiteTexture;
litMat.emissiveColor = new Color(1.0, 1.0, 0.0);
litMat.emissiveIntensity = 0.8;
let sp = new Object3D();
let mr = sp.addComponent(MeshRenderer);
mr.geometry = new SphereGeometry(15, 30, 30);
mr.material = litMat;
sp.x = 1;
sp.y = 15;
sp.z = -8;
this.scene.addChild(sp);
}
}
}
}
}
new Sample_Bloom().run();
