postProcessRenderPipeline.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. import { __decorate } from "../../tslib.es6.js";
  2. import { Tools } from "../../Misc/tools.js";
  3. import { serialize } from "../../Misc/decorators.js";
  4. /**
  5. * PostProcessRenderPipeline
  6. * @see https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/postProcessRenderPipeline
  7. */
  8. export class PostProcessRenderPipeline {
  9. /**
  10. * Gets pipeline name
  11. */
  12. get name() {
  13. return this._name;
  14. }
  15. /** Gets the list of attached cameras */
  16. get cameras() {
  17. return this._cameras;
  18. }
  19. /**
  20. * Initializes a PostProcessRenderPipeline
  21. * @param _engine engine to add the pipeline to
  22. * @param name name of the pipeline
  23. */
  24. constructor(_engine, name) {
  25. this._engine = _engine;
  26. this._name = name;
  27. this._renderEffects = {};
  28. this._renderEffectsForIsolatedPass = new Array();
  29. this._cameras = [];
  30. }
  31. /**
  32. * Gets the class name
  33. * @returns "PostProcessRenderPipeline"
  34. */
  35. getClassName() {
  36. return "PostProcessRenderPipeline";
  37. }
  38. /**
  39. * If all the render effects in the pipeline are supported
  40. */
  41. get isSupported() {
  42. for (const renderEffectName in this._renderEffects) {
  43. if (Object.prototype.hasOwnProperty.call(this._renderEffects, 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. addEffect(renderEffect) {
  56. this._renderEffects[renderEffect._name] = renderEffect;
  57. }
  58. // private
  59. /** @internal */
  60. _rebuild() { }
  61. /**
  62. * @internal
  63. */
  64. _enableEffect(renderEffectName, cameras) {
  65. const renderEffects = this._renderEffects[renderEffectName];
  66. if (!renderEffects) {
  67. return;
  68. }
  69. renderEffects._enable(Tools.MakeArray(cameras || this._cameras));
  70. }
  71. /**
  72. * @internal
  73. */
  74. _disableEffect(renderEffectName, cameras) {
  75. const renderEffects = this._renderEffects[renderEffectName];
  76. if (!renderEffects) {
  77. return;
  78. }
  79. renderEffects._disable(Tools.MakeArray(cameras || this._cameras));
  80. }
  81. /**
  82. * @internal
  83. */
  84. _attachCameras(cameras, unique) {
  85. const cams = Tools.MakeArray(cameras || this._cameras);
  86. if (!cams) {
  87. return;
  88. }
  89. const indicesToDelete = [];
  90. let i;
  91. for (i = 0; i < cams.length; i++) {
  92. const camera = cams[i];
  93. if (!camera) {
  94. continue;
  95. }
  96. if (this._cameras.indexOf(camera) === -1) {
  97. this._cameras.push(camera);
  98. }
  99. else if (unique) {
  100. indicesToDelete.push(i);
  101. }
  102. }
  103. for (i = 0; i < indicesToDelete.length; i++) {
  104. cams.splice(indicesToDelete[i], 1);
  105. }
  106. for (const renderEffectName in this._renderEffects) {
  107. if (Object.prototype.hasOwnProperty.call(this._renderEffects, renderEffectName)) {
  108. this._renderEffects[renderEffectName]._attachCameras(cams);
  109. }
  110. }
  111. }
  112. /**
  113. * @internal
  114. */
  115. _detachCameras(cameras) {
  116. const cams = Tools.MakeArray(cameras || this._cameras);
  117. if (!cams) {
  118. return;
  119. }
  120. for (const renderEffectName in this._renderEffects) {
  121. if (Object.prototype.hasOwnProperty.call(this._renderEffects, renderEffectName)) {
  122. this._renderEffects[renderEffectName]._detachCameras(cams);
  123. }
  124. }
  125. for (let i = 0; i < cams.length; i++) {
  126. this._cameras.splice(this._cameras.indexOf(cams[i]), 1);
  127. }
  128. }
  129. /** @internal */
  130. _update() {
  131. for (const renderEffectName in this._renderEffects) {
  132. if (Object.prototype.hasOwnProperty.call(this._renderEffects, renderEffectName)) {
  133. this._renderEffects[renderEffectName]._update();
  134. }
  135. }
  136. for (let i = 0; i < this._cameras.length; i++) {
  137. if (!this._cameras[i]) {
  138. continue;
  139. }
  140. const cameraName = this._cameras[i].name;
  141. if (this._renderEffectsForIsolatedPass[cameraName]) {
  142. this._renderEffectsForIsolatedPass[cameraName]._update();
  143. }
  144. }
  145. }
  146. /** @internal */
  147. _reset() {
  148. this._renderEffects = {};
  149. this._renderEffectsForIsolatedPass = new Array();
  150. }
  151. _enableMSAAOnFirstPostProcess(sampleCount) {
  152. if (!this._engine._features.supportMSAA) {
  153. return false;
  154. }
  155. // 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)
  156. const effectKeys = Object.keys(this._renderEffects);
  157. if (effectKeys.length > 0) {
  158. const postProcesses = this._renderEffects[effectKeys[0]].getPostProcesses();
  159. if (postProcesses) {
  160. postProcesses[0].samples = sampleCount;
  161. }
  162. }
  163. return true;
  164. }
  165. /**
  166. * Ensures that all post processes in the pipeline are the correct size according to the
  167. * the viewport's required size
  168. */
  169. _adaptPostProcessesToViewPort() {
  170. const effectKeys = Object.keys(this._renderEffects);
  171. for (const effectKey of effectKeys) {
  172. const postProcesses = this._renderEffects[effectKey].getPostProcesses();
  173. if (postProcesses) {
  174. for (const postProcess of postProcesses) {
  175. postProcess.adaptScaleToCurrentViewport = true;
  176. }
  177. }
  178. }
  179. }
  180. /**
  181. * Sets the required values to the prepass renderer.
  182. * @param prePassRenderer defines the prepass renderer to setup.
  183. * @returns true if the pre pass is needed.
  184. */
  185. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  186. setPrePassRenderer(prePassRenderer) {
  187. // Do Nothing by default
  188. return false;
  189. }
  190. /**
  191. * Disposes of the pipeline
  192. */
  193. dispose() {
  194. // Must be implemented by children
  195. }
  196. }
  197. __decorate([
  198. serialize()
  199. ], PostProcessRenderPipeline.prototype, "_name", void 0);
  200. //# sourceMappingURL=postProcessRenderPipeline.js.map