postProcessRenderPipeline.ts 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. import { Nullable } from "types";
  2. import { Tools } from "Tools";
  3. import { Camera } from "Cameras";
  4. import { Engine } from "Engine";
  5. import { PostProcessRenderEffect } from "PostProcess";
  6. /**
  7. * PostProcessRenderPipeline
  8. * @see https://doc.babylonjs.com/how_to/how_to_use_postprocessrenderpipeline
  9. */
  10. export class PostProcessRenderPipeline {
  11. private _renderEffects: { [key: string]: PostProcessRenderEffect };
  12. private _renderEffectsForIsolatedPass: PostProcessRenderEffect[];
  13. /**
  14. * @hidden
  15. */
  16. protected _cameras: Camera[];
  17. /** @hidden */
  18. @serialize()
  19. public _name: string;
  20. /**
  21. * Initializes a PostProcessRenderPipeline
  22. * @param engine engine to add the pipeline to
  23. * @param name name of the pipeline
  24. */
  25. constructor(private engine: Engine, name: string) {
  26. this._name = name;
  27. this._renderEffects = {};
  28. this._renderEffectsForIsolatedPass = new Array<PostProcessRenderEffect>();
  29. this._cameras = [];
  30. }
  31. /**
  32. * "PostProcessRenderPipeline"
  33. * @returns "PostProcessRenderPipeline"
  34. */
  35. public getClassName(): string {
  36. return "PostProcessRenderPipeline";
  37. }
  38. /**
  39. * If all the render effects in the pipeline are support
  40. */
  41. public get isSupported(): boolean {
  42. for (var renderEffectName in this._renderEffects) {
  43. if (this._renderEffects.hasOwnProperty(renderEffectName)) {
  44. if (!this._renderEffects[renderEffectName].isSupported) {
  45. return false;
  46. }
  47. }
  48. }
  49. return true;
  50. }
  51. /**
  52. * Adds an effect to the pipeline
  53. * @param renderEffect the effect to add
  54. */
  55. public addEffect(renderEffect: PostProcessRenderEffect): void {
  56. (<any>this._renderEffects)[renderEffect._name] = renderEffect;
  57. }
  58. // private
  59. /** @hidden */
  60. public _rebuild() {
  61. }
  62. /** @hidden */
  63. public _enableEffect(renderEffectName: string, cameras: Camera): void;
  64. /** @hidden */
  65. public _enableEffect(renderEffectName: string, cameras: Camera[]): void;
  66. /** @hidden */
  67. public _enableEffect(renderEffectName: string, cameras: any): void {
  68. var renderEffects: PostProcessRenderEffect = (<any>this._renderEffects)[renderEffectName];
  69. if (!renderEffects) {
  70. return;
  71. }
  72. renderEffects._enable(Tools.MakeArray(cameras || this._cameras));
  73. }
  74. /** @hidden */
  75. public _disableEffect(renderEffectName: string, cameras: Nullable<Camera[]>): void;
  76. /** @hidden */
  77. public _disableEffect(renderEffectName: string, cameras: Nullable<Camera[]>): void;
  78. /** @hidden */
  79. public _disableEffect(renderEffectName: string, cameras: Nullable<Camera[]>): void {
  80. var renderEffects: PostProcessRenderEffect = (<any>this._renderEffects)[renderEffectName];
  81. if (!renderEffects) {
  82. return;
  83. }
  84. renderEffects._disable(Tools.MakeArray(cameras || this._cameras));
  85. }
  86. /** @hidden */
  87. public _attachCameras(cameras: Camera, unique: boolean): void;
  88. /** @hidden */
  89. public _attachCameras(cameras: Camera[], unique: boolean): void;
  90. /** @hidden */
  91. public _attachCameras(cameras: any, unique: boolean): void {
  92. var cams = Tools.MakeArray(cameras || this._cameras);
  93. if (!cams) {
  94. return;
  95. }
  96. var indicesToDelete = [];
  97. var i: number;
  98. for (i = 0; i < cams.length; i++) {
  99. var camera = cams[i];
  100. var cameraName = camera.name;
  101. if (this._cameras.indexOf(camera) === -1) {
  102. this._cameras[cameraName] = camera;
  103. }
  104. else if (unique) {
  105. indicesToDelete.push(i);
  106. }
  107. }
  108. for (i = 0; i < indicesToDelete.length; i++) {
  109. cameras.splice(indicesToDelete[i], 1);
  110. }
  111. for (var renderEffectName in this._renderEffects) {
  112. if (this._renderEffects.hasOwnProperty(renderEffectName)) {
  113. this._renderEffects[renderEffectName]._attachCameras(cams);
  114. }
  115. }
  116. }
  117. /** @hidden */
  118. public _detachCameras(cameras: Camera): void;
  119. /** @hidden */
  120. public _detachCameras(cameras: Nullable<Camera[]>): void;
  121. /** @hidden */
  122. public _detachCameras(cameras: any): void {
  123. var cams = Tools.MakeArray(cameras || this._cameras);
  124. if (!cams) {
  125. return;
  126. }
  127. for (var renderEffectName in this._renderEffects) {
  128. if (this._renderEffects.hasOwnProperty(renderEffectName)) {
  129. this._renderEffects[renderEffectName]._detachCameras(cams);
  130. }
  131. }
  132. for (var i = 0; i < cams.length; i++) {
  133. this._cameras.splice(this._cameras.indexOf(cams[i]), 1);
  134. }
  135. }
  136. /** @hidden */
  137. public _update(): void {
  138. for (var renderEffectName in this._renderEffects) {
  139. if (this._renderEffects.hasOwnProperty(renderEffectName)) {
  140. this._renderEffects[renderEffectName]._update();
  141. }
  142. }
  143. for (var i = 0; i < this._cameras.length; i++) {
  144. var cameraName = this._cameras[i].name;
  145. if ((<any>this._renderEffectsForIsolatedPass)[cameraName]) {
  146. (<any>this._renderEffectsForIsolatedPass)[cameraName]._update();
  147. }
  148. }
  149. }
  150. /** @hidden */
  151. public _reset(): void {
  152. this._renderEffects = {};
  153. this._renderEffectsForIsolatedPass = new Array<PostProcessRenderEffect>();
  154. }
  155. protected _enableMSAAOnFirstPostProcess(sampleCount: number): boolean {
  156. // Set samples of the very first post process to 4 to enable native anti-aliasing in browsers that support webGL 2.0 (See: https://github.com/BabylonJS/Babylon.js/issues/3754)
  157. var effectKeys = Object.keys(this._renderEffects);
  158. if (this.engine.webGLVersion >= 2 && effectKeys.length > 0) {
  159. var postProcesses = this._renderEffects[effectKeys[0]].getPostProcesses();
  160. if (postProcesses) {
  161. postProcesses[0].samples = sampleCount;
  162. return true;
  163. }
  164. }
  165. return false;
  166. }
  167. /**
  168. * Disposes of the pipeline
  169. */
  170. public dispose() {
  171. // Must be implemented by children
  172. }
  173. }