UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

130 lines (129 loc) 4.65 kB
"use strict"; import { SelectionController } from "./utils/SelectionController"; import { Vector2 } from "three"; import { TypedPostNode, PostParamOptions } from "./_Base"; import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig"; import { BlendFunction, SelectiveBloomEffect, BloomEffect, EffectPass, KernelSize } from "postprocessing"; import { KERNEL_SIZES, KERNEL_SIZE_MENU_OPTIONS } from "../../../core/post/KernelSize"; import { BLEND_FUNCTION_MENU_OPTIONS } from "./../../../core/post/BlendFunction"; import { isBooleanTrue } from "../../../core/Type"; class BloomPostParamsConfig extends NodeParamsConfig { constructor() { super(...arguments); /** @param defines if this node applies a bloom to the whole scene or just a selection. Note that for now, it is necessary to reload your scene when toggling this parameter */ this.useObjectMask = ParamConfig.BOOLEAN(0, { ...PostParamOptions }); /** @param object mask of the objects that will be used for the bloom */ this.objectsMask = ParamConfig.STRING("*bloomed*", { ...PostParamOptions, objectMask: true, visibleIf: { useObjectMask: 1 } }); /** @param updates the cached objects found by objectMask */ this.refreshObjects = ParamConfig.BUTTON(null, { ...PostParamOptions, visibleIf: { useObjectMask: 1 } }); /** @param effect strength */ this.strength = ParamConfig.FLOAT(1.5, { range: [0, 3], rangeLocked: [true, false], ...PostParamOptions }); /** @param effect threshold */ this.threshold = ParamConfig.FLOAT(1, { ...PostParamOptions }); /** @param effect scale */ this.scale = ParamConfig.FLOAT(1, { range: [0, 3], rangeLocked: [true, false], ...PostParamOptions }); /** @param effect radius */ // radius = ParamConfig.FLOAT(1, { // ...PostParamOptions, // }); /** @param kernel size */ this.kernelSize = ParamConfig.INTEGER(KernelSize.LARGE, { ...PostParamOptions, ...KERNEL_SIZE_MENU_OPTIONS }); /** @param effect luminance Smoothing */ this.luminanceSmoothing = ParamConfig.FLOAT(0.1, { ...PostParamOptions }); /** @param resolutionScale */ this.resolutionScale = ParamConfig.FLOAT(0.5, { ...PostParamOptions }); /** @param opacity */ this.opacity = ParamConfig.FLOAT(1, { range: [0, 1], rangeLocked: [true, false], ...PostParamOptions }); /** @param render mode */ this.blendFunction = ParamConfig.INTEGER(BlendFunction.SCREEN, { ...PostParamOptions, ...BLEND_FUNCTION_MENU_OPTIONS }); } /** @param bloom only */ // bloomOnly = ParamConfig.BOOLEAN(0, { // ...PostParamOptions, // }); } const ParamsConfig = new BloomPostParamsConfig(); export class BloomPostNode extends TypedPostNode { constructor() { super(...arguments); this.paramsConfig = ParamsConfig; this._rendererSize = new Vector2(); } static type() { return "bloom"; } createPass(context) { context.renderer.getSize(this._rendererSize); const bloomEffectOptions = { blendFunction: BlendFunction.SCREEN, kernelSize: KERNEL_SIZES[this.pv.kernelSize], luminanceThreshold: this.pv.threshold, luminanceSmoothing: this.pv.luminanceSmoothing, resolutionScale: this.pv.resolutionScale // height: 480, }; const bloomEffect = isBooleanTrue(this.pv.useObjectMask) ? new SelectiveBloomEffect(context.scene, context.camera, bloomEffectOptions) : new BloomEffect(bloomEffectOptions); const pass = new EffectPass(context.camera, bloomEffect); this.updatePass(pass); return pass; } updatePass(pass) { const effect = pass.effects[0]; effect.blendMode.opacity.value = this.pv.opacity; effect.blendMode.blendFunction = this.pv.blendFunction; effect.intensity = this.pv.strength; effect.luminanceMaterial.threshold = this.pv.threshold; effect.luminanceMaterial.smoothing = this.pv.luminanceSmoothing; effect.blurPass.blurMaterial.kernelSize = KERNEL_SIZES[this.pv.kernelSize]; effect.blurPass.resolution.scale = this.pv.resolutionScale; effect.blurPass.scale = this.pv.scale; this._setSelectedObjects(effect); } _selectionController() { return this.__selectionController = this.__selectionController || new SelectionController(); } _setSelectedObjects(effect) { if (effect instanceof SelectiveBloomEffect && isBooleanTrue(this.pv.useObjectMask)) { this._selectionController().updateSelection(this.scene(), this.pv.objectsMask, effect.selection); } } }