bloomEffect.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import { PostProcessRenderEffect } from "../PostProcesses/RenderPipeline/postProcessRenderEffect";
  2. import { PostProcess } from "./postProcess";
  3. import { ExtractHighlightsPostProcess } from "./extractHighlightsPostProcess";
  4. import { BlurPostProcess } from "./blurPostProcess";
  5. import { BloomMergePostProcess } from "./bloomMergePostProcess";
  6. import { Vector2 } from "../Maths/math";
  7. import { Camera } from "../Cameras/camera";
  8. import { Texture } from "../Materials/Textures/texture";
  9. import { Scene } from "../scene";
  10. /**
  11. * The bloom effect spreads bright areas of an image to simulate artifacts seen in cameras
  12. */
  13. export class BloomEffect extends PostProcessRenderEffect {
  14. /**
  15. * @hidden Internal
  16. */
  17. public _effects: Array<PostProcess> = [];
  18. /**
  19. * @hidden Internal
  20. */
  21. public _downscale: ExtractHighlightsPostProcess;
  22. private _blurX: BlurPostProcess;
  23. private _blurY: BlurPostProcess;
  24. private _merge: BloomMergePostProcess;
  25. /**
  26. * The luminance threshold to find bright areas of the image to bloom.
  27. */
  28. public get threshold(): number {
  29. return this._downscale.threshold;
  30. }
  31. public set threshold(value: number) {
  32. this._downscale.threshold = value;
  33. }
  34. /**
  35. * The strength of the bloom.
  36. */
  37. public get weight(): number {
  38. return this._merge.weight;
  39. }
  40. public set weight(value: number) {
  41. this._merge.weight = value;
  42. }
  43. /**
  44. * Specifies the size of the bloom blur kernel, relative to the final output size
  45. */
  46. public get kernel(): number {
  47. return this._blurX.kernel / this.bloomScale;
  48. }
  49. public set kernel(value: number) {
  50. this._blurX.kernel = value * this.bloomScale;
  51. this._blurY.kernel = value * this.bloomScale;
  52. }
  53. /**
  54. * Creates a new instance of @see BloomEffect
  55. * @param scene The scene the effect belongs to.
  56. * @param bloomScale The ratio of the blur texture to the input texture that should be used to compute the bloom.
  57. * @param bloomKernel The size of the kernel to be used when applying the blur.
  58. * @param bloomWeight The the strength of bloom.
  59. * @param pipelineTextureType The type of texture to be used when performing the post processing.
  60. * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
  61. */
  62. constructor(scene: Scene, private bloomScale: number, bloomWeight: number, bloomKernel: number, pipelineTextureType = 0, blockCompilation = false) {
  63. super(scene.getEngine(), "bloom", () => {
  64. return this._effects;
  65. }, true);
  66. this._downscale = new ExtractHighlightsPostProcess("highlights", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
  67. this._blurX = new BlurPostProcess("horizontal blur", new Vector2(1.0, 0), 10.0, bloomScale, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, undefined, blockCompilation);
  68. this._blurX.alwaysForcePOT = true;
  69. this._blurX.autoClear = false;
  70. this._blurY = new BlurPostProcess("vertical blur", new Vector2(0, 1.0), 10.0, bloomScale, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, undefined, blockCompilation);
  71. this._blurY.alwaysForcePOT = true;
  72. this._blurY.autoClear = false;
  73. this.kernel = bloomKernel;
  74. this._effects = [this._downscale, this._blurX, this._blurY];
  75. this._merge = new BloomMergePostProcess("bloomMerge", this._downscale, this._blurY, bloomWeight, bloomScale, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
  76. this._merge.autoClear = false;
  77. this._effects.push(this._merge);
  78. }
  79. /**
  80. * Disposes each of the internal effects for a given camera.
  81. * @param camera The camera to dispose the effect on.
  82. */
  83. public disposeEffects(camera: Camera) {
  84. for (var effectIndex = 0; effectIndex < this._effects.length; effectIndex++) {
  85. this._effects[effectIndex].dispose(camera);
  86. }
  87. }
  88. /**
  89. * @hidden Internal
  90. */
  91. public _updateEffects() {
  92. for (var effectIndex = 0; effectIndex < this._effects.length; effectIndex++) {
  93. this._effects[effectIndex].updateEffect();
  94. }
  95. }
  96. /**
  97. * Internal
  98. * @returns if all the contained post processes are ready.
  99. * @hidden
  100. */
  101. public _isReady() {
  102. for (var effectIndex = 0; effectIndex < this._effects.length; effectIndex++) {
  103. if (!this._effects[effectIndex].isReady()) {
  104. return false;
  105. }
  106. }
  107. return true;
  108. }
  109. }