babylon.bloomEffect.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. module BABYLON {
  2. /**
  3. * The bloom effect spreads bright areas of an image to simulate artifacts seen in cameras
  4. */
  5. export class BloomEffect extends PostProcessRenderEffect{
  6. /**
  7. * Internal
  8. */
  9. public _effects: Array<PostProcess> = [];
  10. private _downscale:ExtractHighlightsPostProcess;
  11. private _blurX:BlurPostProcess;
  12. private _blurY:BlurPostProcess;
  13. private _upscale:PassPostProcess;
  14. private _merge:Nullable<DefaultPipelineMergeMergePostProcess>;
  15. /**
  16. * The luminance threshold to find bright areas of the image to bloom.
  17. */
  18. public get threshold():number{
  19. return this._downscale.threshold;
  20. }
  21. public set threshold(value: number){
  22. this._downscale.threshold = value;
  23. }
  24. /**
  25. * Creates a new instance of @see BloomEffect
  26. * @param scene The scene the effect belongs to.
  27. * @param bloomScale The ratio of the blur texture to the input texture that should be used to compute the bloom.
  28. * @param bloomKernel The size of the kernel to be used when applying the blur.
  29. * @param pipelineTextureType The type of texture to be used when performing the post processing.
  30. * @param performMerge If the finalization merge should be performed by this effect.
  31. * @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)
  32. */
  33. constructor(scene: Scene, bloomScale:number, bloomKernel:number, pipelineTextureType = 0, performMerge = true, blockCompilation = false) {
  34. super(scene.getEngine(), "bloom", ()=>{
  35. return this._effects;
  36. }, true);
  37. this._downscale = new ExtractHighlightsPostProcess("highlights", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
  38. this._blurX = new BlurPostProcess("horizontal blur", new Vector2(1.0, 0), 10.0, bloomScale, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, undefined, blockCompilation);
  39. this._blurX.alwaysForcePOT = true;
  40. this._blurX.autoClear = false;
  41. this._blurX.onActivateObservable.add(() => {
  42. let dw = this._blurX.width / scene.getEngine().getRenderWidth(true);
  43. this._blurX.kernel = bloomKernel * dw;
  44. });
  45. this._blurY = new BlurPostProcess("vertical blur", new Vector2(0, 1.0), 10.0, bloomScale, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, undefined, blockCompilation);
  46. this._blurY.alwaysForcePOT = true;
  47. this._blurY.autoClear = false;
  48. this._blurY.onActivateObservable.add(() => {
  49. let dh = this._blurY.height / scene.getEngine().getRenderHeight(true);
  50. this._blurY.kernel = bloomKernel * dh;
  51. });
  52. this._upscale = new PassPostProcess("sceneRenderTarget", bloomScale, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
  53. this._upscale.autoClear = false;
  54. this._effects = [this._downscale, this._blurY, this._blurX, this._upscale];
  55. if(performMerge){
  56. this._merge = new DefaultPipelineMergeMergePostProcess("defaultPipelineMerge", {originalFromInput: this._blurX, bloom: {blurred: this._blurY, weight: 0}}, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
  57. this._merge.autoClear = false;
  58. this._effects.push(this._merge);
  59. }
  60. }
  61. /**
  62. * Disposes each of the internal effects for a given camera.
  63. * @param camera The camera to dispose the effect on.
  64. */
  65. public disposeEffects(camera:Camera){
  66. for(var effect in this._effects){
  67. this._effects[effect].dispose(camera);
  68. }
  69. }
  70. /**
  71. * Internal
  72. */
  73. public _updateEffects(){
  74. for(var effect in this._effects){
  75. this._effects[effect].updateEffect();
  76. }
  77. }
  78. /**
  79. * Internal
  80. * @returns if all the contained post processes are ready.
  81. */
  82. public _isReady(){
  83. for(var effect in this._effects){
  84. if(!this._effects[effect].isReady()){
  85. return false;
  86. }
  87. }
  88. return true;
  89. }
  90. }
  91. }