postProcessRenderPipeline.ts 7.6 KB

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