babylon.renderTargetTexture.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  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 sceneRenderId = scene.getRenderId();
  224. for (var meshIndex = 0; meshIndex < currentRenderList.length; meshIndex++) {
  225. var mesh = currentRenderList[meshIndex];
  226. if (mesh) {
  227. if (!mesh.isReady()) {
  228. // Reset _currentRefreshId
  229. this.resetRefreshCounter();
  230. continue;
  231. }
  232. mesh._preActivateForIntermediateRendering(sceneRenderId);
  233. if (mesh.isEnabled() && mesh.isVisible && mesh.subMeshes && ((mesh.layerMask & scene.activeCamera.layerMask) !== 0)) {
  234. mesh._activate(sceneRenderId);
  235. for (var subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
  236. var subMesh = mesh.subMeshes[subIndex];
  237. scene._activeIndices += subMesh.indexCount;
  238. this._renderingManager.dispatch(subMesh);
  239. }
  240. }
  241. }
  242. }
  243. if (this.isCube) {
  244. for (var face = 0; face < 6; face++) {
  245. this.renderToTarget(face, currentRenderList, useCameraPostProcess, dumpForDebug);
  246. scene.incrementRenderId();
  247. scene.resetCachedMaterial();
  248. }
  249. }
  250. else {
  251. this.renderToTarget(0, currentRenderList, useCameraPostProcess, dumpForDebug);
  252. }
  253. this.onAfterUnbindObservable.notifyObservers(this);
  254. if (this.activeCamera && this.activeCamera !== scene.activeCamera) {
  255. scene.setTransformMatrix(scene.activeCamera.getViewMatrix(), scene.activeCamera.getProjectionMatrix(true));
  256. }
  257. scene.resetCachedMaterial();
  258. };
  259. RenderTargetTexture.prototype.renderToTarget = function (faceIndex, currentRenderList, useCameraPostProcess, dumpForDebug) {
  260. var scene = this.getScene();
  261. var engine = scene.getEngine();
  262. // Bind
  263. if (!useCameraPostProcess || !scene.postProcessManager._prepareFrame(this._texture)) {
  264. if (this.isCube) {
  265. engine.bindFramebuffer(this._texture, faceIndex);
  266. }
  267. else {
  268. engine.bindFramebuffer(this._texture);
  269. }
  270. }
  271. this.onBeforeRenderObservable.notifyObservers(faceIndex);
  272. // Clear
  273. if (this.onClearObservable.hasObservers()) {
  274. this.onClearObservable.notifyObservers(engine);
  275. }
  276. else {
  277. engine.clear(scene.clearColor, true, true);
  278. }
  279. if (!this._doNotChangeAspectRatio) {
  280. scene.updateTransformMatrix(true);
  281. }
  282. // Render
  283. this._renderingManager.render(this.customRenderFunction, currentRenderList, this.renderParticles, this.renderSprites);
  284. if (useCameraPostProcess) {
  285. scene.postProcessManager._finalizeFrame(false, this._texture, faceIndex);
  286. }
  287. if (!this._doNotChangeAspectRatio) {
  288. scene.updateTransformMatrix(true);
  289. }
  290. this.onAfterRenderObservable.notifyObservers(faceIndex);
  291. // Dump ?
  292. if (dumpForDebug) {
  293. BABYLON.Tools.DumpFramebuffer(this._size, this._size, engine);
  294. }
  295. // Unbind
  296. if (!this.isCube || faceIndex === 5) {
  297. if (this.isCube) {
  298. if (faceIndex === 5) {
  299. engine.generateMipMapsForCubemap(this._texture);
  300. }
  301. }
  302. engine.unBindFramebuffer(this._texture, this.isCube);
  303. }
  304. };
  305. RenderTargetTexture.prototype.clone = function () {
  306. var textureSize = this.getSize();
  307. var newTexture = new RenderTargetTexture(this.name, textureSize.width, this.getScene(), this._generateMipMaps);
  308. // Base texture
  309. newTexture.hasAlpha = this.hasAlpha;
  310. newTexture.level = this.level;
  311. // RenderTarget Texture
  312. newTexture.coordinatesMode = this.coordinatesMode;
  313. newTexture.renderList = this.renderList.slice(0);
  314. return newTexture;
  315. };
  316. RenderTargetTexture.prototype.serialize = function () {
  317. if (!this.name) {
  318. return null;
  319. }
  320. var serializationObject = _super.prototype.serialize.call(this);
  321. serializationObject.renderTargetSize = this.getRenderSize();
  322. serializationObject.renderList = [];
  323. for (var index = 0; index < this.renderList.length; index++) {
  324. serializationObject.renderList.push(this.renderList[index].id);
  325. }
  326. return serializationObject;
  327. };
  328. RenderTargetTexture._REFRESHRATE_RENDER_ONCE = 0;
  329. RenderTargetTexture._REFRESHRATE_RENDER_ONEVERYFRAME = 1;
  330. RenderTargetTexture._REFRESHRATE_RENDER_ONEVERYTWOFRAMES = 2;
  331. return RenderTargetTexture;
  332. }(BABYLON.Texture));
  333. BABYLON.RenderTargetTexture = RenderTargetTexture;
  334. })(BABYLON || (BABYLON = {}));