babylon.renderTargetTexture.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. var __extends = (this && this.__extends) || function (d, b) {
  2. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  3. function __() { this.constructor = d; }
  4. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  5. };
  6. var BABYLON;
  7. (function (BABYLON) {
  8. var RenderTargetTexture = (function (_super) {
  9. __extends(RenderTargetTexture, _super);
  10. function RenderTargetTexture(name, size, scene, generateMipMaps, doNotChangeAspectRatio, type, isCube, samplingMode) {
  11. if (doNotChangeAspectRatio === void 0) { doNotChangeAspectRatio = true; }
  12. if (type === void 0) { type = BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT; }
  13. if (isCube === void 0) { isCube = false; }
  14. if (samplingMode === void 0) { samplingMode = BABYLON.Texture.TRILINEAR_SAMPLINGMODE; }
  15. _super.call(this, null, scene, !generateMipMaps);
  16. this.isCube = isCube;
  17. /**
  18. * Use this list to define the list of mesh you want to render.
  19. */
  20. this.renderList = new Array();
  21. this.renderParticles = true;
  22. this.renderSprites = false;
  23. this.coordinatesMode = BABYLON.Texture.PROJECTION_MODE;
  24. // Events
  25. /**
  26. * An event triggered when the texture is unbind.
  27. * @type {BABYLON.Observable}
  28. */
  29. this.onAfterUnbindObservable = new BABYLON.Observable();
  30. /**
  31. * An event triggered before rendering the texture
  32. * @type {BABYLON.Observable}
  33. */
  34. this.onBeforeRenderObservable = new BABYLON.Observable();
  35. /**
  36. * An event triggered after rendering the texture
  37. * @type {BABYLON.Observable}
  38. */
  39. this.onAfterRenderObservable = new BABYLON.Observable();
  40. /**
  41. * An event triggered after the texture clear
  42. * @type {BABYLON.Observable}
  43. */
  44. this.onClearObservable = new BABYLON.Observable();
  45. this._currentRefreshId = -1;
  46. this._refreshRate = 1;
  47. this.name = name;
  48. this.isRenderTarget = true;
  49. this._size = size;
  50. this._generateMipMaps = generateMipMaps;
  51. this._doNotChangeAspectRatio = doNotChangeAspectRatio;
  52. if (samplingMode === BABYLON.Texture.NEAREST_SAMPLINGMODE) {
  53. this.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE;
  54. this.wrapV = BABYLON.Texture.CLAMP_ADDRESSMODE;
  55. }
  56. if (isCube) {
  57. this._texture = scene.getEngine().createRenderTargetCubeTexture(size, { generateMipMaps: generateMipMaps, samplingMode: samplingMode });
  58. this.coordinatesMode = BABYLON.Texture.INVCUBIC_MODE;
  59. this._textureMatrix = BABYLON.Matrix.Identity();
  60. }
  61. else {
  62. this._texture = scene.getEngine().createRenderTargetTexture(size, { generateMipMaps: generateMipMaps, type: type, samplingMode: samplingMode });
  63. }
  64. // Rendering groups
  65. this._renderingManager = new BABYLON.RenderingManager(scene);
  66. }
  67. Object.defineProperty(RenderTargetTexture, "REFRESHRATE_RENDER_ONCE", {
  68. get: function () {
  69. return RenderTargetTexture._REFRESHRATE_RENDER_ONCE;
  70. },
  71. enumerable: true,
  72. configurable: true
  73. });
  74. Object.defineProperty(RenderTargetTexture, "REFRESHRATE_RENDER_ONEVERYFRAME", {
  75. get: function () {
  76. return RenderTargetTexture._REFRESHRATE_RENDER_ONEVERYFRAME;
  77. },
  78. enumerable: true,
  79. configurable: true
  80. });
  81. Object.defineProperty(RenderTargetTexture, "REFRESHRATE_RENDER_ONEVERYTWOFRAMES", {
  82. get: function () {
  83. return RenderTargetTexture._REFRESHRATE_RENDER_ONEVERYTWOFRAMES;
  84. },
  85. enumerable: true,
  86. configurable: true
  87. });
  88. Object.defineProperty(RenderTargetTexture.prototype, "onAfterUnbind", {
  89. set: function (callback) {
  90. if (this._onAfterUnbindObserver) {
  91. this.onAfterUnbindObservable.remove(this._onAfterUnbindObserver);
  92. }
  93. this._onAfterUnbindObserver = this.onAfterUnbindObservable.add(callback);
  94. },
  95. enumerable: true,
  96. configurable: true
  97. });
  98. Object.defineProperty(RenderTargetTexture.prototype, "onBeforeRender", {
  99. set: function (callback) {
  100. if (this._onBeforeRenderObserver) {
  101. this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);
  102. }
  103. this._onBeforeRenderObserver = this.onBeforeRenderObservable.add(callback);
  104. },
  105. enumerable: true,
  106. configurable: true
  107. });
  108. Object.defineProperty(RenderTargetTexture.prototype, "onAfterRender", {
  109. set: function (callback) {
  110. if (this._onAfterRenderObserver) {
  111. this.onAfterRenderObservable.remove(this._onAfterRenderObserver);
  112. }
  113. this._onAfterRenderObserver = this.onAfterRenderObservable.add(callback);
  114. },
  115. enumerable: true,
  116. configurable: true
  117. });
  118. Object.defineProperty(RenderTargetTexture.prototype, "onClear", {
  119. set: function (callback) {
  120. if (this._onClearObserver) {
  121. this.onClearObservable.remove(this._onClearObserver);
  122. }
  123. this._onClearObserver = this.onClearObservable.add(callback);
  124. },
  125. enumerable: true,
  126. configurable: true
  127. });
  128. RenderTargetTexture.prototype.resetRefreshCounter = function () {
  129. this._currentRefreshId = -1;
  130. };
  131. Object.defineProperty(RenderTargetTexture.prototype, "refreshRate", {
  132. get: function () {
  133. return this._refreshRate;
  134. },
  135. // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
  136. set: function (value) {
  137. this._refreshRate = value;
  138. this.resetRefreshCounter();
  139. },
  140. enumerable: true,
  141. configurable: true
  142. });
  143. RenderTargetTexture.prototype._shouldRender = function () {
  144. if (this._currentRefreshId === -1) {
  145. this._currentRefreshId = 1;
  146. return true;
  147. }
  148. if (this.refreshRate === this._currentRefreshId) {
  149. this._currentRefreshId = 1;
  150. return true;
  151. }
  152. this._currentRefreshId++;
  153. return false;
  154. };
  155. RenderTargetTexture.prototype.isReady = function () {
  156. if (!this.getScene().renderTargetsEnabled) {
  157. return false;
  158. }
  159. return _super.prototype.isReady.call(this);
  160. };
  161. RenderTargetTexture.prototype.getRenderSize = function () {
  162. return this._size;
  163. };
  164. Object.defineProperty(RenderTargetTexture.prototype, "canRescale", {
  165. get: function () {
  166. return true;
  167. },
  168. enumerable: true,
  169. configurable: true
  170. });
  171. RenderTargetTexture.prototype.scale = function (ratio) {
  172. var newSize = this._size * ratio;
  173. this.resize(newSize, this._generateMipMaps);
  174. };
  175. RenderTargetTexture.prototype.getReflectionTextureMatrix = function () {
  176. if (this.isCube) {
  177. return this._textureMatrix;
  178. }
  179. return _super.prototype.getReflectionTextureMatrix.call(this);
  180. };
  181. RenderTargetTexture.prototype.resize = function (size, generateMipMaps) {
  182. this.releaseInternalTexture();
  183. if (this.isCube) {
  184. this._texture = this.getScene().getEngine().createRenderTargetCubeTexture(size);
  185. }
  186. else {
  187. this._texture = this.getScene().getEngine().createRenderTargetTexture(size, generateMipMaps);
  188. }
  189. };
  190. RenderTargetTexture.prototype.render = function (useCameraPostProcess, dumpForDebug) {
  191. var scene = this.getScene();
  192. if (this.useCameraPostProcesses !== undefined) {
  193. useCameraPostProcess = this.useCameraPostProcesses;
  194. }
  195. if (this.activeCamera && this.activeCamera !== scene.activeCamera) {
  196. scene.setTransformMatrix(this.activeCamera.getViewMatrix(), this.activeCamera.getProjectionMatrix(true));
  197. }
  198. if (this._waitingRenderList) {
  199. this.renderList = [];
  200. for (var index = 0; index < this._waitingRenderList.length; index++) {
  201. var id = this._waitingRenderList[index];
  202. this.renderList.push(scene.getMeshByID(id));
  203. }
  204. delete this._waitingRenderList;
  205. }
  206. // Is predicate defined?
  207. if (this.renderListPredicate) {
  208. this.renderList.splice(0); // Clear previous renderList
  209. var sceneMeshes = this.getScene().meshes;
  210. for (var index = 0; index < sceneMeshes.length; index++) {
  211. var mesh = sceneMeshes[index];
  212. if (this.renderListPredicate(mesh)) {
  213. this.renderList.push(mesh);
  214. }
  215. }
  216. }
  217. if (this.renderList && this.renderList.length === 0) {
  218. return;
  219. }
  220. // Prepare renderingManager
  221. this._renderingManager.reset();
  222. var currentRenderList = this.renderList ? this.renderList : scene.getActiveMeshes().data;
  223. var currentRenderListLength = this.renderList ? this.renderList.length : scene.getActiveMeshes().length;
  224. var sceneRenderId = scene.getRenderId();
  225. for (var meshIndex = 0; meshIndex < currentRenderListLength; meshIndex++) {
  226. var mesh = currentRenderList[meshIndex];
  227. if (mesh) {
  228. if (!mesh.isReady()) {
  229. // Reset _currentRefreshId
  230. this.resetRefreshCounter();
  231. continue;
  232. }
  233. mesh._preActivateForIntermediateRendering(sceneRenderId);
  234. if (mesh.isEnabled() && mesh.isVisible && mesh.subMeshes && ((mesh.layerMask & scene.activeCamera.layerMask) !== 0)) {
  235. mesh._activate(sceneRenderId);
  236. for (var subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
  237. var subMesh = mesh.subMeshes[subIndex];
  238. scene._activeIndices.addCount(subMesh.indexCount, false);
  239. this._renderingManager.dispatch(subMesh);
  240. }
  241. }
  242. }
  243. }
  244. if (this.isCube) {
  245. for (var face = 0; face < 6; face++) {
  246. this.renderToTarget(face, currentRenderList, currentRenderListLength, useCameraPostProcess, dumpForDebug);
  247. scene.incrementRenderId();
  248. scene.resetCachedMaterial();
  249. }
  250. }
  251. else {
  252. this.renderToTarget(0, currentRenderList, currentRenderListLength, useCameraPostProcess, dumpForDebug);
  253. }
  254. this.onAfterUnbindObservable.notifyObservers(this);
  255. if (this.activeCamera && this.activeCamera !== scene.activeCamera) {
  256. scene.setTransformMatrix(scene.activeCamera.getViewMatrix(), scene.activeCamera.getProjectionMatrix(true));
  257. }
  258. scene.resetCachedMaterial();
  259. };
  260. RenderTargetTexture.prototype.renderToTarget = function (faceIndex, currentRenderList, currentRenderListLength, useCameraPostProcess, dumpForDebug) {
  261. var scene = this.getScene();
  262. var engine = scene.getEngine();
  263. // Bind
  264. if (!useCameraPostProcess || !scene.postProcessManager._prepareFrame(this._texture)) {
  265. if (this.isCube) {
  266. engine.bindFramebuffer(this._texture, faceIndex);
  267. }
  268. else {
  269. engine.bindFramebuffer(this._texture);
  270. }
  271. }
  272. this.onBeforeRenderObservable.notifyObservers(faceIndex);
  273. // Clear
  274. if (this.onClearObservable.hasObservers()) {
  275. this.onClearObservable.notifyObservers(engine);
  276. }
  277. else {
  278. engine.clear(scene.clearColor, true, true);
  279. }
  280. if (!this._doNotChangeAspectRatio) {
  281. scene.updateTransformMatrix(true);
  282. }
  283. // Render
  284. this._renderingManager.render(this.customRenderFunction, currentRenderList, this.renderParticles, this.renderSprites);
  285. if (useCameraPostProcess) {
  286. scene.postProcessManager._finalizeFrame(false, this._texture, faceIndex);
  287. }
  288. if (!this._doNotChangeAspectRatio) {
  289. scene.updateTransformMatrix(true);
  290. }
  291. this.onAfterRenderObservable.notifyObservers(faceIndex);
  292. // Dump ?
  293. if (dumpForDebug) {
  294. BABYLON.Tools.DumpFramebuffer(this._size, this._size, engine);
  295. }
  296. // Unbind
  297. if (!this.isCube || faceIndex === 5) {
  298. if (this.isCube) {
  299. if (faceIndex === 5) {
  300. engine.generateMipMapsForCubemap(this._texture);
  301. }
  302. }
  303. engine.unBindFramebuffer(this._texture, this.isCube);
  304. }
  305. };
  306. RenderTargetTexture.prototype.clone = function () {
  307. var textureSize = this.getSize();
  308. var newTexture = new RenderTargetTexture(this.name, textureSize.width, this.getScene(), this._generateMipMaps);
  309. // Base texture
  310. newTexture.hasAlpha = this.hasAlpha;
  311. newTexture.level = this.level;
  312. // RenderTarget Texture
  313. newTexture.coordinatesMode = this.coordinatesMode;
  314. newTexture.renderList = this.renderList.slice(0);
  315. return newTexture;
  316. };
  317. RenderTargetTexture.prototype.serialize = function () {
  318. if (!this.name) {
  319. return null;
  320. }
  321. var serializationObject = _super.prototype.serialize.call(this);
  322. serializationObject.renderTargetSize = this.getRenderSize();
  323. serializationObject.renderList = [];
  324. for (var index = 0; index < this.renderList.length; index++) {
  325. serializationObject.renderList.push(this.renderList[index].id);
  326. }
  327. return serializationObject;
  328. };
  329. RenderTargetTexture._REFRESHRATE_RENDER_ONCE = 0;
  330. RenderTargetTexture._REFRESHRATE_RENDER_ONEVERYFRAME = 1;
  331. RenderTargetTexture._REFRESHRATE_RENDER_ONEVERYTWOFRAMES = 2;
  332. return RenderTargetTexture;
  333. })(BABYLON.Texture);
  334. BABYLON.RenderTargetTexture = RenderTargetTexture;
  335. })(BABYLON || (BABYLON = {}));