index.js 95 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062
  1. var __extends = (this && this.__extends) || (function () {
  2. var extendStatics = Object.setPrototypeOf ||
  3. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  4. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  5. return function (d, b) {
  6. extendStatics(d, b);
  7. function __() { this.constructor = d; }
  8. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  9. };
  10. })();
  11. if(typeof require !== 'undefined'){
  12. var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : this);
  13. var BABYLON = globalObject["BABYLON"] || {};
  14. var BABYLON0 = require('babylonjs/core');
  15. if(BABYLON !== BABYLON0) __extends(BABYLON, BABYLON0);
  16. var BABYLON;
  17. (function (BABYLON) {
  18. var SimplificationSettings = /** @class */ (function () {
  19. function SimplificationSettings(quality, distance, optimizeMesh) {
  20. this.quality = quality;
  21. this.distance = distance;
  22. this.optimizeMesh = optimizeMesh;
  23. }
  24. return SimplificationSettings;
  25. }());
  26. BABYLON.SimplificationSettings = SimplificationSettings;
  27. var SimplificationQueue = /** @class */ (function () {
  28. function SimplificationQueue() {
  29. this.running = false;
  30. this._simplificationArray = [];
  31. }
  32. SimplificationQueue.prototype.addTask = function (task) {
  33. this._simplificationArray.push(task);
  34. };
  35. SimplificationQueue.prototype.executeNext = function () {
  36. var task = this._simplificationArray.pop();
  37. if (task) {
  38. this.running = true;
  39. this.runSimplification(task);
  40. }
  41. else {
  42. this.running = false;
  43. }
  44. };
  45. SimplificationQueue.prototype.runSimplification = function (task) {
  46. var _this = this;
  47. if (task.parallelProcessing) {
  48. //parallel simplifier
  49. task.settings.forEach(function (setting) {
  50. var simplifier = _this.getSimplifier(task);
  51. simplifier.simplify(setting, function (newMesh) {
  52. task.mesh.addLODLevel(setting.distance, newMesh);
  53. newMesh.isVisible = true;
  54. //check if it is the last
  55. if (setting.quality === task.settings[task.settings.length - 1].quality && task.successCallback) {
  56. //all done, run the success callback.
  57. task.successCallback();
  58. }
  59. _this.executeNext();
  60. });
  61. });
  62. }
  63. else {
  64. //single simplifier.
  65. var simplifier = this.getSimplifier(task);
  66. var runDecimation = function (setting, callback) {
  67. simplifier.simplify(setting, function (newMesh) {
  68. task.mesh.addLODLevel(setting.distance, newMesh);
  69. newMesh.isVisible = true;
  70. //run the next quality level
  71. callback();
  72. });
  73. };
  74. BABYLON.AsyncLoop.Run(task.settings.length, function (loop) {
  75. runDecimation(task.settings[loop.index], function () {
  76. loop.executeNext();
  77. });
  78. }, function () {
  79. //execution ended, run the success callback.
  80. if (task.successCallback) {
  81. task.successCallback();
  82. }
  83. _this.executeNext();
  84. });
  85. }
  86. };
  87. SimplificationQueue.prototype.getSimplifier = function (task) {
  88. switch (task.simplificationType) {
  89. case SimplificationType.QUADRATIC:
  90. default:
  91. return new QuadraticErrorSimplification(task.mesh);
  92. }
  93. };
  94. return SimplificationQueue;
  95. }());
  96. BABYLON.SimplificationQueue = SimplificationQueue;
  97. /**
  98. * The implemented types of simplification.
  99. * At the moment only Quadratic Error Decimation is implemented.
  100. */
  101. var SimplificationType;
  102. (function (SimplificationType) {
  103. SimplificationType[SimplificationType["QUADRATIC"] = 0] = "QUADRATIC";
  104. })(SimplificationType = BABYLON.SimplificationType || (BABYLON.SimplificationType = {}));
  105. var DecimationTriangle = /** @class */ (function () {
  106. function DecimationTriangle(vertices) {
  107. this.vertices = vertices;
  108. this.error = new Array(4);
  109. this.deleted = false;
  110. this.isDirty = false;
  111. this.deletePending = false;
  112. this.borderFactor = 0;
  113. }
  114. return DecimationTriangle;
  115. }());
  116. BABYLON.DecimationTriangle = DecimationTriangle;
  117. var DecimationVertex = /** @class */ (function () {
  118. function DecimationVertex(position, id) {
  119. this.position = position;
  120. this.id = id;
  121. this.isBorder = true;
  122. this.q = new QuadraticMatrix();
  123. this.triangleCount = 0;
  124. this.triangleStart = 0;
  125. this.originalOffsets = [];
  126. }
  127. DecimationVertex.prototype.updatePosition = function (newPosition) {
  128. this.position.copyFrom(newPosition);
  129. };
  130. return DecimationVertex;
  131. }());
  132. BABYLON.DecimationVertex = DecimationVertex;
  133. var QuadraticMatrix = /** @class */ (function () {
  134. function QuadraticMatrix(data) {
  135. this.data = new Array(10);
  136. for (var i = 0; i < 10; ++i) {
  137. if (data && data[i]) {
  138. this.data[i] = data[i];
  139. }
  140. else {
  141. this.data[i] = 0;
  142. }
  143. }
  144. }
  145. QuadraticMatrix.prototype.det = function (a11, a12, a13, a21, a22, a23, a31, a32, a33) {
  146. var det = this.data[a11] * this.data[a22] * this.data[a33] + this.data[a13] * this.data[a21] * this.data[a32] +
  147. this.data[a12] * this.data[a23] * this.data[a31] - this.data[a13] * this.data[a22] * this.data[a31] -
  148. this.data[a11] * this.data[a23] * this.data[a32] - this.data[a12] * this.data[a21] * this.data[a33];
  149. return det;
  150. };
  151. QuadraticMatrix.prototype.addInPlace = function (matrix) {
  152. for (var i = 0; i < 10; ++i) {
  153. this.data[i] += matrix.data[i];
  154. }
  155. };
  156. QuadraticMatrix.prototype.addArrayInPlace = function (data) {
  157. for (var i = 0; i < 10; ++i) {
  158. this.data[i] += data[i];
  159. }
  160. };
  161. QuadraticMatrix.prototype.add = function (matrix) {
  162. var m = new QuadraticMatrix();
  163. for (var i = 0; i < 10; ++i) {
  164. m.data[i] = this.data[i] + matrix.data[i];
  165. }
  166. return m;
  167. };
  168. QuadraticMatrix.FromData = function (a, b, c, d) {
  169. return new QuadraticMatrix(QuadraticMatrix.DataFromNumbers(a, b, c, d));
  170. };
  171. //returning an array to avoid garbage collection
  172. QuadraticMatrix.DataFromNumbers = function (a, b, c, d) {
  173. return [a * a, a * b, a * c, a * d, b * b, b * c, b * d, c * c, c * d, d * d];
  174. };
  175. return QuadraticMatrix;
  176. }());
  177. BABYLON.QuadraticMatrix = QuadraticMatrix;
  178. var Reference = /** @class */ (function () {
  179. function Reference(vertexId, triangleId) {
  180. this.vertexId = vertexId;
  181. this.triangleId = triangleId;
  182. }
  183. return Reference;
  184. }());
  185. BABYLON.Reference = Reference;
  186. /**
  187. * An implementation of the Quadratic Error simplification algorithm.
  188. * Original paper : http://www1.cs.columbia.edu/~cs4162/html05s/garland97.pdf
  189. * Ported mostly from QSlim and http://voxels.blogspot.de/2014/05/quadric-mesh-simplification-with-source.html to babylon JS
  190. * @author RaananW
  191. */
  192. var QuadraticErrorSimplification = /** @class */ (function () {
  193. function QuadraticErrorSimplification(_mesh) {
  194. this._mesh = _mesh;
  195. this.syncIterations = 5000;
  196. this.aggressiveness = 7;
  197. this.decimationIterations = 100;
  198. this.boundingBoxEpsilon = BABYLON.Epsilon;
  199. }
  200. QuadraticErrorSimplification.prototype.simplify = function (settings, successCallback) {
  201. var _this = this;
  202. this.initDecimatedMesh();
  203. //iterating through the submeshes array, one after the other.
  204. BABYLON.AsyncLoop.Run(this._mesh.subMeshes.length, function (loop) {
  205. _this.initWithMesh(loop.index, function () {
  206. _this.runDecimation(settings, loop.index, function () {
  207. loop.executeNext();
  208. });
  209. }, settings.optimizeMesh);
  210. }, function () {
  211. setTimeout(function () {
  212. successCallback(_this._reconstructedMesh);
  213. }, 0);
  214. });
  215. };
  216. QuadraticErrorSimplification.prototype.runDecimation = function (settings, submeshIndex, successCallback) {
  217. var _this = this;
  218. var targetCount = ~~(this.triangles.length * settings.quality);
  219. var deletedTriangles = 0;
  220. var triangleCount = this.triangles.length;
  221. var iterationFunction = function (iteration, callback) {
  222. setTimeout(function () {
  223. if (iteration % 5 === 0) {
  224. _this.updateMesh(iteration === 0);
  225. }
  226. for (var i = 0; i < _this.triangles.length; ++i) {
  227. _this.triangles[i].isDirty = false;
  228. }
  229. var threshold = 0.000000001 * Math.pow((iteration + 3), _this.aggressiveness);
  230. var trianglesIterator = function (i) {
  231. var tIdx = ~~(((_this.triangles.length / 2) + i) % _this.triangles.length);
  232. var t = _this.triangles[tIdx];
  233. if (!t)
  234. return;
  235. if (t.error[3] > threshold || t.deleted || t.isDirty) {
  236. return;
  237. }
  238. for (var j = 0; j < 3; ++j) {
  239. if (t.error[j] < threshold) {
  240. var deleted0 = [];
  241. var deleted1 = [];
  242. var v0 = t.vertices[j];
  243. var v1 = t.vertices[(j + 1) % 3];
  244. if (v0.isBorder || v1.isBorder)
  245. continue;
  246. var p = BABYLON.Vector3.Zero();
  247. var n = BABYLON.Vector3.Zero();
  248. var uv = BABYLON.Vector2.Zero();
  249. var color = new BABYLON.Color4(0, 0, 0, 1);
  250. _this.calculateError(v0, v1, p, n, uv, color);
  251. var delTr = new Array();
  252. if (_this.isFlipped(v0, v1, p, deleted0, t.borderFactor, delTr))
  253. continue;
  254. if (_this.isFlipped(v1, v0, p, deleted1, t.borderFactor, delTr))
  255. continue;
  256. if (deleted0.indexOf(true) < 0 || deleted1.indexOf(true) < 0)
  257. continue;
  258. var uniqueArray = new Array();
  259. delTr.forEach(function (deletedT) {
  260. if (uniqueArray.indexOf(deletedT) === -1) {
  261. deletedT.deletePending = true;
  262. uniqueArray.push(deletedT);
  263. }
  264. });
  265. if (uniqueArray.length % 2 !== 0) {
  266. continue;
  267. }
  268. v0.q = v1.q.add(v0.q);
  269. v0.updatePosition(p);
  270. var tStart = _this.references.length;
  271. deletedTriangles = _this.updateTriangles(v0, v0, deleted0, deletedTriangles);
  272. deletedTriangles = _this.updateTriangles(v0, v1, deleted1, deletedTriangles);
  273. var tCount = _this.references.length - tStart;
  274. if (tCount <= v0.triangleCount) {
  275. if (tCount) {
  276. for (var c = 0; c < tCount; c++) {
  277. _this.references[v0.triangleStart + c] = _this.references[tStart + c];
  278. }
  279. }
  280. }
  281. else {
  282. v0.triangleStart = tStart;
  283. }
  284. v0.triangleCount = tCount;
  285. break;
  286. }
  287. }
  288. };
  289. BABYLON.AsyncLoop.SyncAsyncForLoop(_this.triangles.length, _this.syncIterations, trianglesIterator, callback, function () { return (triangleCount - deletedTriangles <= targetCount); });
  290. }, 0);
  291. };
  292. BABYLON.AsyncLoop.Run(this.decimationIterations, function (loop) {
  293. if (triangleCount - deletedTriangles <= targetCount)
  294. loop.breakLoop();
  295. else {
  296. iterationFunction(loop.index, function () {
  297. loop.executeNext();
  298. });
  299. }
  300. }, function () {
  301. setTimeout(function () {
  302. //reconstruct this part of the mesh
  303. _this.reconstructMesh(submeshIndex);
  304. successCallback();
  305. }, 0);
  306. });
  307. };
  308. QuadraticErrorSimplification.prototype.initWithMesh = function (submeshIndex, callback, optimizeMesh) {
  309. var _this = this;
  310. this.vertices = [];
  311. this.triangles = [];
  312. var positionData = this._mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
  313. var indices = this._mesh.getIndices();
  314. var submesh = this._mesh.subMeshes[submeshIndex];
  315. var findInVertices = function (positionToSearch) {
  316. if (optimizeMesh) {
  317. for (var ii = 0; ii < _this.vertices.length; ++ii) {
  318. if (_this.vertices[ii].position.equals(positionToSearch)) {
  319. return _this.vertices[ii];
  320. }
  321. }
  322. }
  323. return null;
  324. };
  325. var vertexReferences = [];
  326. var vertexInit = function (i) {
  327. if (!positionData) {
  328. return;
  329. }
  330. var offset = i + submesh.verticesStart;
  331. var position = BABYLON.Vector3.FromArray(positionData, offset * 3);
  332. var vertex = findInVertices(position) || new DecimationVertex(position, _this.vertices.length);
  333. vertex.originalOffsets.push(offset);
  334. if (vertex.id === _this.vertices.length) {
  335. _this.vertices.push(vertex);
  336. }
  337. vertexReferences.push(vertex.id);
  338. };
  339. //var totalVertices = mesh.getTotalVertices();
  340. var totalVertices = submesh.verticesCount;
  341. BABYLON.AsyncLoop.SyncAsyncForLoop(totalVertices, (this.syncIterations / 4) >> 0, vertexInit, function () {
  342. var indicesInit = function (i) {
  343. if (!indices) {
  344. return;
  345. }
  346. var offset = (submesh.indexStart / 3) + i;
  347. var pos = (offset * 3);
  348. var i0 = indices[pos + 0];
  349. var i1 = indices[pos + 1];
  350. var i2 = indices[pos + 2];
  351. var v0 = _this.vertices[vertexReferences[i0 - submesh.verticesStart]];
  352. var v1 = _this.vertices[vertexReferences[i1 - submesh.verticesStart]];
  353. var v2 = _this.vertices[vertexReferences[i2 - submesh.verticesStart]];
  354. var triangle = new DecimationTriangle([v0, v1, v2]);
  355. triangle.originalOffset = pos;
  356. _this.triangles.push(triangle);
  357. };
  358. BABYLON.AsyncLoop.SyncAsyncForLoop(submesh.indexCount / 3, _this.syncIterations, indicesInit, function () {
  359. _this.init(callback);
  360. });
  361. });
  362. };
  363. QuadraticErrorSimplification.prototype.init = function (callback) {
  364. var _this = this;
  365. var triangleInit1 = function (i) {
  366. var t = _this.triangles[i];
  367. t.normal = BABYLON.Vector3.Cross(t.vertices[1].position.subtract(t.vertices[0].position), t.vertices[2].position.subtract(t.vertices[0].position)).normalize();
  368. for (var j = 0; j < 3; j++) {
  369. t.vertices[j].q.addArrayInPlace(QuadraticMatrix.DataFromNumbers(t.normal.x, t.normal.y, t.normal.z, -(BABYLON.Vector3.Dot(t.normal, t.vertices[0].position))));
  370. }
  371. };
  372. BABYLON.AsyncLoop.SyncAsyncForLoop(this.triangles.length, this.syncIterations, triangleInit1, function () {
  373. var triangleInit2 = function (i) {
  374. var t = _this.triangles[i];
  375. for (var j = 0; j < 3; ++j) {
  376. t.error[j] = _this.calculateError(t.vertices[j], t.vertices[(j + 1) % 3]);
  377. }
  378. t.error[3] = Math.min(t.error[0], t.error[1], t.error[2]);
  379. };
  380. BABYLON.AsyncLoop.SyncAsyncForLoop(_this.triangles.length, _this.syncIterations, triangleInit2, function () {
  381. callback();
  382. });
  383. });
  384. };
  385. QuadraticErrorSimplification.prototype.reconstructMesh = function (submeshIndex) {
  386. var newTriangles = [];
  387. var i;
  388. for (i = 0; i < this.vertices.length; ++i) {
  389. this.vertices[i].triangleCount = 0;
  390. }
  391. var t;
  392. var j;
  393. for (i = 0; i < this.triangles.length; ++i) {
  394. if (!this.triangles[i].deleted) {
  395. t = this.triangles[i];
  396. for (j = 0; j < 3; ++j) {
  397. t.vertices[j].triangleCount = 1;
  398. }
  399. newTriangles.push(t);
  400. }
  401. }
  402. var newPositionData = (this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.PositionKind) || []);
  403. var newNormalData = (this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.NormalKind) || []);
  404. var newUVsData = (this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.UVKind) || []);
  405. var newColorsData = (this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.ColorKind) || []);
  406. var normalData = this._mesh.getVerticesData(BABYLON.VertexBuffer.NormalKind);
  407. var uvs = this._mesh.getVerticesData(BABYLON.VertexBuffer.UVKind);
  408. var colorsData = this._mesh.getVerticesData(BABYLON.VertexBuffer.ColorKind);
  409. var vertexCount = 0;
  410. for (i = 0; i < this.vertices.length; ++i) {
  411. var vertex = this.vertices[i];
  412. vertex.id = vertexCount;
  413. if (vertex.triangleCount) {
  414. vertex.originalOffsets.forEach(function (originalOffset) {
  415. if (!normalData) {
  416. return;
  417. }
  418. newPositionData.push(vertex.position.x);
  419. newPositionData.push(vertex.position.y);
  420. newPositionData.push(vertex.position.z);
  421. newNormalData.push(normalData[originalOffset * 3]);
  422. newNormalData.push(normalData[(originalOffset * 3) + 1]);
  423. newNormalData.push(normalData[(originalOffset * 3) + 2]);
  424. if (uvs && uvs.length) {
  425. newUVsData.push(uvs[(originalOffset * 2)]);
  426. newUVsData.push(uvs[(originalOffset * 2) + 1]);
  427. }
  428. else if (colorsData && colorsData.length) {
  429. newColorsData.push(colorsData[(originalOffset * 4)]);
  430. newColorsData.push(colorsData[(originalOffset * 4) + 1]);
  431. newColorsData.push(colorsData[(originalOffset * 4) + 2]);
  432. newColorsData.push(colorsData[(originalOffset * 4) + 3]);
  433. }
  434. ++vertexCount;
  435. });
  436. }
  437. }
  438. var startingIndex = this._reconstructedMesh.getTotalIndices();
  439. var startingVertex = this._reconstructedMesh.getTotalVertices();
  440. var submeshesArray = this._reconstructedMesh.subMeshes;
  441. this._reconstructedMesh.subMeshes = [];
  442. var newIndicesArray = this._reconstructedMesh.getIndices(); //[];
  443. var originalIndices = this._mesh.getIndices();
  444. for (i = 0; i < newTriangles.length; ++i) {
  445. t = newTriangles[i]; //now get the new referencing point for each vertex
  446. [0, 1, 2].forEach(function (idx) {
  447. var id = originalIndices[t.originalOffset + idx];
  448. var offset = t.vertices[idx].originalOffsets.indexOf(id);
  449. if (offset < 0)
  450. offset = 0;
  451. newIndicesArray.push(t.vertices[idx].id + offset + startingVertex);
  452. });
  453. }
  454. //overwriting the old vertex buffers and indices.
  455. this._reconstructedMesh.setIndices(newIndicesArray);
  456. this._reconstructedMesh.setVerticesData(BABYLON.VertexBuffer.PositionKind, newPositionData);
  457. this._reconstructedMesh.setVerticesData(BABYLON.VertexBuffer.NormalKind, newNormalData);
  458. if (newUVsData.length > 0)
  459. this._reconstructedMesh.setVerticesData(BABYLON.VertexBuffer.UVKind, newUVsData);
  460. if (newColorsData.length > 0)
  461. this._reconstructedMesh.setVerticesData(BABYLON.VertexBuffer.ColorKind, newColorsData);
  462. //create submesh
  463. var originalSubmesh = this._mesh.subMeshes[submeshIndex];
  464. if (submeshIndex > 0) {
  465. this._reconstructedMesh.subMeshes = [];
  466. submeshesArray.forEach(function (submesh) {
  467. BABYLON.SubMesh.AddToMesh(submesh.materialIndex, submesh.verticesStart, submesh.verticesCount, /* 0, newPositionData.length/3, */ submesh.indexStart, submesh.indexCount, submesh.getMesh());
  468. });
  469. BABYLON.SubMesh.AddToMesh(originalSubmesh.materialIndex, startingVertex, vertexCount, /* 0, newPositionData.length / 3, */ startingIndex, newTriangles.length * 3, this._reconstructedMesh);
  470. }
  471. };
  472. QuadraticErrorSimplification.prototype.initDecimatedMesh = function () {
  473. this._reconstructedMesh = new BABYLON.Mesh(this._mesh.name + "Decimated", this._mesh.getScene());
  474. this._reconstructedMesh.material = this._mesh.material;
  475. this._reconstructedMesh.parent = this._mesh.parent;
  476. this._reconstructedMesh.isVisible = false;
  477. this._reconstructedMesh.renderingGroupId = this._mesh.renderingGroupId;
  478. };
  479. QuadraticErrorSimplification.prototype.isFlipped = function (vertex1, vertex2, point, deletedArray, borderFactor, delTr) {
  480. for (var i = 0; i < vertex1.triangleCount; ++i) {
  481. var t = this.triangles[this.references[vertex1.triangleStart + i].triangleId];
  482. if (t.deleted)
  483. continue;
  484. var s = this.references[vertex1.triangleStart + i].vertexId;
  485. var v1 = t.vertices[(s + 1) % 3];
  486. var v2 = t.vertices[(s + 2) % 3];
  487. if ((v1 === vertex2 || v2 === vertex2)) {
  488. deletedArray[i] = true;
  489. delTr.push(t);
  490. continue;
  491. }
  492. var d1 = v1.position.subtract(point);
  493. d1 = d1.normalize();
  494. var d2 = v2.position.subtract(point);
  495. d2 = d2.normalize();
  496. if (Math.abs(BABYLON.Vector3.Dot(d1, d2)) > 0.999)
  497. return true;
  498. var normal = BABYLON.Vector3.Cross(d1, d2).normalize();
  499. deletedArray[i] = false;
  500. if (BABYLON.Vector3.Dot(normal, t.normal) < 0.2)
  501. return true;
  502. }
  503. return false;
  504. };
  505. QuadraticErrorSimplification.prototype.updateTriangles = function (origVertex, vertex, deletedArray, deletedTriangles) {
  506. var newDeleted = deletedTriangles;
  507. for (var i = 0; i < vertex.triangleCount; ++i) {
  508. var ref = this.references[vertex.triangleStart + i];
  509. var t = this.triangles[ref.triangleId];
  510. if (t.deleted)
  511. continue;
  512. if (deletedArray[i] && t.deletePending) {
  513. t.deleted = true;
  514. newDeleted++;
  515. continue;
  516. }
  517. t.vertices[ref.vertexId] = origVertex;
  518. t.isDirty = true;
  519. t.error[0] = this.calculateError(t.vertices[0], t.vertices[1]) + (t.borderFactor / 2);
  520. t.error[1] = this.calculateError(t.vertices[1], t.vertices[2]) + (t.borderFactor / 2);
  521. t.error[2] = this.calculateError(t.vertices[2], t.vertices[0]) + (t.borderFactor / 2);
  522. t.error[3] = Math.min(t.error[0], t.error[1], t.error[2]);
  523. this.references.push(ref);
  524. }
  525. return newDeleted;
  526. };
  527. QuadraticErrorSimplification.prototype.identifyBorder = function () {
  528. for (var i = 0; i < this.vertices.length; ++i) {
  529. var vCount = [];
  530. var vId = [];
  531. var v = this.vertices[i];
  532. var j;
  533. for (j = 0; j < v.triangleCount; ++j) {
  534. var triangle = this.triangles[this.references[v.triangleStart + j].triangleId];
  535. for (var ii = 0; ii < 3; ii++) {
  536. var ofs = 0;
  537. var vv = triangle.vertices[ii];
  538. while (ofs < vCount.length) {
  539. if (vId[ofs] === vv.id)
  540. break;
  541. ++ofs;
  542. }
  543. if (ofs === vCount.length) {
  544. vCount.push(1);
  545. vId.push(vv.id);
  546. }
  547. else {
  548. vCount[ofs]++;
  549. }
  550. }
  551. }
  552. for (j = 0; j < vCount.length; ++j) {
  553. if (vCount[j] === 1) {
  554. this.vertices[vId[j]].isBorder = true;
  555. }
  556. else {
  557. this.vertices[vId[j]].isBorder = false;
  558. }
  559. }
  560. }
  561. };
  562. QuadraticErrorSimplification.prototype.updateMesh = function (identifyBorders) {
  563. if (identifyBorders === void 0) { identifyBorders = false; }
  564. var i;
  565. if (!identifyBorders) {
  566. var newTrianglesVector = [];
  567. for (i = 0; i < this.triangles.length; ++i) {
  568. if (!this.triangles[i].deleted) {
  569. newTrianglesVector.push(this.triangles[i]);
  570. }
  571. }
  572. this.triangles = newTrianglesVector;
  573. }
  574. for (i = 0; i < this.vertices.length; ++i) {
  575. this.vertices[i].triangleCount = 0;
  576. this.vertices[i].triangleStart = 0;
  577. }
  578. var t;
  579. var j;
  580. var v;
  581. for (i = 0; i < this.triangles.length; ++i) {
  582. t = this.triangles[i];
  583. for (j = 0; j < 3; ++j) {
  584. v = t.vertices[j];
  585. v.triangleCount++;
  586. }
  587. }
  588. var tStart = 0;
  589. for (i = 0; i < this.vertices.length; ++i) {
  590. this.vertices[i].triangleStart = tStart;
  591. tStart += this.vertices[i].triangleCount;
  592. this.vertices[i].triangleCount = 0;
  593. }
  594. var newReferences = new Array(this.triangles.length * 3);
  595. for (i = 0; i < this.triangles.length; ++i) {
  596. t = this.triangles[i];
  597. for (j = 0; j < 3; ++j) {
  598. v = t.vertices[j];
  599. newReferences[v.triangleStart + v.triangleCount] = new Reference(j, i);
  600. v.triangleCount++;
  601. }
  602. }
  603. this.references = newReferences;
  604. if (identifyBorders) {
  605. this.identifyBorder();
  606. }
  607. };
  608. QuadraticErrorSimplification.prototype.vertexError = function (q, point) {
  609. var x = point.x;
  610. var y = point.y;
  611. var z = point.z;
  612. return q.data[0] * x * x + 2 * q.data[1] * x * y + 2 * q.data[2] * x * z + 2 * q.data[3] * x + q.data[4] * y * y
  613. + 2 * q.data[5] * y * z + 2 * q.data[6] * y + q.data[7] * z * z + 2 * q.data[8] * z + q.data[9];
  614. };
  615. QuadraticErrorSimplification.prototype.calculateError = function (vertex1, vertex2, pointResult, normalResult, uvResult, colorResult) {
  616. var q = vertex1.q.add(vertex2.q);
  617. var border = vertex1.isBorder && vertex2.isBorder;
  618. var error = 0;
  619. var qDet = q.det(0, 1, 2, 1, 4, 5, 2, 5, 7);
  620. if (qDet !== 0 && !border) {
  621. if (!pointResult) {
  622. pointResult = BABYLON.Vector3.Zero();
  623. }
  624. pointResult.x = -1 / qDet * (q.det(1, 2, 3, 4, 5, 6, 5, 7, 8));
  625. pointResult.y = 1 / qDet * (q.det(0, 2, 3, 1, 5, 6, 2, 7, 8));
  626. pointResult.z = -1 / qDet * (q.det(0, 1, 3, 1, 4, 6, 2, 5, 8));
  627. error = this.vertexError(q, pointResult);
  628. }
  629. else {
  630. var p3 = (vertex1.position.add(vertex2.position)).divide(new BABYLON.Vector3(2, 2, 2));
  631. //var norm3 = (vertex1.normal.add(vertex2.normal)).divide(new Vector3(2, 2, 2)).normalize();
  632. var error1 = this.vertexError(q, vertex1.position);
  633. var error2 = this.vertexError(q, vertex2.position);
  634. var error3 = this.vertexError(q, p3);
  635. error = Math.min(error1, error2, error3);
  636. if (error === error1) {
  637. if (pointResult) {
  638. pointResult.copyFrom(vertex1.position);
  639. }
  640. }
  641. else if (error === error2) {
  642. if (pointResult) {
  643. pointResult.copyFrom(vertex2.position);
  644. }
  645. }
  646. else {
  647. if (pointResult) {
  648. pointResult.copyFrom(p3);
  649. }
  650. }
  651. }
  652. return error;
  653. };
  654. return QuadraticErrorSimplification;
  655. }());
  656. BABYLON.QuadraticErrorSimplification = QuadraticErrorSimplification;
  657. })(BABYLON || (BABYLON = {}));
  658. //# sourceMappingURL=babylon.meshSimplification.js.map
  659. var BABYLON;
  660. (function (BABYLON) {
  661. var MeshLODLevel = /** @class */ (function () {
  662. function MeshLODLevel(distance, mesh) {
  663. this.distance = distance;
  664. this.mesh = mesh;
  665. }
  666. return MeshLODLevel;
  667. }());
  668. BABYLON.MeshLODLevel = MeshLODLevel;
  669. })(BABYLON || (BABYLON = {}));
  670. //# sourceMappingURL=babylon.meshLODLevel.js.map
  671. BABYLON.Effect.ShadersStore['defaultVertexShader'] = "#include<__decl__defaultVertex>\n\nattribute vec3 position;\n#ifdef NORMAL\nattribute vec3 normal;\n#endif\n#ifdef TANGENT\nattribute vec4 tangent;\n#endif\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#ifdef VERTEXCOLOR\nattribute vec4 color;\n#endif\n#include<helperFunctions>\n#include<bonesDeclaration>\n\n#include<instancesDeclaration>\n#ifdef MAINUV1\nvarying vec2 vMainUV1;\n#endif\n#ifdef MAINUV2\nvarying vec2 vMainUV2;\n#endif\n#if defined(DIFFUSE) && DIFFUSEDIRECTUV == 0\nvarying vec2 vDiffuseUV;\n#endif\n#if defined(AMBIENT) && AMBIENTDIRECTUV == 0\nvarying vec2 vAmbientUV;\n#endif\n#if defined(OPACITY) && OPACITYDIRECTUV == 0\nvarying vec2 vOpacityUV;\n#endif\n#if defined(EMISSIVE) && EMISSIVEDIRECTUV == 0\nvarying vec2 vEmissiveUV;\n#endif\n#if defined(LIGHTMAP) && LIGHTMAPDIRECTUV == 0\nvarying vec2 vLightmapUV;\n#endif\n#if defined(SPECULAR) && defined(SPECULARTERM) && SPECULARDIRECTUV == 0\nvarying vec2 vSpecularUV;\n#endif\n#if defined(BUMP) && BUMPDIRECTUV == 0\nvarying vec2 vBumpUV;\n#endif\n\nvarying vec3 vPositionW;\n#ifdef NORMAL\nvarying vec3 vNormalW;\n#endif\n#ifdef VERTEXCOLOR\nvarying vec4 vColor;\n#endif\n#include<bumpVertexDeclaration>\n#include<clipPlaneVertexDeclaration>\n#include<fogVertexDeclaration>\n#include<__decl__lightFragment>[0..maxSimultaneousLights]\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vec3 vPositionUVW;\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vec3 vDirectionW;\n#endif\n#include<logDepthDeclaration>\nvoid main(void) {\nvec3 positionUpdated=position;\n#ifdef NORMAL \nvec3 normalUpdated=normal;\n#endif\n#ifdef TANGENT\nvec4 tangentUpdated=tangent;\n#endif\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#ifdef REFLECTIONMAP_SKYBOX\nvPositionUVW=positionUpdated;\n#endif \n#include<instancesVertex>\n#include<bonesVertex>\ngl_Position=viewProjection*finalWorld*vec4(positionUpdated,1.0);\nvec4 worldPos=finalWorld*vec4(positionUpdated,1.0);\nvPositionW=vec3(worldPos);\n#ifdef NORMAL\nmat3 normalWorld=mat3(finalWorld);\n#ifdef NONUNIFORMSCALING\nnormalWorld=transposeMat3(inverseMat3(normalWorld));\n#endif\nvNormalW=normalize(normalWorld*normalUpdated);\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvDirectionW=normalize(vec3(finalWorld*vec4(positionUpdated,0.0)));\n#endif\n\n#ifndef UV1\nvec2 uv=vec2(0.,0.);\n#endif\n#ifndef UV2\nvec2 uv2=vec2(0.,0.);\n#endif\n#ifdef MAINUV1\nvMainUV1=uv;\n#endif\n#ifdef MAINUV2\nvMainUV2=uv2;\n#endif\n#if defined(DIFFUSE) && DIFFUSEDIRECTUV == 0\nif (vDiffuseInfos.x == 0.)\n{\nvDiffuseUV=vec2(diffuseMatrix*vec4(uv,1.0,0.0));\n}\nelse\n{\nvDiffuseUV=vec2(diffuseMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(AMBIENT) && AMBIENTDIRECTUV == 0\nif (vAmbientInfos.x == 0.)\n{\nvAmbientUV=vec2(ambientMatrix*vec4(uv,1.0,0.0));\n}\nelse\n{\nvAmbientUV=vec2(ambientMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(OPACITY) && OPACITYDIRECTUV == 0\nif (vOpacityInfos.x == 0.)\n{\nvOpacityUV=vec2(opacityMatrix*vec4(uv,1.0,0.0));\n}\nelse\n{\nvOpacityUV=vec2(opacityMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(EMISSIVE) && EMISSIVEDIRECTUV == 0\nif (vEmissiveInfos.x == 0.)\n{\nvEmissiveUV=vec2(emissiveMatrix*vec4(uv,1.0,0.0));\n}\nelse\n{\nvEmissiveUV=vec2(emissiveMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(LIGHTMAP) && LIGHTMAPDIRECTUV == 0\nif (vLightmapInfos.x == 0.)\n{\nvLightmapUV=vec2(lightmapMatrix*vec4(uv,1.0,0.0));\n}\nelse\n{\nvLightmapUV=vec2(lightmapMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(SPECULAR) && defined(SPECULARTERM) && SPECULARDIRECTUV == 0\nif (vSpecularInfos.x == 0.)\n{\nvSpecularUV=vec2(specularMatrix*vec4(uv,1.0,0.0));\n}\nelse\n{\nvSpecularUV=vec2(specularMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(BUMP) && BUMPDIRECTUV == 0\nif (vBumpInfos.x == 0.)\n{\nvBumpUV=vec2(bumpMatrix*vec4(uv,1.0,0.0));\n}\nelse\n{\nvBumpUV=vec2(bumpMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#include<bumpVertex>\n#include<clipPlaneVertex>\n#include<fogVertex>\n#include<shadowsVertex>[0..maxSimultaneousLights]\n#ifdef VERTEXCOLOR\n\nvColor=color;\n#endif\n#include<pointCloudVertex>\n#include<logDepthVertex>\n}";
  672. BABYLON.Effect.ShadersStore['defaultPixelShader'] = "#include<__decl__defaultFragment>\n#if defined(BUMP) || !defined(NORMAL)\n#extension GL_OES_standard_derivatives : enable\n#endif\n#ifdef LOGARITHMICDEPTH\n#extension GL_EXT_frag_depth : enable\n#endif\n\n#define RECIPROCAL_PI2 0.15915494\nuniform vec3 vEyePosition;\nuniform vec3 vAmbientColor;\n\nvarying vec3 vPositionW;\n#ifdef NORMAL\nvarying vec3 vNormalW;\n#endif\n#ifdef VERTEXCOLOR\nvarying vec4 vColor;\n#endif\n#ifdef MAINUV1\nvarying vec2 vMainUV1;\n#endif\n#ifdef MAINUV2\nvarying vec2 vMainUV2;\n#endif\n\n#include<helperFunctions>\n\n#include<__decl__lightFragment>[0..maxSimultaneousLights]\n#include<lightsFragmentFunctions>\n#include<shadowsFragmentFunctions>\n\n#ifdef DIFFUSE\n#if DIFFUSEDIRECTUV == 1\n#define vDiffuseUV vMainUV1\n#elif DIFFUSEDIRECTUV == 2\n#define vDiffuseUV vMainUV2\n#else\nvarying vec2 vDiffuseUV;\n#endif\nuniform sampler2D diffuseSampler;\n#endif\n#ifdef AMBIENT\n#if AMBIENTDIRECTUV == 1\n#define vAmbientUV vMainUV1\n#elif AMBIENTDIRECTUV == 2\n#define vAmbientUV vMainUV2\n#else\nvarying vec2 vAmbientUV;\n#endif\nuniform sampler2D ambientSampler;\n#endif\n#ifdef OPACITY \n#if OPACITYDIRECTUV == 1\n#define vOpacityUV vMainUV1\n#elif OPACITYDIRECTUV == 2\n#define vOpacityUV vMainUV2\n#else\nvarying vec2 vOpacityUV;\n#endif\nuniform sampler2D opacitySampler;\n#endif\n#ifdef EMISSIVE\n#if EMISSIVEDIRECTUV == 1\n#define vEmissiveUV vMainUV1\n#elif EMISSIVEDIRECTUV == 2\n#define vEmissiveUV vMainUV2\n#else\nvarying vec2 vEmissiveUV;\n#endif\nuniform sampler2D emissiveSampler;\n#endif\n#ifdef LIGHTMAP\n#if LIGHTMAPDIRECTUV == 1\n#define vLightmapUV vMainUV1\n#elif LIGHTMAPDIRECTUV == 2\n#define vLightmapUV vMainUV2\n#else\nvarying vec2 vLightmapUV;\n#endif\nuniform sampler2D lightmapSampler;\n#endif\n#ifdef REFRACTION\n#ifdef REFRACTIONMAP_3D\nuniform samplerCube refractionCubeSampler;\n#else\nuniform sampler2D refraction2DSampler;\n#endif\n#endif\n#if defined(SPECULAR) && defined(SPECULARTERM)\n#if SPECULARDIRECTUV == 1\n#define vSpecularUV vMainUV1\n#elif SPECULARDIRECTUV == 2\n#define vSpecularUV vMainUV2\n#else\nvarying vec2 vSpecularUV;\n#endif\nuniform sampler2D specularSampler;\n#endif\n\n#include<fresnelFunction>\n\n#ifdef REFLECTION\n#ifdef REFLECTIONMAP_3D\nuniform samplerCube reflectionCubeSampler;\n#else\nuniform sampler2D reflection2DSampler;\n#endif\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vec3 vPositionUVW;\n#else\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vec3 vDirectionW;\n#endif\n#endif\n#include<reflectionFunction>\n#endif\n#include<imageProcessingDeclaration>\n#include<imageProcessingFunctions>\n#include<bumpFragmentFunctions>\n#include<clipPlaneFragmentDeclaration>\n#include<logDepthDeclaration>\n#include<fogFragmentDeclaration>\nvoid main(void) {\n#include<clipPlaneFragment>\nvec3 viewDirectionW=normalize(vEyePosition-vPositionW);\n\nvec4 baseColor=vec4(1.,1.,1.,1.);\nvec3 diffuseColor=vDiffuseColor.rgb;\n\nfloat alpha=vDiffuseColor.a;\n\n#ifdef NORMAL\nvec3 normalW=normalize(vNormalW);\n#else\nvec3 normalW=normalize(-cross(dFdx(vPositionW),dFdy(vPositionW)));\n#endif\n#include<bumpFragment>\n#ifdef TWOSIDEDLIGHTING\nnormalW=gl_FrontFacing ? normalW : -normalW;\n#endif\n#ifdef DIFFUSE\nbaseColor=texture2D(diffuseSampler,vDiffuseUV+uvOffset);\n#ifdef ALPHATEST\nif (baseColor.a<0.4)\ndiscard;\n#endif\n#ifdef ALPHAFROMDIFFUSE\nalpha*=baseColor.a;\n#endif\nbaseColor.rgb*=vDiffuseInfos.y;\n#endif\n#include<depthPrePass>\n#ifdef VERTEXCOLOR\nbaseColor.rgb*=vColor.rgb;\n#endif\n\nvec3 baseAmbientColor=vec3(1.,1.,1.);\n#ifdef AMBIENT\nbaseAmbientColor=texture2D(ambientSampler,vAmbientUV+uvOffset).rgb*vAmbientInfos.y;\n#endif\n\n#ifdef SPECULARTERM\nfloat glossiness=vSpecularColor.a;\nvec3 specularColor=vSpecularColor.rgb;\n#ifdef SPECULAR\nvec4 specularMapColor=texture2D(specularSampler,vSpecularUV+uvOffset);\nspecularColor=specularMapColor.rgb;\n#ifdef GLOSSINESS\nglossiness=glossiness*specularMapColor.a;\n#endif\n#endif\n#else\nfloat glossiness=0.;\n#endif\n\nvec3 diffuseBase=vec3(0.,0.,0.);\nlightingInfo info;\n#ifdef SPECULARTERM\nvec3 specularBase=vec3(0.,0.,0.);\n#endif\nfloat shadow=1.;\n#ifdef LIGHTMAP\nvec3 lightmapColor=texture2D(lightmapSampler,vLightmapUV+uvOffset).rgb*vLightmapInfos.y;\n#endif\n#include<lightFragment>[0..maxSimultaneousLights]\n\nvec3 refractionColor=vec3(0.,0.,0.);\n#ifdef REFRACTION\nvec3 refractionVector=normalize(refract(-viewDirectionW,normalW,vRefractionInfos.y));\n#ifdef REFRACTIONMAP_3D\nrefractionVector.y=refractionVector.y*vRefractionInfos.w;\nif (dot(refractionVector,viewDirectionW)<1.0)\n{\nrefractionColor=textureCube(refractionCubeSampler,refractionVector).rgb*vRefractionInfos.x;\n}\n#else\nvec3 vRefractionUVW=vec3(refractionMatrix*(view*vec4(vPositionW+refractionVector*vRefractionInfos.z,1.0)));\nvec2 refractionCoords=vRefractionUVW.xy/vRefractionUVW.z;\nrefractionCoords.y=1.0-refractionCoords.y;\nrefractionColor=texture2D(refraction2DSampler,refractionCoords).rgb*vRefractionInfos.x;\n#endif\n#endif\n\nvec3 reflectionColor=vec3(0.,0.,0.);\n#ifdef REFLECTION\nvec3 vReflectionUVW=computeReflectionCoords(vec4(vPositionW,1.0),normalW);\n#ifdef REFLECTIONMAP_3D\n#ifdef ROUGHNESS\nfloat bias=vReflectionInfos.y;\n#ifdef SPECULARTERM\n#ifdef SPECULAR\n#ifdef GLOSSINESS\nbias*=(1.0-specularMapColor.a);\n#endif\n#endif\n#endif\nreflectionColor=textureCube(reflectionCubeSampler,vReflectionUVW,bias).rgb*vReflectionInfos.x;\n#else\nreflectionColor=textureCube(reflectionCubeSampler,vReflectionUVW).rgb*vReflectionInfos.x;\n#endif\n#else\nvec2 coords=vReflectionUVW.xy;\n#ifdef REFLECTIONMAP_PROJECTION\ncoords/=vReflectionUVW.z;\n#endif\ncoords.y=1.0-coords.y;\nreflectionColor=texture2D(reflection2DSampler,coords).rgb*vReflectionInfos.x;\n#endif\n#ifdef REFLECTIONFRESNEL\nfloat reflectionFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,reflectionRightColor.a,reflectionLeftColor.a);\n#ifdef REFLECTIONFRESNELFROMSPECULAR\n#ifdef SPECULARTERM\nreflectionColor*=specularColor.rgb*(1.0-reflectionFresnelTerm)+reflectionFresnelTerm*reflectionRightColor.rgb;\n#else\nreflectionColor*=reflectionLeftColor.rgb*(1.0-reflectionFresnelTerm)+reflectionFresnelTerm*reflectionRightColor.rgb;\n#endif\n#else\nreflectionColor*=reflectionLeftColor.rgb*(1.0-reflectionFresnelTerm)+reflectionFresnelTerm*reflectionRightColor.rgb;\n#endif\n#endif\n#endif\n#ifdef REFRACTIONFRESNEL\nfloat refractionFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,refractionRightColor.a,refractionLeftColor.a);\nrefractionColor*=refractionLeftColor.rgb*(1.0-refractionFresnelTerm)+refractionFresnelTerm*refractionRightColor.rgb;\n#endif\n#ifdef OPACITY\nvec4 opacityMap=texture2D(opacitySampler,vOpacityUV+uvOffset);\n#ifdef OPACITYRGB\nopacityMap.rgb=opacityMap.rgb*vec3(0.3,0.59,0.11);\nalpha*=(opacityMap.x+opacityMap.y+opacityMap.z)* vOpacityInfos.y;\n#else\nalpha*=opacityMap.a*vOpacityInfos.y;\n#endif\n#endif\n#ifdef VERTEXALPHA\nalpha*=vColor.a;\n#endif\n#ifdef OPACITYFRESNEL\nfloat opacityFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,opacityParts.z,opacityParts.w);\nalpha+=opacityParts.x*(1.0-opacityFresnelTerm)+opacityFresnelTerm*opacityParts.y;\n#endif\n\nvec3 emissiveColor=vEmissiveColor;\n#ifdef EMISSIVE\nemissiveColor+=texture2D(emissiveSampler,vEmissiveUV+uvOffset).rgb*vEmissiveInfos.y;\n#endif\n#ifdef EMISSIVEFRESNEL\nfloat emissiveFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,emissiveRightColor.a,emissiveLeftColor.a);\nemissiveColor*=emissiveLeftColor.rgb*(1.0-emissiveFresnelTerm)+emissiveFresnelTerm*emissiveRightColor.rgb;\n#endif\n\n#ifdef DIFFUSEFRESNEL\nfloat diffuseFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,diffuseRightColor.a,diffuseLeftColor.a);\ndiffuseBase*=diffuseLeftColor.rgb*(1.0-diffuseFresnelTerm)+diffuseFresnelTerm*diffuseRightColor.rgb;\n#endif\n\n#ifdef EMISSIVEASILLUMINATION\nvec3 finalDiffuse=clamp(diffuseBase*diffuseColor+vAmbientColor,0.0,1.0)*baseColor.rgb;\n#else\n#ifdef LINKEMISSIVEWITHDIFFUSE\nvec3 finalDiffuse=clamp((diffuseBase+emissiveColor)*diffuseColor+vAmbientColor,0.0,1.0)*baseColor.rgb;\n#else\nvec3 finalDiffuse=clamp(diffuseBase*diffuseColor+emissiveColor+vAmbientColor,0.0,1.0)*baseColor.rgb;\n#endif\n#endif\n#ifdef SPECULARTERM\nvec3 finalSpecular=specularBase*specularColor;\n#ifdef SPECULAROVERALPHA\nalpha=clamp(alpha+dot(finalSpecular,vec3(0.3,0.59,0.11)),0.,1.);\n#endif\n#else\nvec3 finalSpecular=vec3(0.0);\n#endif\n#ifdef REFLECTIONOVERALPHA\nalpha=clamp(alpha+dot(reflectionColor,vec3(0.3,0.59,0.11)),0.,1.);\n#endif\n\n#ifdef EMISSIVEASILLUMINATION\nvec4 color=vec4(clamp(finalDiffuse*baseAmbientColor+finalSpecular+reflectionColor+emissiveColor+refractionColor,0.0,1.0),alpha);\n#else\nvec4 color=vec4(finalDiffuse*baseAmbientColor+finalSpecular+reflectionColor+refractionColor,alpha);\n#endif\n\n#ifdef LIGHTMAP\n#ifndef LIGHTMAPEXCLUDED\n#ifdef USELIGHTMAPASSHADOWMAP\ncolor.rgb*=lightmapColor;\n#else\ncolor.rgb+=lightmapColor;\n#endif\n#endif\n#endif\n#include<logDepthFragment>\n#include<fogFragment>\n\n\n#ifdef IMAGEPROCESSINGPOSTPROCESS\ncolor.rgb=toLinearSpace(color.rgb);\n#else\n#ifdef IMAGEPROCESSING\ncolor.rgb=toLinearSpace(color.rgb);\ncolor=applyImageProcessing(color);\n#endif\n#endif\n#ifdef PREMULTIPLYALPHA\n\ncolor.rgb*=color.a;\n#endif\ngl_FragColor=color;\n}";
  673. var BABYLON;
  674. (function (BABYLON) {
  675. // Standard optimizations
  676. var SceneOptimization = /** @class */ (function () {
  677. function SceneOptimization(priority) {
  678. if (priority === void 0) { priority = 0; }
  679. this.priority = priority;
  680. this.apply = function (scene) {
  681. return true; // Return true if everything that can be done was applied
  682. };
  683. }
  684. return SceneOptimization;
  685. }());
  686. BABYLON.SceneOptimization = SceneOptimization;
  687. var TextureOptimization = /** @class */ (function (_super) {
  688. __extends(TextureOptimization, _super);
  689. function TextureOptimization(priority, maximumSize) {
  690. if (priority === void 0) { priority = 0; }
  691. if (maximumSize === void 0) { maximumSize = 1024; }
  692. var _this = _super.call(this, priority) || this;
  693. _this.priority = priority;
  694. _this.maximumSize = maximumSize;
  695. _this.apply = function (scene) {
  696. var allDone = true;
  697. for (var index = 0; index < scene.textures.length; index++) {
  698. var texture = scene.textures[index];
  699. if (!texture.canRescale || texture.getContext) {
  700. continue;
  701. }
  702. var currentSize = texture.getSize();
  703. var maxDimension = Math.max(currentSize.width, currentSize.height);
  704. if (maxDimension > _this.maximumSize) {
  705. texture.scale(0.5);
  706. allDone = false;
  707. }
  708. }
  709. return allDone;
  710. };
  711. return _this;
  712. }
  713. return TextureOptimization;
  714. }(SceneOptimization));
  715. BABYLON.TextureOptimization = TextureOptimization;
  716. var HardwareScalingOptimization = /** @class */ (function (_super) {
  717. __extends(HardwareScalingOptimization, _super);
  718. function HardwareScalingOptimization(priority, maximumScale) {
  719. if (priority === void 0) { priority = 0; }
  720. if (maximumScale === void 0) { maximumScale = 2; }
  721. var _this = _super.call(this, priority) || this;
  722. _this.priority = priority;
  723. _this.maximumScale = maximumScale;
  724. _this._currentScale = 1;
  725. _this.apply = function (scene) {
  726. _this._currentScale++;
  727. scene.getEngine().setHardwareScalingLevel(_this._currentScale);
  728. return _this._currentScale >= _this.maximumScale;
  729. };
  730. return _this;
  731. }
  732. return HardwareScalingOptimization;
  733. }(SceneOptimization));
  734. BABYLON.HardwareScalingOptimization = HardwareScalingOptimization;
  735. var ShadowsOptimization = /** @class */ (function (_super) {
  736. __extends(ShadowsOptimization, _super);
  737. function ShadowsOptimization() {
  738. var _this = _super !== null && _super.apply(this, arguments) || this;
  739. _this.apply = function (scene) {
  740. scene.shadowsEnabled = false;
  741. return true;
  742. };
  743. return _this;
  744. }
  745. return ShadowsOptimization;
  746. }(SceneOptimization));
  747. BABYLON.ShadowsOptimization = ShadowsOptimization;
  748. var PostProcessesOptimization = /** @class */ (function (_super) {
  749. __extends(PostProcessesOptimization, _super);
  750. function PostProcessesOptimization() {
  751. var _this = _super !== null && _super.apply(this, arguments) || this;
  752. _this.apply = function (scene) {
  753. scene.postProcessesEnabled = false;
  754. return true;
  755. };
  756. return _this;
  757. }
  758. return PostProcessesOptimization;
  759. }(SceneOptimization));
  760. BABYLON.PostProcessesOptimization = PostProcessesOptimization;
  761. var LensFlaresOptimization = /** @class */ (function (_super) {
  762. __extends(LensFlaresOptimization, _super);
  763. function LensFlaresOptimization() {
  764. var _this = _super !== null && _super.apply(this, arguments) || this;
  765. _this.apply = function (scene) {
  766. scene.lensFlaresEnabled = false;
  767. return true;
  768. };
  769. return _this;
  770. }
  771. return LensFlaresOptimization;
  772. }(SceneOptimization));
  773. BABYLON.LensFlaresOptimization = LensFlaresOptimization;
  774. var ParticlesOptimization = /** @class */ (function (_super) {
  775. __extends(ParticlesOptimization, _super);
  776. function ParticlesOptimization() {
  777. var _this = _super !== null && _super.apply(this, arguments) || this;
  778. _this.apply = function (scene) {
  779. scene.particlesEnabled = false;
  780. return true;
  781. };
  782. return _this;
  783. }
  784. return ParticlesOptimization;
  785. }(SceneOptimization));
  786. BABYLON.ParticlesOptimization = ParticlesOptimization;
  787. var RenderTargetsOptimization = /** @class */ (function (_super) {
  788. __extends(RenderTargetsOptimization, _super);
  789. function RenderTargetsOptimization() {
  790. var _this = _super !== null && _super.apply(this, arguments) || this;
  791. _this.apply = function (scene) {
  792. scene.renderTargetsEnabled = false;
  793. return true;
  794. };
  795. return _this;
  796. }
  797. return RenderTargetsOptimization;
  798. }(SceneOptimization));
  799. BABYLON.RenderTargetsOptimization = RenderTargetsOptimization;
  800. var MergeMeshesOptimization = /** @class */ (function (_super) {
  801. __extends(MergeMeshesOptimization, _super);
  802. function MergeMeshesOptimization() {
  803. var _this = _super !== null && _super.apply(this, arguments) || this;
  804. _this._canBeMerged = function (abstractMesh) {
  805. if (!(abstractMesh instanceof BABYLON.Mesh)) {
  806. return false;
  807. }
  808. var mesh = abstractMesh;
  809. if (!mesh.isVisible || !mesh.isEnabled()) {
  810. return false;
  811. }
  812. if (mesh.instances.length > 0) {
  813. return false;
  814. }
  815. if (mesh.skeleton || mesh.hasLODLevels) {
  816. return false;
  817. }
  818. if (mesh.parent) {
  819. return false;
  820. }
  821. return true;
  822. };
  823. _this.apply = function (scene, updateSelectionTree) {
  824. var globalPool = scene.meshes.slice(0);
  825. var globalLength = globalPool.length;
  826. for (var index = 0; index < globalLength; index++) {
  827. var currentPool = new Array();
  828. var current = globalPool[index];
  829. // Checks
  830. if (!_this._canBeMerged(current)) {
  831. continue;
  832. }
  833. currentPool.push(current);
  834. // Find compatible meshes
  835. for (var subIndex = index + 1; subIndex < globalLength; subIndex++) {
  836. var otherMesh = globalPool[subIndex];
  837. if (!_this._canBeMerged(otherMesh)) {
  838. continue;
  839. }
  840. if (otherMesh.material !== current.material) {
  841. continue;
  842. }
  843. if (otherMesh.checkCollisions !== current.checkCollisions) {
  844. continue;
  845. }
  846. currentPool.push(otherMesh);
  847. globalLength--;
  848. globalPool.splice(subIndex, 1);
  849. subIndex--;
  850. }
  851. if (currentPool.length < 2) {
  852. continue;
  853. }
  854. // Merge meshes
  855. BABYLON.Mesh.MergeMeshes(currentPool);
  856. }
  857. if (updateSelectionTree != undefined) {
  858. if (updateSelectionTree) {
  859. scene.createOrUpdateSelectionOctree();
  860. }
  861. }
  862. else if (MergeMeshesOptimization.UpdateSelectionTree) {
  863. scene.createOrUpdateSelectionOctree();
  864. }
  865. return true;
  866. };
  867. return _this;
  868. }
  869. Object.defineProperty(MergeMeshesOptimization, "UpdateSelectionTree", {
  870. get: function () {
  871. return MergeMeshesOptimization._UpdateSelectionTree;
  872. },
  873. set: function (value) {
  874. MergeMeshesOptimization._UpdateSelectionTree = value;
  875. },
  876. enumerable: true,
  877. configurable: true
  878. });
  879. MergeMeshesOptimization._UpdateSelectionTree = false;
  880. return MergeMeshesOptimization;
  881. }(SceneOptimization));
  882. BABYLON.MergeMeshesOptimization = MergeMeshesOptimization;
  883. // Options
  884. var SceneOptimizerOptions = /** @class */ (function () {
  885. function SceneOptimizerOptions(targetFrameRate, trackerDuration) {
  886. if (targetFrameRate === void 0) { targetFrameRate = 60; }
  887. if (trackerDuration === void 0) { trackerDuration = 2000; }
  888. this.targetFrameRate = targetFrameRate;
  889. this.trackerDuration = trackerDuration;
  890. this.optimizations = new Array();
  891. }
  892. SceneOptimizerOptions.LowDegradationAllowed = function (targetFrameRate) {
  893. var result = new SceneOptimizerOptions(targetFrameRate);
  894. var priority = 0;
  895. result.optimizations.push(new MergeMeshesOptimization(priority));
  896. result.optimizations.push(new ShadowsOptimization(priority));
  897. result.optimizations.push(new LensFlaresOptimization(priority));
  898. // Next priority
  899. priority++;
  900. result.optimizations.push(new PostProcessesOptimization(priority));
  901. result.optimizations.push(new ParticlesOptimization(priority));
  902. // Next priority
  903. priority++;
  904. result.optimizations.push(new TextureOptimization(priority, 1024));
  905. return result;
  906. };
  907. SceneOptimizerOptions.ModerateDegradationAllowed = function (targetFrameRate) {
  908. var result = new SceneOptimizerOptions(targetFrameRate);
  909. var priority = 0;
  910. result.optimizations.push(new MergeMeshesOptimization(priority));
  911. result.optimizations.push(new ShadowsOptimization(priority));
  912. result.optimizations.push(new LensFlaresOptimization(priority));
  913. // Next priority
  914. priority++;
  915. result.optimizations.push(new PostProcessesOptimization(priority));
  916. result.optimizations.push(new ParticlesOptimization(priority));
  917. // Next priority
  918. priority++;
  919. result.optimizations.push(new TextureOptimization(priority, 512));
  920. // Next priority
  921. priority++;
  922. result.optimizations.push(new RenderTargetsOptimization(priority));
  923. // Next priority
  924. priority++;
  925. result.optimizations.push(new HardwareScalingOptimization(priority, 2));
  926. return result;
  927. };
  928. SceneOptimizerOptions.HighDegradationAllowed = function (targetFrameRate) {
  929. var result = new SceneOptimizerOptions(targetFrameRate);
  930. var priority = 0;
  931. result.optimizations.push(new MergeMeshesOptimization(priority));
  932. result.optimizations.push(new ShadowsOptimization(priority));
  933. result.optimizations.push(new LensFlaresOptimization(priority));
  934. // Next priority
  935. priority++;
  936. result.optimizations.push(new PostProcessesOptimization(priority));
  937. result.optimizations.push(new ParticlesOptimization(priority));
  938. // Next priority
  939. priority++;
  940. result.optimizations.push(new TextureOptimization(priority, 256));
  941. // Next priority
  942. priority++;
  943. result.optimizations.push(new RenderTargetsOptimization(priority));
  944. // Next priority
  945. priority++;
  946. result.optimizations.push(new HardwareScalingOptimization(priority, 4));
  947. return result;
  948. };
  949. return SceneOptimizerOptions;
  950. }());
  951. BABYLON.SceneOptimizerOptions = SceneOptimizerOptions;
  952. // Scene optimizer tool
  953. var SceneOptimizer = /** @class */ (function () {
  954. function SceneOptimizer() {
  955. }
  956. SceneOptimizer._CheckCurrentState = function (scene, options, currentPriorityLevel, onSuccess, onFailure) {
  957. // TODO: add an epsilon
  958. if (scene.getEngine().getFps() >= options.targetFrameRate) {
  959. if (onSuccess) {
  960. onSuccess();
  961. }
  962. return;
  963. }
  964. // Apply current level of optimizations
  965. var allDone = true;
  966. var noOptimizationApplied = true;
  967. for (var index = 0; index < options.optimizations.length; index++) {
  968. var optimization = options.optimizations[index];
  969. if (optimization.priority === currentPriorityLevel) {
  970. noOptimizationApplied = false;
  971. allDone = allDone && optimization.apply(scene);
  972. }
  973. }
  974. // If no optimization was applied, this is a failure :(
  975. if (noOptimizationApplied) {
  976. if (onFailure) {
  977. onFailure();
  978. }
  979. return;
  980. }
  981. // If all optimizations were done, move to next level
  982. if (allDone) {
  983. currentPriorityLevel++;
  984. }
  985. // Let's the system running for a specific amount of time before checking FPS
  986. scene.executeWhenReady(function () {
  987. setTimeout(function () {
  988. SceneOptimizer._CheckCurrentState(scene, options, currentPriorityLevel, onSuccess, onFailure);
  989. }, options.trackerDuration);
  990. });
  991. };
  992. SceneOptimizer.OptimizeAsync = function (scene, options, onSuccess, onFailure) {
  993. if (!options) {
  994. options = SceneOptimizerOptions.ModerateDegradationAllowed();
  995. }
  996. // Let's the system running for a specific amount of time before checking FPS
  997. scene.executeWhenReady(function () {
  998. setTimeout(function () {
  999. SceneOptimizer._CheckCurrentState(scene, options, 0, onSuccess, onFailure);
  1000. }, options.trackerDuration);
  1001. });
  1002. };
  1003. return SceneOptimizer;
  1004. }());
  1005. BABYLON.SceneOptimizer = SceneOptimizer;
  1006. })(BABYLON || (BABYLON = {}));
  1007. //# sourceMappingURL=babylon.sceneOptimizer.js.map
  1008. BABYLON.Effect.IncludesShadersStore['depthPrePass'] = "#ifdef DEPTHPREPASS\ngl_FragColor=vec4(0.,0.,0.,1.0);\nreturn;\n#endif";
  1009. BABYLON.Effect.IncludesShadersStore['bonesDeclaration'] = "#if NUM_BONE_INFLUENCERS>0\nuniform mat4 mBones[BonesPerMesh];\nattribute vec4 matricesIndices;\nattribute vec4 matricesWeights;\n#if NUM_BONE_INFLUENCERS>4\nattribute vec4 matricesIndicesExtra;\nattribute vec4 matricesWeightsExtra;\n#endif\n#endif";
  1010. BABYLON.Effect.IncludesShadersStore['instancesDeclaration'] = "#ifdef INSTANCES\nattribute vec4 world0;\nattribute vec4 world1;\nattribute vec4 world2;\nattribute vec4 world3;\n#else\nuniform mat4 world;\n#endif";
  1011. BABYLON.Effect.IncludesShadersStore['pointCloudVertexDeclaration'] = "#ifdef POINTSIZE\nuniform float pointSize;\n#endif";
  1012. BABYLON.Effect.IncludesShadersStore['bumpVertexDeclaration'] = "#if defined(BUMP) || defined(PARALLAX)\n#if defined(TANGENT) && defined(NORMAL) \nvarying mat3 vTBN;\n#endif\n#endif\n";
  1013. BABYLON.Effect.IncludesShadersStore['clipPlaneVertexDeclaration'] = "#ifdef CLIPPLANE\nuniform vec4 vClipPlane;\nvarying float fClipDistance;\n#endif";
  1014. BABYLON.Effect.IncludesShadersStore['fogVertexDeclaration'] = "#ifdef FOG\nvarying vec3 vFogDistance;\n#endif";
  1015. BABYLON.Effect.IncludesShadersStore['morphTargetsVertexGlobalDeclaration'] = "#ifdef MORPHTARGETS\nuniform float morphTargetInfluences[NUM_MORPH_INFLUENCERS];\n#endif";
  1016. BABYLON.Effect.IncludesShadersStore['morphTargetsVertexDeclaration'] = "#ifdef MORPHTARGETS\nattribute vec3 position{X};\n#ifdef MORPHTARGETS_NORMAL\nattribute vec3 normal{X};\n#endif\n#ifdef MORPHTARGETS_TANGENT\nattribute vec3 tangent{X};\n#endif\n#endif";
  1017. BABYLON.Effect.IncludesShadersStore['logDepthDeclaration'] = "#ifdef LOGARITHMICDEPTH\nuniform float logarithmicDepthConstant;\nvarying float vFragmentDepth;\n#endif";
  1018. BABYLON.Effect.IncludesShadersStore['morphTargetsVertex'] = "#ifdef MORPHTARGETS\npositionUpdated+=(position{X}-position)*morphTargetInfluences[{X}];\n#ifdef MORPHTARGETS_NORMAL\nnormalUpdated+=(normal{X}-normal)*morphTargetInfluences[{X}];\n#endif\n#ifdef MORPHTARGETS_TANGENT\ntangentUpdated.xyz+=(tangent{X}-tangent.xyz)*morphTargetInfluences[{X}];\n#endif\n#endif";
  1019. BABYLON.Effect.IncludesShadersStore['instancesVertex'] = "#ifdef INSTANCES\nmat4 finalWorld=mat4(world0,world1,world2,world3);\n#else\nmat4 finalWorld=world;\n#endif";
  1020. BABYLON.Effect.IncludesShadersStore['bonesVertex'] = "#if NUM_BONE_INFLUENCERS>0\nmat4 influence;\ninfluence=mBones[int(matricesIndices[0])]*matricesWeights[0];\n#if NUM_BONE_INFLUENCERS>1\ninfluence+=mBones[int(matricesIndices[1])]*matricesWeights[1];\n#endif \n#if NUM_BONE_INFLUENCERS>2\ninfluence+=mBones[int(matricesIndices[2])]*matricesWeights[2];\n#endif \n#if NUM_BONE_INFLUENCERS>3\ninfluence+=mBones[int(matricesIndices[3])]*matricesWeights[3];\n#endif \n#if NUM_BONE_INFLUENCERS>4\ninfluence+=mBones[int(matricesIndicesExtra[0])]*matricesWeightsExtra[0];\n#endif \n#if NUM_BONE_INFLUENCERS>5\ninfluence+=mBones[int(matricesIndicesExtra[1])]*matricesWeightsExtra[1];\n#endif \n#if NUM_BONE_INFLUENCERS>6\ninfluence+=mBones[int(matricesIndicesExtra[2])]*matricesWeightsExtra[2];\n#endif \n#if NUM_BONE_INFLUENCERS>7\ninfluence+=mBones[int(matricesIndicesExtra[3])]*matricesWeightsExtra[3];\n#endif \nfinalWorld=finalWorld*influence;\n#endif";
  1021. BABYLON.Effect.IncludesShadersStore['bumpVertex'] = "#if defined(BUMP) || defined(PARALLAX)\n#if defined(TANGENT) && defined(NORMAL)\nvec3 tbnNormal=normalize(normalUpdated);\nvec3 tbnTangent=normalize(tangentUpdated.xyz);\nvec3 tbnBitangent=cross(tbnNormal,tbnTangent)*tangentUpdated.w;\nvTBN=mat3(finalWorld)*mat3(tbnTangent,tbnBitangent,tbnNormal);\n#endif\n#endif";
  1022. BABYLON.Effect.IncludesShadersStore['clipPlaneVertex'] = "#ifdef CLIPPLANE\nfClipDistance=dot(worldPos,vClipPlane);\n#endif";
  1023. BABYLON.Effect.IncludesShadersStore['fogVertex'] = "#ifdef FOG\nvFogDistance=(view*worldPos).xyz;\n#endif";
  1024. BABYLON.Effect.IncludesShadersStore['shadowsVertex'] = "#ifdef SHADOWS\n#if defined(SHADOW{X}) && !defined(SHADOWCUBE{X})\nvPositionFromLight{X}=lightMatrix{X}*worldPos;\nvDepthMetric{X}=((vPositionFromLight{X}.z+light{X}.depthValues.x)/(light{X}.depthValues.y));\n#endif\n#endif";
  1025. BABYLON.Effect.IncludesShadersStore['pointCloudVertex'] = "#ifdef POINTSIZE\ngl_PointSize=pointSize;\n#endif";
  1026. BABYLON.Effect.IncludesShadersStore['logDepthVertex'] = "#ifdef LOGARITHMICDEPTH\nvFragmentDepth=1.0+gl_Position.w;\ngl_Position.z=log2(max(0.000001,vFragmentDepth))*logarithmicDepthConstant;\n#endif";
  1027. BABYLON.Effect.IncludesShadersStore['helperFunctions'] = "const float PI=3.1415926535897932384626433832795;\nconst float LinearEncodePowerApprox=2.2;\nconst float GammaEncodePowerApprox=1.0/LinearEncodePowerApprox;\nconst vec3 LuminanceEncodeApprox=vec3(0.2126,0.7152,0.0722);\nmat3 transposeMat3(mat3 inMatrix) {\nvec3 i0=inMatrix[0];\nvec3 i1=inMatrix[1];\nvec3 i2=inMatrix[2];\nmat3 outMatrix=mat3(\nvec3(i0.x,i1.x,i2.x),\nvec3(i0.y,i1.y,i2.y),\nvec3(i0.z,i1.z,i2.z)\n);\nreturn outMatrix;\n}\n\nmat3 inverseMat3(mat3 inMatrix) {\nfloat a00=inMatrix[0][0],a01=inMatrix[0][1],a02=inMatrix[0][2];\nfloat a10=inMatrix[1][0],a11=inMatrix[1][1],a12=inMatrix[1][2];\nfloat a20=inMatrix[2][0],a21=inMatrix[2][1],a22=inMatrix[2][2];\nfloat b01=a22*a11-a12*a21;\nfloat b11=-a22*a10+a12*a20;\nfloat b21=a21*a10-a11*a20;\nfloat det=a00*b01+a01*b11+a02*b21;\nreturn mat3(b01,(-a22*a01+a02*a21),(a12*a01-a02*a11),\nb11,(a22*a00-a02*a20),(-a12*a00+a02*a10),\nb21,(-a21*a00+a01*a20),(a11*a00-a01*a10))/det;\n}\nfloat computeFallOff(float value,vec2 clipSpace,float frustumEdgeFalloff)\n{\nfloat mask=smoothstep(1.0-frustumEdgeFalloff,1.0,clamp(dot(clipSpace,clipSpace),0.,1.));\nreturn mix(value,1.0,mask);\n}\nvec3 applyEaseInOut(vec3 x){\nreturn x*x*(3.0-2.0*x);\n}\nvec3 toLinearSpace(vec3 color)\n{\nreturn pow(color,vec3(LinearEncodePowerApprox));\n}\nvec3 toGammaSpace(vec3 color)\n{\nreturn pow(color,vec3(GammaEncodePowerApprox));\n}\nfloat square(float value)\n{\nreturn value*value;\n}\nfloat getLuminance(vec3 color)\n{\nreturn clamp(dot(color,LuminanceEncodeApprox),0.,1.);\n}\n\nfloat getRand(vec2 seed) {\nreturn fract(sin(dot(seed.xy ,vec2(12.9898,78.233)))*43758.5453);\n}\nvec3 dither(vec2 seed,vec3 color) {\nfloat rand=getRand(seed);\ncolor+=mix(-0.5/255.0,0.5/255.0,rand);\ncolor=max(color,0.0);\nreturn color;\n}";
  1028. BABYLON.Effect.IncludesShadersStore['lightFragmentDeclaration'] = "#ifdef LIGHT{X}\nuniform vec4 vLightData{X};\nuniform vec4 vLightDiffuse{X};\n#ifdef SPECULARTERM\nuniform vec3 vLightSpecular{X};\n#else\nvec3 vLightSpecular{X}=vec3(0.);\n#endif\n#ifdef SHADOW{X}\n#if defined(SHADOWCUBE{X})\nuniform samplerCube shadowSampler{X};\n#else\nvarying vec4 vPositionFromLight{X};\nvarying float vDepthMetric{X};\nuniform sampler2D shadowSampler{X};\nuniform mat4 lightMatrix{X};\n#endif\nuniform vec4 shadowsInfo{X};\nuniform vec2 depthValues{X};\n#endif\n#ifdef SPOTLIGHT{X}\nuniform vec4 vLightDirection{X};\n#endif\n#ifdef HEMILIGHT{X}\nuniform vec3 vLightGround{X};\n#endif\n#endif";
  1029. BABYLON.Effect.IncludesShadersStore['lightsFragmentFunctions'] = "\nstruct lightingInfo\n{\nvec3 diffuse;\n#ifdef SPECULARTERM\nvec3 specular;\n#endif\n#ifdef NDOTL\nfloat ndl;\n#endif\n};\nlightingInfo computeLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec3 diffuseColor,vec3 specularColor,float range,float glossiness) {\nlightingInfo result;\nvec3 lightVectorW;\nfloat attenuation=1.0;\nif (lightData.w == 0.)\n{\nvec3 direction=lightData.xyz-vPositionW;\nattenuation=max(0.,1.0-length(direction)/range);\nlightVectorW=normalize(direction);\n}\nelse\n{\nlightVectorW=normalize(-lightData.xyz);\n}\n\nfloat ndl=max(0.,dot(vNormal,lightVectorW));\n#ifdef NDOTL\nresult.ndl=ndl;\n#endif\nresult.diffuse=ndl*diffuseColor*attenuation;\n#ifdef SPECULARTERM\n\nvec3 angleW=normalize(viewDirectionW+lightVectorW);\nfloat specComp=max(0.,dot(vNormal,angleW));\nspecComp=pow(specComp,max(1.,glossiness));\nresult.specular=specComp*specularColor*attenuation;\n#endif\nreturn result;\n}\nlightingInfo computeSpotLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec4 lightDirection,vec3 diffuseColor,vec3 specularColor,float range,float glossiness) {\nlightingInfo result;\nvec3 direction=lightData.xyz-vPositionW;\nvec3 lightVectorW=normalize(direction);\nfloat attenuation=max(0.,1.0-length(direction)/range);\n\nfloat cosAngle=max(0.,dot(lightDirection.xyz,-lightVectorW));\nif (cosAngle>=lightDirection.w)\n{\ncosAngle=max(0.,pow(cosAngle,lightData.w));\nattenuation*=cosAngle;\n\nfloat ndl=max(0.,dot(vNormal,lightVectorW));\n#ifdef NDOTL\nresult.ndl=ndl;\n#endif\nresult.diffuse=ndl*diffuseColor*attenuation;\n#ifdef SPECULARTERM\n\nvec3 angleW=normalize(viewDirectionW+lightVectorW);\nfloat specComp=max(0.,dot(vNormal,angleW));\nspecComp=pow(specComp,max(1.,glossiness));\nresult.specular=specComp*specularColor*attenuation;\n#endif\nreturn result;\n}\nresult.diffuse=vec3(0.);\n#ifdef SPECULARTERM\nresult.specular=vec3(0.);\n#endif\n#ifdef NDOTL\nresult.ndl=0.;\n#endif\nreturn result;\n}\nlightingInfo computeHemisphericLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec3 diffuseColor,vec3 specularColor,vec3 groundColor,float glossiness) {\nlightingInfo result;\n\nfloat ndl=dot(vNormal,lightData.xyz)*0.5+0.5;\n#ifdef NDOTL\nresult.ndl=ndl;\n#endif\nresult.diffuse=mix(groundColor,diffuseColor,ndl);\n#ifdef SPECULARTERM\n\nvec3 angleW=normalize(viewDirectionW+lightData.xyz);\nfloat specComp=max(0.,dot(vNormal,angleW));\nspecComp=pow(specComp,max(1.,glossiness));\nresult.specular=specComp*specularColor;\n#endif\nreturn result;\n}\n";
  1030. BABYLON.Effect.IncludesShadersStore['lightUboDeclaration'] = "#ifdef LIGHT{X}\nuniform Light{X}\n{\nvec4 vLightData;\nvec4 vLightDiffuse;\nvec3 vLightSpecular;\n#ifdef SPOTLIGHT{X}\nvec4 vLightDirection;\n#endif\n#ifdef HEMILIGHT{X}\nvec3 vLightGround;\n#endif\nvec4 shadowsInfo;\nvec2 depthValues;\n} light{X};\n#ifdef SHADOW{X}\n#if defined(SHADOWCUBE{X})\nuniform samplerCube shadowSampler{X};\n#else\nvarying vec4 vPositionFromLight{X};\nvarying float vDepthMetric{X};\nuniform sampler2D shadowSampler{X};\nuniform mat4 lightMatrix{X};\n#endif\n#endif\n#endif";
  1031. BABYLON.Effect.IncludesShadersStore['defaultVertexDeclaration'] = "\nuniform mat4 viewProjection;\nuniform mat4 view;\n#ifdef DIFFUSE\nuniform mat4 diffuseMatrix;\nuniform vec2 vDiffuseInfos;\n#endif\n#ifdef AMBIENT\nuniform mat4 ambientMatrix;\nuniform vec2 vAmbientInfos;\n#endif\n#ifdef OPACITY\nuniform mat4 opacityMatrix;\nuniform vec2 vOpacityInfos;\n#endif\n#ifdef EMISSIVE\nuniform vec2 vEmissiveInfos;\nuniform mat4 emissiveMatrix;\n#endif\n#ifdef LIGHTMAP\nuniform vec2 vLightmapInfos;\nuniform mat4 lightmapMatrix;\n#endif\n#if defined(SPECULAR) && defined(SPECULARTERM)\nuniform vec2 vSpecularInfos;\nuniform mat4 specularMatrix;\n#endif\n#ifdef BUMP\nuniform vec3 vBumpInfos;\nuniform mat4 bumpMatrix;\n#endif\n#ifdef POINTSIZE\nuniform float pointSize;\n#endif\n";
  1032. BABYLON.Effect.IncludesShadersStore['defaultFragmentDeclaration'] = "uniform vec4 vDiffuseColor;\n#ifdef SPECULARTERM\nuniform vec4 vSpecularColor;\n#endif\nuniform vec3 vEmissiveColor;\n\n#ifdef DIFFUSE\nuniform vec2 vDiffuseInfos;\n#endif\n#ifdef AMBIENT\nuniform vec2 vAmbientInfos;\n#endif\n#ifdef OPACITY \nuniform vec2 vOpacityInfos;\n#endif\n#ifdef EMISSIVE\nuniform vec2 vEmissiveInfos;\n#endif\n#ifdef LIGHTMAP\nuniform vec2 vLightmapInfos;\n#endif\n#ifdef BUMP\nuniform vec3 vBumpInfos;\nuniform vec2 vTangentSpaceParams;\n#endif\n#if defined(REFLECTIONMAP_SPHERICAL) || defined(REFLECTIONMAP_PROJECTION) || defined(REFRACTION)\nuniform mat4 view;\n#endif\n#ifdef REFRACTION\nuniform vec4 vRefractionInfos;\n#ifndef REFRACTIONMAP_3D\nuniform mat4 refractionMatrix;\n#endif\n#ifdef REFRACTIONFRESNEL\nuniform vec4 refractionLeftColor;\nuniform vec4 refractionRightColor;\n#endif\n#endif\n#if defined(SPECULAR) && defined(SPECULARTERM)\nuniform vec2 vSpecularInfos;\n#endif\n#ifdef DIFFUSEFRESNEL\nuniform vec4 diffuseLeftColor;\nuniform vec4 diffuseRightColor;\n#endif\n#ifdef OPACITYFRESNEL\nuniform vec4 opacityParts;\n#endif\n#ifdef EMISSIVEFRESNEL\nuniform vec4 emissiveLeftColor;\nuniform vec4 emissiveRightColor;\n#endif\n\n#ifdef REFLECTION\nuniform vec2 vReflectionInfos;\n#ifdef REFLECTIONMAP_SKYBOX\n#else\n#if defined(REFLECTIONMAP_PLANAR) || defined(REFLECTIONMAP_CUBIC) || defined(REFLECTIONMAP_PROJECTION)\nuniform mat4 reflectionMatrix;\n#endif\n#endif\n#ifdef REFLECTIONFRESNEL\nuniform vec4 reflectionLeftColor;\nuniform vec4 reflectionRightColor;\n#endif\n#endif";
  1033. BABYLON.Effect.IncludesShadersStore['defaultUboDeclaration'] = "layout(std140,column_major) uniform;\nuniform Material\n{\nvec4 diffuseLeftColor;\nvec4 diffuseRightColor;\nvec4 opacityParts;\nvec4 reflectionLeftColor;\nvec4 reflectionRightColor;\nvec4 refractionLeftColor;\nvec4 refractionRightColor;\nvec4 emissiveLeftColor; \nvec4 emissiveRightColor;\nvec2 vDiffuseInfos;\nvec2 vAmbientInfos;\nvec2 vOpacityInfos;\nvec2 vReflectionInfos;\nvec2 vEmissiveInfos;\nvec2 vLightmapInfos;\nvec2 vSpecularInfos;\nvec3 vBumpInfos;\nmat4 diffuseMatrix;\nmat4 ambientMatrix;\nmat4 opacityMatrix;\nmat4 reflectionMatrix;\nmat4 emissiveMatrix;\nmat4 lightmapMatrix;\nmat4 specularMatrix;\nmat4 bumpMatrix; \nvec4 vTangentSpaceParams;\nmat4 refractionMatrix;\nvec4 vRefractionInfos;\nvec4 vSpecularColor;\nvec3 vEmissiveColor;\nvec4 vDiffuseColor;\nfloat pointSize; \n};\nuniform Scene {\nmat4 viewProjection;\nmat4 view;\n};";
  1034. BABYLON.Effect.IncludesShadersStore['shadowsFragmentFunctions'] = "#ifdef SHADOWS\n#ifndef SHADOWFLOAT\nfloat unpack(vec4 color)\n{\nconst vec4 bit_shift=vec4(1.0/(255.0*255.0*255.0),1.0/(255.0*255.0),1.0/255.0,1.0);\nreturn dot(color,bit_shift);\n}\n#endif\nfloat computeShadowCube(vec3 lightPosition,samplerCube shadowSampler,float darkness,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\ndepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadow=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadow=textureCube(shadowSampler,directionToLight).x;\n#endif\nif (depth>shadow)\n{\nreturn darkness;\n}\nreturn 1.0;\n}\nfloat computeShadowWithPCFCube(vec3 lightPosition,samplerCube shadowSampler,float mapSize,float darkness,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\ndepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\nfloat visibility=1.;\nvec3 poissonDisk[4];\npoissonDisk[0]=vec3(-1.0,1.0,-1.0);\npoissonDisk[1]=vec3(1.0,-1.0,-1.0);\npoissonDisk[2]=vec3(-1.0,-1.0,-1.0);\npoissonDisk[3]=vec3(1.0,-1.0,1.0);\n\n#ifndef SHADOWFLOAT\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[0]*mapSize))<depth) visibility-=0.25;\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[1]*mapSize))<depth) visibility-=0.25;\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[2]*mapSize))<depth) visibility-=0.25;\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[3]*mapSize))<depth) visibility-=0.25;\n#else\nif (textureCube(shadowSampler,directionToLight+poissonDisk[0]*mapSize).x<depth) visibility-=0.25;\nif (textureCube(shadowSampler,directionToLight+poissonDisk[1]*mapSize).x<depth) visibility-=0.25;\nif (textureCube(shadowSampler,directionToLight+poissonDisk[2]*mapSize).x<depth) visibility-=0.25;\nif (textureCube(shadowSampler,directionToLight+poissonDisk[3]*mapSize).x<depth) visibility-=0.25;\n#endif\nreturn min(1.0,visibility+darkness);\n}\nfloat computeShadowWithESMCube(vec3 lightPosition,samplerCube shadowSampler,float darkness,float depthScale,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\nfloat shadowPixelDepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadowMapSample=textureCube(shadowSampler,directionToLight).x;\n#endif\nfloat esm=1.0-clamp(exp(min(87.,depthScale*shadowPixelDepth))*shadowMapSample,0.,1.-darkness); \nreturn esm;\n}\nfloat computeShadowWithCloseESMCube(vec3 lightPosition,samplerCube shadowSampler,float darkness,float depthScale,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\nfloat shadowPixelDepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadowMapSample=textureCube(shadowSampler,directionToLight).x;\n#endif\nfloat esm=clamp(exp(min(87.,-depthScale*(shadowPixelDepth-shadowMapSample))),darkness,1.);\nreturn esm;\n}\nfloat computeShadow(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadow=unpack(texture2D(shadowSampler,uv));\n#else\nfloat shadow=texture2D(shadowSampler,uv).x;\n#endif\nif (shadowPixelDepth>shadow)\n{\nreturn computeFallOff(darkness,clipSpace.xy,frustumEdgeFalloff);\n}\nreturn 1.;\n}\nfloat computeShadowWithPCF(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float mapSize,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\nfloat visibility=1.;\nvec2 poissonDisk[4];\npoissonDisk[0]=vec2(-0.94201624,-0.39906216);\npoissonDisk[1]=vec2(0.94558609,-0.76890725);\npoissonDisk[2]=vec2(-0.094184101,-0.92938870);\npoissonDisk[3]=vec2(0.34495938,0.29387760);\n\n#ifndef SHADOWFLOAT\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[0]*mapSize))<shadowPixelDepth) visibility-=0.25;\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[1]*mapSize))<shadowPixelDepth) visibility-=0.25;\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[2]*mapSize))<shadowPixelDepth) visibility-=0.25;\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[3]*mapSize))<shadowPixelDepth) visibility-=0.25;\n#else\nif (texture2D(shadowSampler,uv+poissonDisk[0]*mapSize).x<shadowPixelDepth) visibility-=0.25;\nif (texture2D(shadowSampler,uv+poissonDisk[1]*mapSize).x<shadowPixelDepth) visibility-=0.25;\nif (texture2D(shadowSampler,uv+poissonDisk[2]*mapSize).x<shadowPixelDepth) visibility-=0.25;\nif (texture2D(shadowSampler,uv+poissonDisk[3]*mapSize).x<shadowPixelDepth) visibility-=0.25;\n#endif\nreturn computeFallOff(min(1.0,visibility+darkness),clipSpace.xy,frustumEdgeFalloff);\n}\nfloat computeShadowWithESM(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float depthScale,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(texture2D(shadowSampler,uv));\n#else\nfloat shadowMapSample=texture2D(shadowSampler,uv).x;\n#endif\nfloat esm=1.0-clamp(exp(min(87.,depthScale*shadowPixelDepth))*shadowMapSample,0.,1.-darkness);\nreturn computeFallOff(esm,clipSpace.xy,frustumEdgeFalloff);\n}\nfloat computeShadowWithCloseESM(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float depthScale,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0); \n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(texture2D(shadowSampler,uv));\n#else\nfloat shadowMapSample=texture2D(shadowSampler,uv).x;\n#endif\nfloat esm=clamp(exp(min(87.,-depthScale*(shadowPixelDepth-shadowMapSample))),darkness,1.);\nreturn computeFallOff(esm,clipSpace.xy,frustumEdgeFalloff);\n}\n#endif\n";
  1035. BABYLON.Effect.IncludesShadersStore['fresnelFunction'] = "#ifdef FRESNEL\nfloat computeFresnelTerm(vec3 viewDirection,vec3 worldNormal,float bias,float power)\n{\nfloat fresnelTerm=pow(bias+abs(dot(viewDirection,worldNormal)),power);\nreturn clamp(fresnelTerm,0.,1.);\n}\n#endif";
  1036. BABYLON.Effect.IncludesShadersStore['reflectionFunction'] = "vec3 computeReflectionCoords(vec4 worldPos,vec3 worldNormal)\n{\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvec3 direction=normalize(vDirectionW);\nfloat t=clamp(direction.y*-0.5+0.5,0.,1.0);\nfloat s=atan(direction.z,direction.x)*RECIPROCAL_PI2+0.5;\n#ifdef REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED\nreturn vec3(1.0-s,t,0);\n#else\nreturn vec3(s,t,0);\n#endif\n#endif\n#ifdef REFLECTIONMAP_EQUIRECTANGULAR\nvec3 cameraToVertex=normalize(worldPos.xyz-vEyePosition.xyz);\nvec3 r=reflect(cameraToVertex,worldNormal);\nfloat t=clamp(r.y*-0.5+0.5,0.,1.0);\nfloat s=atan(r.z,r.x)*RECIPROCAL_PI2+0.5;\nreturn vec3(s,t,0);\n#endif\n#ifdef REFLECTIONMAP_SPHERICAL\nvec3 viewDir=normalize(vec3(view*worldPos));\nvec3 viewNormal=normalize(vec3(view*vec4(worldNormal,0.0)));\nvec3 r=reflect(viewDir,viewNormal);\nr.z=r.z-1.0;\nfloat m=2.0*length(r);\nreturn vec3(r.x/m+0.5,1.0-r.y/m-0.5,0);\n#endif\n#ifdef REFLECTIONMAP_PLANAR\nvec3 viewDir=worldPos.xyz-vEyePosition.xyz;\nvec3 coords=normalize(reflect(viewDir,worldNormal));\nreturn vec3(reflectionMatrix*vec4(coords,1));\n#endif\n#ifdef REFLECTIONMAP_CUBIC\nvec3 viewDir=worldPos.xyz-vEyePosition.xyz;\nvec3 coords=reflect(viewDir,worldNormal);\n#ifdef INVERTCUBICMAP\ncoords.y=1.0-coords.y;\n#endif\nreturn vec3(reflectionMatrix*vec4(coords,0));\n#endif\n#ifdef REFLECTIONMAP_PROJECTION\nreturn vec3(reflectionMatrix*(view*worldPos));\n#endif\n#ifdef REFLECTIONMAP_SKYBOX\nreturn vPositionUVW;\n#endif\n#ifdef REFLECTIONMAP_EXPLICIT\nreturn vec3(0,0,0);\n#endif\n}";
  1037. BABYLON.Effect.IncludesShadersStore['imageProcessingDeclaration'] = "#ifdef EXPOSURE\nuniform float exposureLinear;\n#endif\n#ifdef CONTRAST\nuniform float contrast;\n#endif\n#ifdef VIGNETTE\nuniform vec2 vInverseScreenSize;\nuniform vec4 vignetteSettings1;\nuniform vec4 vignetteSettings2;\n#endif\n#ifdef COLORCURVES\nuniform vec4 vCameraColorCurveNegative;\nuniform vec4 vCameraColorCurveNeutral;\nuniform vec4 vCameraColorCurvePositive;\n#endif\n#ifdef COLORGRADING\n#ifdef COLORGRADING3D\nuniform highp sampler3D txColorTransform;\n#else\nuniform sampler2D txColorTransform;\n#endif\nuniform vec4 colorTransformSettings;\n#endif";
  1038. BABYLON.Effect.IncludesShadersStore['imageProcessingFunctions'] = "#if defined(COLORGRADING) && !defined(COLORGRADING3D)\n\nvec3 sampleTexture3D(sampler2D colorTransform,vec3 color,vec2 sampler3dSetting)\n{\nfloat sliceSize=2.0*sampler3dSetting.x; \n#ifdef SAMPLER3DGREENDEPTH\nfloat sliceContinuous=(color.g-sampler3dSetting.x)*sampler3dSetting.y;\n#else\nfloat sliceContinuous=(color.b-sampler3dSetting.x)*sampler3dSetting.y;\n#endif\nfloat sliceInteger=floor(sliceContinuous);\n\n\nfloat sliceFraction=sliceContinuous-sliceInteger;\n#ifdef SAMPLER3DGREENDEPTH\nvec2 sliceUV=color.rb;\n#else\nvec2 sliceUV=color.rg;\n#endif\nsliceUV.x*=sliceSize;\nsliceUV.x+=sliceInteger*sliceSize;\nsliceUV=clamp(sliceUV,0.,1.);\nvec4 slice0Color=texture2D(colorTransform,sliceUV);\nsliceUV.x+=sliceSize;\nsliceUV=clamp(sliceUV,0.,1.);\nvec4 slice1Color=texture2D(colorTransform,sliceUV);\nvec3 result=mix(slice0Color.rgb,slice1Color.rgb,sliceFraction);\n#ifdef SAMPLER3DBGRMAP\ncolor.rgb=result.rgb;\n#else\ncolor.rgb=result.bgr;\n#endif\nreturn color;\n}\n#endif\nvec4 applyImageProcessing(vec4 result) {\n#ifdef EXPOSURE\nresult.rgb*=exposureLinear;\n#endif\n#ifdef VIGNETTE\n\nvec2 viewportXY=gl_FragCoord.xy*vInverseScreenSize;\nviewportXY=viewportXY*2.0-1.0;\nvec3 vignetteXY1=vec3(viewportXY*vignetteSettings1.xy+vignetteSettings1.zw,1.0);\nfloat vignetteTerm=dot(vignetteXY1,vignetteXY1);\nfloat vignette=pow(vignetteTerm,vignetteSettings2.w);\n\nvec3 vignetteColor=vignetteSettings2.rgb;\n#ifdef VIGNETTEBLENDMODEMULTIPLY\nvec3 vignetteColorMultiplier=mix(vignetteColor,vec3(1,1,1),vignette);\nresult.rgb*=vignetteColorMultiplier;\n#endif\n#ifdef VIGNETTEBLENDMODEOPAQUE\nresult.rgb=mix(vignetteColor,result.rgb,vignette);\n#endif\n#endif\n#ifdef TONEMAPPING\nconst float tonemappingCalibration=1.590579;\nresult.rgb=1.0-exp2(-tonemappingCalibration*result.rgb);\n#endif\n\nresult.rgb=toGammaSpace(result.rgb);\nresult.rgb=clamp(result.rgb,0.0,1.0);\n#ifdef CONTRAST\n\nvec3 resultHighContrast=applyEaseInOut(result.rgb);\nif (contrast<1.0) {\n\nresult.rgb=mix(vec3(0.5,0.5,0.5),result.rgb,contrast);\n} else {\n\nresult.rgb=mix(result.rgb,resultHighContrast,contrast-1.0);\n}\n#endif\n\n#ifdef COLORGRADING\nvec3 colorTransformInput=result.rgb*colorTransformSettings.xxx+colorTransformSettings.yyy;\n#ifdef COLORGRADING3D\nvec3 colorTransformOutput=texture(txColorTransform,colorTransformInput).rgb;\n#else\nvec3 colorTransformOutput=sampleTexture3D(txColorTransform,colorTransformInput,colorTransformSettings.yz).rgb;\n#endif\nresult.rgb=mix(result.rgb,colorTransformOutput,colorTransformSettings.www);\n#endif\n#ifdef COLORCURVES\n\nfloat luma=getLuminance(result.rgb);\nvec2 curveMix=clamp(vec2(luma*3.0-1.5,luma*-3.0+1.5),vec2(0.0),vec2(1.0));\nvec4 colorCurve=vCameraColorCurveNeutral+curveMix.x*vCameraColorCurvePositive-curveMix.y*vCameraColorCurveNegative;\nresult.rgb*=colorCurve.rgb;\nresult.rgb=mix(vec3(luma),result.rgb,colorCurve.a);\n#endif\nreturn result;\n}";
  1039. BABYLON.Effect.IncludesShadersStore['bumpFragmentFunctions'] = "#ifdef BUMP\n#if BUMPDIRECTUV == 1\n#define vBumpUV vMainUV1\n#elif BUMPDIRECTUV == 2\n#define vBumpUV vMainUV2\n#else\nvarying vec2 vBumpUV;\n#endif\nuniform sampler2D bumpSampler;\n#if defined(TANGENT) && defined(NORMAL) \nvarying mat3 vTBN;\n#endif\n\nmat3 cotangent_frame(vec3 normal,vec3 p,vec2 uv)\n{\n\nuv=gl_FrontFacing ? uv : -uv;\n\nvec3 dp1=dFdx(p);\nvec3 dp2=dFdy(p);\nvec2 duv1=dFdx(uv);\nvec2 duv2=dFdy(uv);\n\nvec3 dp2perp=cross(dp2,normal);\nvec3 dp1perp=cross(normal,dp1);\nvec3 tangent=dp2perp*duv1.x+dp1perp*duv2.x;\nvec3 bitangent=dp2perp*duv1.y+dp1perp*duv2.y;\n\ntangent*=vTangentSpaceParams.x;\nbitangent*=vTangentSpaceParams.y;\n\nfloat invmax=inversesqrt(max(dot(tangent,tangent),dot(bitangent,bitangent)));\nreturn mat3(tangent*invmax,bitangent*invmax,normal);\n}\nvec3 perturbNormal(mat3 cotangentFrame,vec2 uv)\n{\nvec3 map=texture2D(bumpSampler,uv).xyz;\nmap=map*2.0-1.0;\n#ifdef NORMALXYSCALE\nmap=normalize(map*vec3(vBumpInfos.y,vBumpInfos.y,1.0));\n#endif\nreturn normalize(cotangentFrame*map);\n}\n#ifdef PARALLAX\nconst float minSamples=4.;\nconst float maxSamples=15.;\nconst int iMaxSamples=15;\n\nvec2 parallaxOcclusion(vec3 vViewDirCoT,vec3 vNormalCoT,vec2 texCoord,float parallaxScale) {\nfloat parallaxLimit=length(vViewDirCoT.xy)/vViewDirCoT.z;\nparallaxLimit*=parallaxScale;\nvec2 vOffsetDir=normalize(vViewDirCoT.xy);\nvec2 vMaxOffset=vOffsetDir*parallaxLimit;\nfloat numSamples=maxSamples+(dot(vViewDirCoT,vNormalCoT)*(minSamples-maxSamples));\nfloat stepSize=1.0/numSamples;\n\nfloat currRayHeight=1.0;\nvec2 vCurrOffset=vec2(0,0);\nvec2 vLastOffset=vec2(0,0);\nfloat lastSampledHeight=1.0;\nfloat currSampledHeight=1.0;\nfor (int i=0; i<iMaxSamples; i++)\n{\ncurrSampledHeight=texture2D(bumpSampler,vBumpUV+vCurrOffset).w;\n\nif (currSampledHeight>currRayHeight)\n{\nfloat delta1=currSampledHeight-currRayHeight;\nfloat delta2=(currRayHeight+stepSize)-lastSampledHeight;\nfloat ratio=delta1/(delta1+delta2);\nvCurrOffset=(ratio)* vLastOffset+(1.0-ratio)*vCurrOffset;\n\nbreak;\n}\nelse\n{\ncurrRayHeight-=stepSize;\nvLastOffset=vCurrOffset;\nvCurrOffset+=stepSize*vMaxOffset;\nlastSampledHeight=currSampledHeight;\n}\n}\nreturn vCurrOffset;\n}\nvec2 parallaxOffset(vec3 viewDir,float heightScale)\n{\n\nfloat height=texture2D(bumpSampler,vBumpUV).w;\nvec2 texCoordOffset=heightScale*viewDir.xy*height;\nreturn -texCoordOffset;\n}\n#endif\n#endif";
  1040. BABYLON.Effect.IncludesShadersStore['clipPlaneFragmentDeclaration'] = "#ifdef CLIPPLANE\nvarying float fClipDistance;\n#endif";
  1041. BABYLON.Effect.IncludesShadersStore['fogFragmentDeclaration'] = "#ifdef FOG\n#define FOGMODE_NONE 0.\n#define FOGMODE_EXP 1.\n#define FOGMODE_EXP2 2.\n#define FOGMODE_LINEAR 3.\n#define E 2.71828\nuniform vec4 vFogInfos;\nuniform vec3 vFogColor;\nvarying vec3 vFogDistance;\nfloat CalcFogFactor()\n{\nfloat fogCoeff=1.0;\nfloat fogStart=vFogInfos.y;\nfloat fogEnd=vFogInfos.z;\nfloat fogDensity=vFogInfos.w;\nfloat fogDistance=length(vFogDistance);\nif (FOGMODE_LINEAR == vFogInfos.x)\n{\nfogCoeff=(fogEnd-fogDistance)/(fogEnd-fogStart);\n}\nelse if (FOGMODE_EXP == vFogInfos.x)\n{\nfogCoeff=1.0/pow(E,fogDistance*fogDensity);\n}\nelse if (FOGMODE_EXP2 == vFogInfos.x)\n{\nfogCoeff=1.0/pow(E,fogDistance*fogDistance*fogDensity*fogDensity);\n}\nreturn clamp(fogCoeff,0.0,1.0);\n}\n#endif";
  1042. BABYLON.Effect.IncludesShadersStore['clipPlaneFragment'] = "#ifdef CLIPPLANE\nif (fClipDistance>0.0)\n{\ndiscard;\n}\n#endif";
  1043. BABYLON.Effect.IncludesShadersStore['bumpFragment'] = "vec2 uvOffset=vec2(0.0,0.0);\n#if defined(BUMP) || defined(PARALLAX)\n#ifdef NORMALXYSCALE\nfloat normalScale=1.0;\n#else \nfloat normalScale=vBumpInfos.y;\n#endif\n#if defined(TANGENT) && defined(NORMAL)\nmat3 TBN=vTBN;\n#else\nmat3 TBN=cotangent_frame(normalW*normalScale,vPositionW,vBumpUV);\n#endif\n#endif\n#ifdef PARALLAX\nmat3 invTBN=transposeMat3(TBN);\n#ifdef PARALLAXOCCLUSION\nuvOffset=parallaxOcclusion(invTBN*-viewDirectionW,invTBN*normalW,vBumpUV,vBumpInfos.z);\n#else\nuvOffset=parallaxOffset(invTBN*viewDirectionW,vBumpInfos.z);\n#endif\n#endif\n#ifdef BUMP\nnormalW=perturbNormal(TBN,vBumpUV+uvOffset);\n#endif";
  1044. BABYLON.Effect.IncludesShadersStore['lightFragment'] = "#ifdef LIGHT{X}\n#if defined(SHADOWONLY) || (defined(LIGHTMAP) && defined(LIGHTMAPEXCLUDED{X}) && defined(LIGHTMAPNOSPECULAR{X}))\n\n#else\n#ifdef PBR\n#ifdef SPOTLIGHT{X}\ninfo=computeSpotLighting(viewDirectionW,normalW,light{X}.vLightData,light{X}.vLightDirection,light{X}.vLightDiffuse.rgb,light{X}.vLightSpecular,light{X}.vLightDiffuse.a,roughness,NdotV,specularEnvironmentR0,specularEnvironmentR90,NdotL);\n#endif\n#ifdef HEMILIGHT{X}\ninfo=computeHemisphericLighting(viewDirectionW,normalW,light{X}.vLightData,light{X}.vLightDiffuse.rgb,light{X}.vLightSpecular,light{X}.vLightGround,roughness,NdotV,specularEnvironmentR0,specularEnvironmentR90,NdotL);\n#endif\n#if defined(POINTLIGHT{X}) || defined(DIRLIGHT{X})\ninfo=computeLighting(viewDirectionW,normalW,light{X}.vLightData,light{X}.vLightDiffuse.rgb,light{X}.vLightSpecular,light{X}.vLightDiffuse.a,roughness,NdotV,specularEnvironmentR0,specularEnvironmentR90,NdotL);\n#endif\n#else\n#ifdef SPOTLIGHT{X}\ninfo=computeSpotLighting(viewDirectionW,normalW,light{X}.vLightData,light{X}.vLightDirection,light{X}.vLightDiffuse.rgb,light{X}.vLightSpecular,light{X}.vLightDiffuse.a,glossiness);\n#endif\n#ifdef HEMILIGHT{X}\ninfo=computeHemisphericLighting(viewDirectionW,normalW,light{X}.vLightData,light{X}.vLightDiffuse.rgb,light{X}.vLightSpecular,light{X}.vLightGround,glossiness);\n#endif\n#if defined(POINTLIGHT{X}) || defined(DIRLIGHT{X})\ninfo=computeLighting(viewDirectionW,normalW,light{X}.vLightData,light{X}.vLightDiffuse.rgb,light{X}.vLightSpecular,light{X}.vLightDiffuse.a,glossiness);\n#endif\n#endif\n#endif\n#ifdef SHADOW{X}\n#ifdef SHADOWCLOSEESM{X}\n#if defined(SHADOWCUBE{X})\nshadow=computeShadowWithCloseESMCube(light{X}.vLightData.xyz,shadowSampler{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.z,light{X}.depthValues);\n#else\nshadow=computeShadowWithCloseESM(vPositionFromLight{X},vDepthMetric{X},shadowSampler{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.z,light{X}.shadowsInfo.w);\n#endif\n#else\n#ifdef SHADOWESM{X}\n#if defined(SHADOWCUBE{X})\nshadow=computeShadowWithESMCube(light{X}.vLightData.xyz,shadowSampler{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.z,light{X}.depthValues);\n#else\nshadow=computeShadowWithESM(vPositionFromLight{X},vDepthMetric{X},shadowSampler{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.z,light{X}.shadowsInfo.w);\n#endif\n#else \n#ifdef SHADOWPCF{X}\n#if defined(SHADOWCUBE{X})\nshadow=computeShadowWithPCFCube(light{X}.vLightData.xyz,shadowSampler{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.x,light{X}.depthValues);\n#else\nshadow=computeShadowWithPCF(vPositionFromLight{X},vDepthMetric{X},shadowSampler{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#else\n#if defined(SHADOWCUBE{X})\nshadow=computeShadowCube(light{X}.vLightData.xyz,shadowSampler{X},light{X}.shadowsInfo.x,light{X}.depthValues);\n#else\nshadow=computeShadow(vPositionFromLight{X},vDepthMetric{X},shadowSampler{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#endif\n#endif\n#endif\n#ifdef SHADOWONLY\n#ifndef SHADOWINUSE\n#define SHADOWINUSE\n#endif\nglobalShadow+=shadow;\nshadowLightCount+=1.0;\n#endif\n#else\nshadow=1.;\n#endif\n#ifndef SHADOWONLY\n#ifdef CUSTOMUSERLIGHTING\ndiffuseBase+=computeCustomDiffuseLighting(info,diffuseBase,shadow);\n#ifdef SPECULARTERM\nspecularBase+=computeCustomSpecularLighting(info,specularBase,shadow);\n#endif\n#elif defined(LIGHTMAP) && defined(LIGHTMAPEXCLUDED{X})\ndiffuseBase+=lightmapColor*shadow;\n#ifdef SPECULARTERM\n#ifndef LIGHTMAPNOSPECULAR{X}\nspecularBase+=info.specular*shadow*lightmapColor;\n#endif\n#endif\n#else\ndiffuseBase+=info.diffuse*shadow;\n#ifdef SPECULARTERM\nspecularBase+=info.specular*shadow;\n#endif\n#endif\n#endif\n#endif";
  1045. BABYLON.Effect.IncludesShadersStore['logDepthFragment'] = "#ifdef LOGARITHMICDEPTH\ngl_FragDepthEXT=log2(vFragmentDepth)*logarithmicDepthConstant*0.5;\n#endif";
  1046. BABYLON.Effect.IncludesShadersStore['fogFragment'] = "#ifdef FOG\nfloat fog=CalcFogFactor();\ncolor.rgb=fog*color.rgb+(1.0-fog)*vFogColor;\n#endif";
  1047. (function() {
  1048. var EXPORTS = {};EXPORTS['SimplificationSettings'] = BABYLON['SimplificationSettings'];EXPORTS['SimplificationQueue'] = BABYLON['SimplificationQueue'];EXPORTS['SimplificationType'] = BABYLON['SimplificationType'];EXPORTS['DecimationTriangle'] = BABYLON['DecimationTriangle'];EXPORTS['DecimationVertex'] = BABYLON['DecimationVertex'];EXPORTS['QuadraticMatrix'] = BABYLON['QuadraticMatrix'];EXPORTS['Reference'] = BABYLON['Reference'];EXPORTS['QuadraticErrorSimplification'] = BABYLON['QuadraticErrorSimplification'];EXPORTS['MeshLODLevel'] = BABYLON['MeshLODLevel'];EXPORTS['SceneOptimization'] = BABYLON['SceneOptimization'];EXPORTS['TextureOptimization'] = BABYLON['TextureOptimization'];EXPORTS['HardwareScalingOptimization'] = BABYLON['HardwareScalingOptimization'];EXPORTS['ShadowsOptimization'] = BABYLON['ShadowsOptimization'];EXPORTS['PostProcessesOptimization'] = BABYLON['PostProcessesOptimization'];EXPORTS['LensFlaresOptimization'] = BABYLON['LensFlaresOptimization'];EXPORTS['ParticlesOptimization'] = BABYLON['ParticlesOptimization'];EXPORTS['RenderTargetsOptimization'] = BABYLON['RenderTargetsOptimization'];EXPORTS['MergeMeshesOptimization'] = BABYLON['MergeMeshesOptimization'];EXPORTS['SceneOptimizerOptions'] = BABYLON['SceneOptimizerOptions'];EXPORTS['SceneOptimizer'] = BABYLON['SceneOptimizer'];
  1049. globalObject["BABYLON"] = globalObject["BABYLON"] || BABYLON;
  1050. module.exports = EXPORTS;
  1051. })();
  1052. }