postProcessRenderPipeline.ts 6.9 KB

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