@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
130 lines (129 loc) • 4.65 kB
JavaScript
"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);
}
}
}