postProcessRenderPipeline.ts 7.6 KB

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