Source: filters/defaults/blur/BlurFilterPass.ts

  1. import { TexturePool } from '../../../rendering/renderers/shared/texture/TexturePool';
  2. import { RendererType } from '../../../rendering/renderers/types';
  3. import { Filter } from '../../Filter';
  4. import { generateBlurGlProgram } from './gl/generateBlurGlProgram';
  5. import { generateBlurProgram } from './gpu/generateBlurProgram';
  6. import type { RenderSurface } from '../../../rendering/renderers/shared/renderTarget/RenderTargetSystem';
  7. import type { Texture } from '../../../rendering/renderers/shared/texture/Texture';
  8. import type { FilterSystem } from '../../FilterSystem';
  9. import type { BlurFilterOptions } from './BlurFilter';
  10. /**
  11. * Options for BlurFilterPass
  12. * @memberof filters
  13. */
  14. export interface BlurFilterPassOptions extends BlurFilterOptions
  15. {
  16. /** Do pass along the x-axis (`true`) or y-axis (`false`). */
  17. horizontal: boolean;
  18. }
  19. /**
  20. * The BlurFilterPass applies a horizontal or vertical Gaussian blur to an object.
  21. * @memberof filters
  22. */
  23. export class BlurFilterPass extends Filter
  24. {
  25. /** Default blur filter pass options */
  26. public static defaultOptions: Partial<BlurFilterPassOptions> = {
  27. /** The strength of the blur filter. */
  28. strength: 8,
  29. /** The quality of the blur filter. */
  30. quality: 4,
  31. /** The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15. */
  32. kernelSize: 5,
  33. };
  34. /** Do pass along the x-axis (`true`) or y-axis (`false`). */
  35. public horizontal: boolean;
  36. /** The number of passes to run the filter. */
  37. public passes!: number;
  38. /** The strength of the blur filter. */
  39. public strength!: number;
  40. private _quality: number;
  41. private readonly _uniforms: any;
  42. /**
  43. * @param options
  44. * @param options.horizontal - Do pass along the x-axis (`true`) or y-axis (`false`).
  45. * @param options.strength - The strength of the blur filter.
  46. * @param options.quality - The quality of the blur filter.
  47. * @param options.kernelSize - The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15.
  48. */
  49. constructor(options: BlurFilterPassOptions)
  50. {
  51. options = { ...BlurFilterPass.defaultOptions, ...options };
  52. const glProgram = generateBlurGlProgram(options.horizontal, options.kernelSize);
  53. const gpuProgram = generateBlurProgram(options.horizontal, options.kernelSize);
  54. super({
  55. glProgram,
  56. gpuProgram,
  57. resources: {
  58. blurUniforms: {
  59. uStrength: { value: 0, type: 'f32' },
  60. }
  61. },
  62. ...options
  63. });
  64. this.horizontal = options.horizontal;
  65. this._quality = 0;
  66. this.quality = options.quality;
  67. this.blur = options.strength;
  68. this._uniforms = this.resources.blurUniforms.uniforms;
  69. }
  70. /**
  71. * Applies the filter.
  72. * @param filterManager - The manager.
  73. * @param input - The input target.
  74. * @param output - The output target.
  75. * @param clearMode - How to clear
  76. */
  77. public apply(
  78. filterManager: FilterSystem,
  79. input: Texture,
  80. output: RenderSurface,
  81. clearMode: boolean
  82. ): void
  83. {
  84. this._uniforms.uStrength = this.strength / this.passes;
  85. if (this.passes === 1)
  86. {
  87. filterManager.applyFilter(this, input, output, clearMode);
  88. }
  89. else
  90. {
  91. const tempTexture = TexturePool.getSameSizeTexture(input);
  92. let flip = input;
  93. let flop = tempTexture;
  94. this._state.blend = false;
  95. const shouldClear = filterManager.renderer.type === RendererType.WEBGPU;
  96. for (let i = 0; i < this.passes - 1; i++)
  97. {
  98. filterManager.applyFilter(this, flip, flop, i === 0 ? true : shouldClear);
  99. const temp = flop;
  100. flop = flip;
  101. flip = temp;
  102. }
  103. this._state.blend = true;
  104. filterManager.applyFilter(this, flip, output, clearMode);
  105. TexturePool.returnTexture(tempTexture);
  106. }
  107. }
  108. /**
  109. * Sets the strength of both the blur.
  110. * @default 16
  111. */
  112. get blur(): number
  113. {
  114. return this.strength;
  115. }
  116. set blur(value: number)
  117. {
  118. this.padding = 1 + (Math.abs(value) * 2);
  119. this.strength = value;
  120. }
  121. /**
  122. * Sets the quality of the blur by modifying the number of passes. More passes means higher
  123. * quality blurring but the lower the performance.
  124. * @default 4
  125. */
  126. get quality(): number
  127. {
  128. return this._quality;
  129. }
  130. set quality(value: number)
  131. {
  132. this._quality = value;
  133. this.passes = value;
  134. }
  135. }