Skip to content

BloomPost

BloomPost, also known as highlight overflow, is a post-processing effect that creates an optical illusion. Parts of the screen with brightness higher than a threshold value will diffuse into surrounding pixels and gradually decrease with distance, which creates a glowing and hazy effect.

ts
//Initialize the engine
await Engine3D.init();

Engine3D.setting.render.postProcessing.bloom.downSampleStep = 5;
Engine3D.setting.render.postProcessing.bloom.downSampleBlurSize = 5;
Engine3D.setting.render.postProcessing.bloom.downSampleBlurSigma = 1.0;
Engine3D.setting.render.postProcessing.bloom.upSampleBlurSize = 5;
Engine3D.setting.render.postProcessing.bloom.upSampleBlurSigma = 1.0;
Engine3D.setting.render.postProcessing.bloom.luminanceThreshole = 1.0;
Engine3D.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;
Engine3D.startRenderView(view);

Engine3D.setting.render.postProcessing.bloom configuration parameters:

ParameterTypeDescription
enable?booleanenable
downSampleStepnumberdown sample step
downSampleBlurSizenumberdown sample blur size
downSampleBlurSigmanumberdown sample blur sigma
upSampleBlurSizenumberup sample blur size
upSampleBlurSigmanumberup sample blur sigma
luminanceThresholenumberluminance threshold
bloomIntensitynumberbloom intensity

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 = Engine3D.res.whiteTexture;
mat.emissiveColor = new Color(1.0, 0.0, 0.0);
mat.emissiveIntensity = 3;

WebGPU is not supported in your browser
Please upgrade to latest Chrome/Edge

<
ts
import { View3D, DirectLight, Engine3D, PostProcessingComponent, LitMaterial, HoverCameraController, KelvinUtil, MeshRenderer, Object3D, PlaneGeometry, Scene3D, SphereGeometry, CameraUtil, webGPUContext, BoxGeometry, TAAPost, AtmosphericComponent, GTAOPost, Color, BloomPost } from '@orillusion/core';
import * as dat from 'dat.gui';

class Sample_Bloom {
    lightObj: Object3D;
    scene: Scene3D;

    async run() {
        Engine3D.setting.shadow.shadowSize = 2048;
        Engine3D.setting.shadow.shadowBound = 500;

        await Engine3D.init();

        this.scene = new Scene3D();
        let sky = this.scene.addComponent(AtmosphericComponent);
        sky.sunY = 0.6;

        let mainCamera = CameraUtil.createCamera3DObject(this.scene, 'camera');
        mainCamera.perspective(60, webGPUContext.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;
        Engine3D.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 = 10;
            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 = Engine3D.res.whiteTexture;
                    litMat.emissiveColor = new Color(0.0, 0.0, 1.0);
                    litMat.emissiveIntensity = 5.0;
                    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 = Engine3D.res.whiteTexture;
                    litMat.emissiveColor = new Color(1.0, 1.0, 0.0);
                    litMat.emissiveIntensity = 5;
                    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();