Skip to content

HDR 屏幕泛光 - BloomPost

一种屏幕后期效果,也叫高光溢出,是一种光学效果;屏幕颜色内亮度高于阈值的部分会表现出扩散到周围像素中,并且随距离的增加而递减,形成一种发光朦胧的效果。

ts
//初始化引擎
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;

// 添加 BloomPost
let postProcessing = this.scene.addComponent(PostProcessingComponent);
postProcessing.addPost(BloomPost);

//开始渲染
let view = new View3D();
view.scene = this.scene;
view.camera = this.camera;
Engine3D.startRenderView(view);

Engine3D.setting.render.postProcessing.bloom 配置参数。

参数类型描述
enablebooleanenable
downSampleStepnumber下采样次数
downSampleBlurSizenumber下采样模糊范围
downSampleBlurSigmanumber下采样模糊计算指数
upSampleBlurSizenumber上采样次数
upSampleBlurSigmanumber上采样模糊范围
luminanceThresholenumberBloom高亮区域阈值
bloomIntensitybooleanBloom最终亮度加成系数

一般我们可以通过对物体材质添加发光贴图和颜色来控制物体的发光效果:

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()