babylon.postProcessRenderEffect.ts 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. module BABYLON {
  2. export class PostProcessRenderEffect {
  3. private _engine: Engine;
  4. private _name: string;
  5. private _postProcesses: PostProcess[];
  6. private _postProcessType;
  7. private _ratio: number;
  8. private _samplingMode: number;
  9. private _singleInstance: boolean;
  10. private _cameras: Camera[];
  11. private _indicesForCamera: number[];
  12. private _renderPasses: PostProcessRenderPass[];
  13. private _renderEffectAsPasses: PostProcessRenderEffect[];
  14. public name: string;
  15. public parameters: (effect) => void;
  16. constructor(engine: Engine, name: string, postProcessType, ratio: number, samplingMode: number, singleInstance: boolean) {
  17. this.name = name;
  18. this._engine = engine;
  19. this._name = name;
  20. this._postProcessType = postProcessType;
  21. this._ratio = ratio || 1.0;
  22. this._samplingMode = samplingMode || null;
  23. this._singleInstance = singleInstance || true;
  24. this._cameras = [];
  25. this._postProcesses = [];
  26. this._indicesForCamera = [];
  27. this._renderPasses = [];
  28. this._renderEffectAsPasses = [];
  29. this.parameters = function () { };
  30. }
  31. public static getInstance(engine: Engine, postProcessType, ratio: number, samplingMode: number): PostProcess {
  32. var tmpClass;
  33. var instance;
  34. var args = new Array();
  35. var parameters = PostProcessRenderEffect.getParametersNames(postProcessType);
  36. for (var i = 0; i < parameters.length; i++) {
  37. switch (parameters[i]) {
  38. case "name":
  39. args[i] = postProcessType.toString();
  40. break;
  41. case "ratio":
  42. args[i] = ratio;
  43. break;
  44. case "camera":
  45. args[i] = null;
  46. break;
  47. case "samplingMode":
  48. args[i] = samplingMode;
  49. break;
  50. case "engine":
  51. args[i] = engine;
  52. break;
  53. case "reusable":
  54. args[i] = true;
  55. break;
  56. default:
  57. args[i] = null;
  58. break;
  59. }
  60. }
  61. tmpClass = function () { };
  62. tmpClass.prototype = postProcessType.prototype;
  63. instance = new tmpClass();
  64. postProcessType.apply(instance, args);
  65. return instance;
  66. }
  67. public static getParametersNames(func): string[] {
  68. var commentsRegex = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
  69. var functWithoutComments = eval(func).toString().replace(commentsRegex, '');
  70. var parameters = functWithoutComments.slice(functWithoutComments.indexOf('(') + 1, functWithoutComments.indexOf(')')).match(/([^\s,]+)/g);
  71. if (parameters === null)
  72. parameters = [];
  73. return parameters;
  74. }
  75. public _update(): void {
  76. for (var renderPassName in this._renderPasses) {
  77. this._renderPasses[renderPassName]._update();
  78. }
  79. }
  80. public addPass(renderPass: PostProcessRenderPass): void {
  81. this._renderPasses[renderPass.name] = renderPass;
  82. this._linkParameters();
  83. }
  84. public removePass(renderPass: PostProcessRenderPass): void {
  85. delete this._renderPasses[renderPass.name];
  86. this._linkParameters();
  87. }
  88. public addRenderEffectAsPass(renderEffect: PostProcessRenderEffect): void {
  89. this._renderEffectAsPasses[renderEffect.name] = renderEffect;
  90. this._linkParameters();
  91. }
  92. public getPass(passName: string): void {
  93. for (var renderPassName in this._renderPasses) {
  94. if (renderPassName == passName) {
  95. return this._renderPasses[passName];
  96. }
  97. }
  98. }
  99. public emptyPasses(): void {
  100. this._renderPasses.length = 0;
  101. this._linkParameters();
  102. }
  103. public attachCameras(cameras: Camera[]): void {
  104. var postProcess = null;
  105. cameras = Tools.MakeArray(cameras || this._cameras);
  106. for (var i = 0; i < cameras.length; i++) {
  107. if (this._singleInstance) {
  108. postProcess = this._postProcesses[0] || PostProcessRenderEffect.getInstance(this._engine, this._postProcessType, this._ratio, this._samplingMode);
  109. this._postProcesses[0] = postProcess;
  110. }
  111. else {
  112. postProcess = this._postProcesses[cameras[i].name] || PostProcessRenderEffect.getInstance(this._engine, this._postProcessType, this._ratio, this._samplingMode);
  113. this._postProcesses[cameras[i].name] = postProcess;
  114. }
  115. var index = cameras[i].attachPostProcess(postProcess);
  116. if (this._indicesForCamera[cameras[i].name] == null) {
  117. this._indicesForCamera[cameras[i].name] = [];
  118. }
  119. this._indicesForCamera[cameras[i].name].push(index);
  120. if (this._cameras.indexOf(cameras[i]) == -1) {
  121. this._cameras.push(cameras[i]);
  122. }
  123. for (var passName in this._renderPasses) {
  124. this._renderPasses[passName].incRefCount();
  125. }
  126. }
  127. this._linkParameters();
  128. }
  129. public detachCamera(cameras): void {
  130. cameras = Tools.MakeArray(cameras || this._cameras);
  131. for (var i = 0; i < cameras.length; i++) {
  132. if (this._singleInstance) {
  133. cameras[i].detachPostProcess(this._postProcesses[0], this._indicesForCamera[cameras[i].name]);
  134. }
  135. else {
  136. cameras[i].detachPostProcess(this._postProcesses[cameras[i].name], this._indicesForCamera[cameras[i].name]);
  137. }
  138. var index = this._cameras.indexOf(cameras[i].name);
  139. this._indicesForCamera.splice(index, 1);
  140. this._cameras.splice(index, 1);
  141. for (var passName in this._renderPasses) {
  142. this._renderPasses[passName].decRefCount();
  143. }
  144. }
  145. }
  146. public enable(cameras: Camera[]): void {
  147. cameras = Tools.MakeArray(cameras || this._cameras);
  148. for (var i = 0; i < cameras.length; i++) {
  149. for (var j = 0; j < this._indicesForCamera[cameras[i].name].length; j++) {
  150. if (cameras[i]._postProcesses[this._indicesForCamera[cameras[i].name][j]] === undefined) {
  151. if (this._singleInstance) {
  152. cameras[i].attachPostProcess(this._postProcesses[0], this._indicesForCamera[cameras[i].name][j]);
  153. }
  154. else {
  155. cameras[i].attachPostProcess(this._postProcesses[cameras[i].name], this._indicesForCamera[cameras[i].name][j]);
  156. }
  157. }
  158. }
  159. for (var passName in this._renderPasses) {
  160. this._renderPasses[passName].incRefCount();
  161. }
  162. }
  163. }
  164. public disable(cameras: Camera[]): void {
  165. cameras = Tools.MakeArray(cameras || this._cameras);
  166. for (var i = 0; i < cameras.length; i++) {
  167. if (this._singleInstance) {
  168. cameras[i].detachPostProcess(this._postProcesses[0], this._indicesForCamera[cameras[i].name]);
  169. }
  170. else {
  171. cameras[i].detachPostProcess(this._postProcesses[cameras[i].name], this._indicesForCamera[cameras[i].name]);
  172. }
  173. for (var passName in this._renderPasses) {
  174. this._renderPasses[passName].decRefCount();
  175. }
  176. }
  177. }
  178. public getPostProcess(): PostProcess {
  179. return this._postProcesses[0];
  180. }
  181. private _linkParameters(): void {
  182. var that = this;
  183. for (var index in this._postProcesses) {
  184. this._postProcesses[index].onApply = function (effect) {
  185. that.parameters(effect);
  186. that._linkTextures(effect);
  187. };
  188. }
  189. }
  190. private _linkTextures(effect): void {
  191. for (var renderPassName in this._renderPasses) {
  192. effect.setTexture(renderPassName, this._renderPasses[renderPassName].getRenderTexture());
  193. }
  194. for (var renderEffectName in this._renderEffectAsPasses) {
  195. effect.setTextureFromPostProcess(renderEffectName + "Sampler", this._renderEffectAsPasses[renderEffectName].getPostProcess());
  196. }
  197. }
  198. }
  199. }