babylon.renderTargetTexture.js 17 KB

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