threepipe
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PipelinePassPlugin.ts 2.4KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import {IPassID, IPipelinePass} from '../../postprocessing'
  2. import {AViewerPluginSync, ISerializedConfig, ThreeViewer} from '../../viewer'
  3. import {AnyFunction, serialize} from 'ts-browser-helpers'
  4. import {SerializationMetaType} from '../../utils'
  5. import {uiConfig, uiToggle} from 'uiconfig.js'
  6. export abstract class PipelinePassPlugin<T extends IPipelinePass, TPassId extends IPassID, TEvent extends string, TViewer extends ThreeViewer=ThreeViewer> extends AViewerPluginSync<TEvent, TViewer> {
  7. abstract passId: TPassId
  8. @serialize()
  9. @uiToggle('Enabled')
  10. get enabled(): boolean {
  11. return this._pass?.enabled || this._enabledTemp
  12. }
  13. set enabled(value: boolean) {
  14. if (this._pass) this._pass.enabled = value
  15. this._enabledTemp = value
  16. }
  17. @uiConfig()
  18. @serialize('pass')
  19. protected _pass?: T
  20. abstract createPass(v:TViewer):T
  21. /**
  22. * This function is called every frame before composer render, if this pass is being used in the pipeline
  23. * @param _
  24. * @protected
  25. */
  26. protected _beforeRender(): boolean {return this._pass?.enabled && this.enabled || false}
  27. private _enabledTemp = true // to save enabled state when pass is not yet created
  28. constructor() {
  29. super()
  30. this._beforeRender = this._beforeRender.bind(this)
  31. }
  32. onAdded(viewer: TViewer): void {
  33. super.onAdded(viewer)
  34. this._pass = this.createPass(viewer)
  35. this._pass.onDirty?.push(viewer.setDirty)
  36. this._pass.beforeRender = wrapThisFunction(this._beforeRender, this._pass.beforeRender)
  37. viewer.renderManager.registerPass(this._pass)
  38. this.enabled = this._enabledTemp
  39. }
  40. onRemove(viewer: TViewer): void {
  41. if (this._pass) viewer.renderManager.unregisterPass(this._pass)
  42. this._pass?.dispose?.()
  43. this._pass = undefined
  44. super.onRemove(viewer)
  45. }
  46. get pass(): T | undefined {
  47. return this._pass
  48. }
  49. toJSON(meta?: SerializationMetaType): ISerializedConfig&{pass?: any} {
  50. return super.toJSON(meta)
  51. }
  52. fromJSON(data: ISerializedConfig&{pass?: any}, meta?: SerializationMetaType): this|null|Promise<this|null> {
  53. return super.fromJSON(data, meta)
  54. }
  55. }
  56. function wrapThisFunction<T extends AnyFunction, T2>(f1: ()=>void, f2?: T): T {
  57. return function(this: T2, ...args: Parameters<T>) {
  58. f1()
  59. return f2 && f2.call(this, ...args)
  60. } as T
  61. }