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

AScreenPassExtensionPlugin.ts 3.5KB

1 год назад
1 год назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import {type AViewerPlugin, AViewerPluginEventMap, AViewerPluginSync} from '../../viewer/AViewerPlugin'
  2. import type {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<TE extends AViewerPluginEventMap = AViewerPluginEventMap> extends AViewerPluginSync<TE> 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(shaderPatch = '') {
  24. super()
  25. this._shaderPatch = shaderPatch
  26. this.setDirty = this.setDirty.bind(this)
  27. }
  28. /**
  29. * The priority of the material extension when applied to the material in ScreenPass
  30. * set to very low priority, so applied at the end
  31. */
  32. priority = -100
  33. protected _shaderPatch = ''
  34. shaderExtender(shader: Shader, _: IMaterial, _1: WebGLRenderer): void {
  35. if (this.isDisabled()) return
  36. shader.fragmentShader = shaderReplaceString(
  37. shader.fragmentShader,
  38. '#glMarker', '\n' + this._shaderPatch + '\n',
  39. {prepend: true}
  40. )
  41. }
  42. getUiConfig(): any {
  43. return this.uiConfig
  44. }
  45. computeCacheKey = (_: IMaterial) => this.isDisabled() ? '0' : '1'
  46. isCompatible(_: IMaterial): boolean {
  47. return true // (material as MeshStandardMaterial2).isMeshStandardMaterial2
  48. }
  49. setDirty() {
  50. this.__setDirty?.() // this will update version which will set needsUpdate on material
  51. this._viewer?.renderManager.screenPass.setDirty()
  52. }
  53. fromJSON(data: any, meta?: any): this | null | Promise<this | null> {
  54. // really old legacy
  55. if (data.pass) {
  56. data = {...data}
  57. data.extension = {...data.pass}
  58. delete data.extension.enabled
  59. delete data.pass
  60. }
  61. // legacy
  62. if (data.extension) {
  63. data = {...data, ...data.extension}
  64. delete data.extension
  65. }
  66. return super.fromJSON(data, meta)
  67. }
  68. onAdded(viewer: ThreeViewer) {
  69. super.onAdded(viewer)
  70. viewer.forPlugin(GBufferPlugin, (gbuffer) => {
  71. gbuffer.registerGBufferUpdater(this.constructor.PluginType, this.updateGBufferFlags.bind(this))
  72. }, (gbuffer)=>{
  73. gbuffer.unregisterGBufferUpdater(this.constructor.PluginType)
  74. })
  75. viewer.renderManager.screenPass.material.registerMaterialExtensions([this])
  76. }
  77. onRemove(viewer: ThreeViewer) {
  78. viewer.getPlugin(GBufferPlugin)?.unregisterGBufferUpdater(this.constructor.PluginType)
  79. viewer.renderManager.screenPass.material.unregisterMaterialExtensions([this])
  80. super.onRemove(viewer)
  81. }
  82. // for typescript
  83. // eslint-disable-next-line @typescript-eslint/naming-convention
  84. __setDirty?: () => void
  85. updateGBufferFlags(_: Vector4, _1: GBufferUpdaterContext): void {
  86. return
  87. }
  88. }