threepipe
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

AScreenPassExtensionPlugin.ts 3.8KB

2 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import {type AViewerPlugin, AViewerPluginSync} from '../../viewer/AViewerPlugin'
  2. import type {IViewerEvent, ThreeViewer} from '../../viewer'
  3. import {MaterialExtension} from '../../materials'
  4. import {Shader, Vector4, WebGLRenderer} from 'three'
  5. import {IMaterial} from '../../core'
  6. import {shaderReplaceString} from '../../utils'
  7. import {GBufferPlugin, GBufferUpdater, GBufferUpdaterContext} from '../pipeline/GBufferPlugin'
  8. /**
  9. * Base Screen Pass Extension Plugin
  10. *
  11. * Extend the class to add an extension to {@link ScreenPass} material.
  12. * See {@link TonemapPlugin} and {@link VignettePlugin} for examples.
  13. *
  14. *
  15. * @category Plugins
  16. */
  17. export abstract class AScreenPassExtensionPlugin<T extends string> extends AViewerPluginSync<T> implements MaterialExtension, GBufferUpdater {
  18. declare ['constructor']: (typeof AScreenPassExtensionPlugin) & (typeof AViewerPluginSync) & (typeof AViewerPlugin)
  19. abstract enabled: boolean
  20. set uniformsNeedUpdate(v: boolean) { // for @uniform decorator
  21. if (v) this.setDirty()
  22. }
  23. constructor() {
  24. super()
  25. this.setDirty = this.setDirty.bind(this)
  26. }
  27. /**
  28. * The priority of the material extension when applied to the material in ScreenPass
  29. * set to very low priority, so applied at the end
  30. */
  31. priority = -100
  32. protected _shaderPatch = ''
  33. shaderExtender(shader: Shader, _: IMaterial, _1: WebGLRenderer): void {
  34. if (this.isDisabled()) return
  35. shader.fragmentShader = shaderReplaceString(
  36. shader.fragmentShader,
  37. '#glMarker', '\n' + this._shaderPatch + '\n',
  38. {prepend: true}
  39. )
  40. }
  41. getUiConfig(): any {
  42. return this.uiConfig
  43. }
  44. computeCacheKey = (_: IMaterial) => this.isDisabled() ? '0' : '1'
  45. isCompatible(_: IMaterial): boolean {
  46. return true // (material as MeshStandardMaterial2).isMeshStandardMaterial2
  47. }
  48. setDirty() {
  49. this.__setDirty?.() // this will update version which will set needsUpdate on material
  50. this._viewer?.renderManager.screenPass.setDirty()
  51. }
  52. fromJSON(data: any, meta?: any): this | null | Promise<this | null> {
  53. // really old legacy
  54. if (data.pass) {
  55. data = {...data}
  56. data.extension = {...data.pass}
  57. delete data.extension.enabled
  58. delete data.pass
  59. }
  60. // legacy
  61. if (data.extension) {
  62. data = {...data, ...data.extension}
  63. delete data.extension
  64. }
  65. return super.fromJSON(data, meta)
  66. }
  67. onAdded(viewer: ThreeViewer) {
  68. super.onAdded(viewer)
  69. const gbuffer = viewer.getPlugin(GBufferPlugin)
  70. if (gbuffer) gbuffer.registerGBufferUpdater(this.constructor.PluginType, this.updateGBufferFlags.bind(this))
  71. else viewer.addEventListener('addPlugin', this._onPluginAdd)
  72. viewer.renderManager.screenPass.material.registerMaterialExtensions([this])
  73. }
  74. private _onPluginAdd = (e: IViewerEvent)=>{
  75. if (e.plugin?.constructor?.PluginType !== GBufferPlugin.PluginType) return
  76. const gbuffer = e.plugin as GBufferPlugin
  77. gbuffer.registerGBufferUpdater(this.constructor.PluginType, this.updateGBufferFlags.bind(this))
  78. this._viewer?.removeEventListener('addPlugin', this._onPluginAdd)
  79. }
  80. onRemove(viewer: ThreeViewer) {
  81. viewer.removeEventListener('addPlugin', this._onPluginAdd)
  82. viewer.getPlugin(GBufferPlugin)?.unregisterGBufferUpdater(this.constructor.PluginType)
  83. viewer.renderManager.screenPass.material.unregisterMaterialExtensions([this])
  84. super.onRemove(viewer)
  85. }
  86. // for typescript
  87. // eslint-disable-next-line @typescript-eslint/naming-convention
  88. __setDirty?: () => void
  89. updateGBufferFlags(_: Vector4, _1: GBufferUpdaterContext): void {
  90. return
  91. }
  92. }