UNPKG

@polygonjs/polygonjs

Version:

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

191 lines (190 loc) 5.88 kB
"use strict"; import { Vector2 } from "three"; import { TypedPostNode, PostParamOptions } from "./_Base"; import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig"; import { BlendFunction, GlitchEffect, EffectPass, GlitchMode } from "postprocessing"; import { BLEND_FUNCTION_MENU_OPTIONS } from "../../../core/post/BlendFunction"; import { NodeContext } from "../../poly/NodeContext"; const GLITCH_MODES = [ GlitchMode.DISABLED, GlitchMode.SPORADIC, GlitchMode.CONSTANT_MILD, GlitchMode.CONSTANT_WILD ]; const GLITCH_MODE_BY_INDEX = ["DISABLED", "SPORADIC", "CONSTANT_MILD", "CONSTANT_WILD"]; export const GLITCH_MODE_MENU_OPTIONS = { menu: { entries: GLITCH_MODES.map((value) => { return { name: GLITCH_MODE_BY_INDEX[value], value }; }) } }; class GlitchPostParamsConfig extends NodeParamsConfig { constructor() { super(...arguments); // useTexture = ParamConfig.BOOLEAN(0, { // ...PostParamOptions, // }); this.texture = ParamConfig.NODE_PATH("", { nodeSelection: { context: NodeContext.COP }, dependentOnFoundNode: false, ...PostParamOptions // visibleIf: {useTexture: 1}, }); // dtSize = ParamConfig.INTEGER(64, { // separatorBefore: true, // ...PostParamOptions, // range: [2, 128], // rangeLocked: [true, false], // visibleIf: {useTexture: 0}, // }); /** @param mode */ this.mode = ParamConfig.INTEGER(GLITCH_MODES.indexOf(GlitchMode.CONSTANT_MILD), { ...GLITCH_MODE_MENU_OPTIONS, ...PostParamOptions }); this.minDelay = ParamConfig.FLOAT(0.5, { separatorBefore: true, ...PostParamOptions, range: [0, 1], rangeLocked: [true, false] }); this.maxDelay = ParamConfig.FLOAT(0.5, { ...PostParamOptions, range: [0, 1], rangeLocked: [true, false] }); this.minDuration = ParamConfig.FLOAT(0.5, { separatorBefore: true, ...PostParamOptions, range: [0, 1], rangeLocked: [true, false] }); this.maxDuration = ParamConfig.FLOAT(0.5, { ...PostParamOptions, range: [0, 1], rangeLocked: [true, false] }); this.minStrength = ParamConfig.FLOAT(0.5, { separatorBefore: true, ...PostParamOptions, range: [0, 1], rangeLocked: [true, false] }); this.maxStrength = ParamConfig.FLOAT(0.5, { ...PostParamOptions, range: [0, 1], rangeLocked: [true, false] }); /** @param columns */ this.columns = ParamConfig.INTEGER(2, { ...PostParamOptions, range: [0, 20], rangeLocked: [true, false] }); /** @param ratio */ this.ratio = ParamConfig.FLOAT(1, { range: [0, 1], rangeLocked: [true, true], ...PostParamOptions }); /** @param blend function */ this.blendFunction = ParamConfig.INTEGER(BlendFunction.SCREEN, { ...PostParamOptions, ...BLEND_FUNCTION_MENU_OPTIONS }); /** @param if true, the offset parameter will be updated on each render to reflect the intensity of the glitch. This can be used to drive other effects with it */ this.updateOffset = ParamConfig.BOOLEAN(0, { separatorBefore: true, ...PostParamOptions }); this.offset = ParamConfig.VECTOR2([0, 0], { cook: false, visibleIf: { updateOffset: 1 } }); } } const ParamsConfig = new GlitchPostParamsConfig(); export class GlitchPostNode extends TypedPostNode { constructor() { super(...arguments); this.paramsConfig = ParamsConfig; this._rendererSize = new Vector2(); this._offsetArray = [0, 0]; this._onRenderBound = this._onRender.bind(this); } static type() { return "glitch"; } createPass(context) { this._lastViewer = context.viewer; context.renderer.getSize(this._rendererSize); this._lastEffect = new GlitchEffect({ blendFunction: this.pv.blendFunction, chromaticAberrationOffset: new Vector2(0, 0) // delay:this.pv.delay, // duration:this.pv.duration, // strength:this.pv.strength, // dtSize: this.pv.dtSize, }); const pass = new EffectPass(context.camera, this._lastEffect); this.updatePass(pass); return pass; } async updatePass(pass) { const effect = pass.effects[0]; effect.blendFunction = this.pv.blendFunction; effect.mode = GLITCH_MODES[this.pv.mode]; effect.minDelay = this.pv.minDelay; effect.maxDelay = this.pv.maxDelay; effect.minDuration = this.pv.minDuration; effect.maxDuration = this.pv.maxDuration; effect.minStrength = this.pv.minStrength; effect.maxStrength = this.pv.maxStrength; effect.columns = this.pv.columns; effect.ratio = this.pv.ratio; const texture = await this._fetchTexture(); if (texture) { effect.perturbationMap = texture; } this._updateOnTickCallback(); } async _fetchTexture() { var _a; const textureNode = this.pv.texture.nodeWithContext(NodeContext.COP, (_a = this.states) == null ? void 0 : _a.error); if (textureNode) { const container = await textureNode.compute(); return container.coreContent(); } } _onTickCallbackName() { return `post/glitch-${this.graphNodeId()}`; } _updateOnTickCallback() { if (!this._lastViewer) { return; } const callbackName = this._onTickCallbackName(); if (this.pv.updateOffset) { if (!this._lastViewer.registeredAfterRenderCallbacks().has(callbackName)) { this._lastViewer.registerOnAfterRender(callbackName, this._onRenderBound); } } else { this._lastViewer.unRegisterOnAfterRender(callbackName); } } _onRender() { if (!this._lastEffect) { return; } this._lastEffect.chromaticAberrationOffset.toArray(this._offsetArray); this.p.offset.set(this._offsetArray); } }