es6.js 95 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074
  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. import * as BABYLON from 'babylonjs/core/es6';
  12. var BABYLON;
  13. (function (BABYLON) {
  14. var SimplificationSettings = /** @class */ (function () {
  15. function SimplificationSettings(quality, distance, optimizeMesh) {
  16. this.quality = quality;
  17. this.distance = distance;
  18. this.optimizeMesh = optimizeMesh;
  19. }
  20. return SimplificationSettings;
  21. }());
  22. BABYLON.SimplificationSettings = SimplificationSettings;
  23. var SimplificationQueue = /** @class */ (function () {
  24. function SimplificationQueue() {
  25. this.running = false;
  26. this._simplificationArray = [];
  27. }
  28. SimplificationQueue.prototype.addTask = function (task) {
  29. this._simplificationArray.push(task);
  30. };
  31. SimplificationQueue.prototype.executeNext = function () {
  32. var task = this._simplificationArray.pop();
  33. if (task) {
  34. this.running = true;
  35. this.runSimplification(task);
  36. }
  37. else {
  38. this.running = false;
  39. }
  40. };
  41. SimplificationQueue.prototype.runSimplification = function (task) {
  42. var _this = this;
  43. if (task.parallelProcessing) {
  44. //parallel simplifier
  45. task.settings.forEach(function (setting) {
  46. var simplifier = _this.getSimplifier(task);
  47. simplifier.simplify(setting, function (newMesh) {
  48. task.mesh.addLODLevel(setting.distance, newMesh);
  49. newMesh.isVisible = true;
  50. //check if it is the last
  51. if (setting.quality === task.settings[task.settings.length - 1].quality && task.successCallback) {
  52. //all done, run the success callback.
  53. task.successCallback();
  54. }
  55. _this.executeNext();
  56. });
  57. });
  58. }
  59. else {
  60. //single simplifier.
  61. var simplifier = this.getSimplifier(task);
  62. var runDecimation = function (setting, callback) {
  63. simplifier.simplify(setting, function (newMesh) {
  64. task.mesh.addLODLevel(setting.distance, newMesh);
  65. newMesh.isVisible = true;
  66. //run the next quality level
  67. callback();
  68. });
  69. };
  70. BABYLON.AsyncLoop.Run(task.settings.length, function (loop) {
  71. runDecimation(task.settings[loop.index], function () {
  72. loop.executeNext();
  73. });
  74. }, function () {
  75. //execution ended, run the success callback.
  76. if (task.successCallback) {
  77. task.successCallback();
  78. }
  79. _this.executeNext();
  80. });
  81. }
  82. };
  83. SimplificationQueue.prototype.getSimplifier = function (task) {
  84. switch (task.simplificationType) {
  85. case SimplificationType.QUADRATIC:
  86. default:
  87. return new QuadraticErrorSimplification(task.mesh);
  88. }
  89. };
  90. return SimplificationQueue;
  91. }());
  92. BABYLON.SimplificationQueue = SimplificationQueue;
  93. /**
  94. * The implemented types of simplification.
  95. * At the moment only Quadratic Error Decimation is implemented.
  96. */
  97. var SimplificationType;
  98. (function (SimplificationType) {
  99. SimplificationType[SimplificationType["QUADRATIC"] = 0] = "QUADRATIC";
  100. })(SimplificationType = BABYLON.SimplificationType || (BABYLON.SimplificationType = {}));
  101. var DecimationTriangle = /** @class */ (function () {
  102. function DecimationTriangle(vertices) {
  103. this.vertices = vertices;
  104. this.error = new Array(4);
  105. this.deleted = false;
  106. this.isDirty = false;
  107. this.deletePending = false;
  108. this.borderFactor = 0;
  109. }
  110. return DecimationTriangle;
  111. }());
  112. BABYLON.DecimationTriangle = DecimationTriangle;
  113. var DecimationVertex = /** @class */ (function () {
  114. function DecimationVertex(position, id) {
  115. this.position = position;
  116. this.id = id;
  117. this.isBorder = true;
  118. this.q = new QuadraticMatrix();
  119. this.triangleCount = 0;
  120. this.triangleStart = 0;
  121. this.originalOffsets = [];
  122. }
  123. DecimationVertex.prototype.updatePosition = function (newPosition) {
  124. this.position.copyFrom(newPosition);
  125. };
  126. return DecimationVertex;
  127. }());
  128. BABYLON.DecimationVertex = DecimationVertex;
  129. var QuadraticMatrix = /** @class */ (function () {
  130. function QuadraticMatrix(data) {
  131. this.data = new Array(10);
  132. for (var i = 0; i < 10; ++i) {
  133. if (data && data[i]) {
  134. this.data[i] = data[i];
  135. }
  136. else {
  137. this.data[i] = 0;
  138. }
  139. }
  140. }
  141. QuadraticMatrix.prototype.det = function (a11, a12, a13, a21, a22, a23, a31, a32, a33) {
  142. var det = this.data[a11] * this.data[a22] * this.data[a33] + this.data[a13] * this.data[a21] * this.data[a32] +
  143. this.data[a12] * this.data[a23] * this.data[a31] - this.data[a13] * this.data[a22] * this.data[a31] -
  144. this.data[a11] * this.data[a23] * this.data[a32] - this.data[a12] * this.data[a21] * this.data[a33];
  145. return det;
  146. };
  147. QuadraticMatrix.prototype.addInPlace = function (matrix) {
  148. for (var i = 0; i < 10; ++i) {
  149. this.data[i] += matrix.data[i];
  150. }
  151. };
  152. QuadraticMatrix.prototype.addArrayInPlace = function (data) {
  153. for (var i = 0; i < 10; ++i) {
  154. this.data[i] += data[i];
  155. }
  156. };
  157. QuadraticMatrix.prototype.add = function (matrix) {
  158. var m = new QuadraticMatrix();
  159. for (var i = 0; i < 10; ++i) {
  160. m.data[i] = this.data[i] + matrix.data[i];
  161. }
  162. return m;
  163. };
  164. QuadraticMatrix.FromData = function (a, b, c, d) {
  165. return new QuadraticMatrix(QuadraticMatrix.DataFromNumbers(a, b, c, d));
  166. };
  167. //returning an array to avoid garbage collection
  168. QuadraticMatrix.DataFromNumbers = function (a, b, c, d) {
  169. return [a * a, a * b, a * c, a * d, b * b, b * c, b * d, c * c, c * d, d * d];
  170. };
  171. return QuadraticMatrix;
  172. }());
  173. BABYLON.QuadraticMatrix = QuadraticMatrix;
  174. var Reference = /** @class */ (function () {
  175. function Reference(vertexId, triangleId) {
  176. this.vertexId = vertexId;
  177. this.triangleId = triangleId;
  178. }
  179. return Reference;
  180. }());
  181. BABYLON.Reference = Reference;
  182. /**
  183. * An implementation of the Quadratic Error simplification algorithm.
  184. * Original paper : http://www1.cs.columbia.edu/~cs4162/html05s/garland97.pdf
  185. * Ported mostly from QSlim and http://voxels.blogspot.de/2014/05/quadric-mesh-simplification-with-source.html to babylon JS
  186. * @author RaananW
  187. */
  188. var QuadraticErrorSimplification = /** @class */ (function () {
  189. function QuadraticErrorSimplification(_mesh) {
  190. this._mesh = _mesh;
  191. this.syncIterations = 5000;
  192. this.aggressiveness = 7;
  193. this.decimationIterations = 100;
  194. this.boundingBoxEpsilon = BABYLON.Epsilon;
  195. }
  196. QuadraticErrorSimplification.prototype.simplify = function (settings, successCallback) {
  197. var _this = this;
  198. this.initDecimatedMesh();
  199. //iterating through the submeshes array, one after the other.
  200. BABYLON.AsyncLoop.Run(this._mesh.subMeshes.length, function (loop) {
  201. _this.initWithMesh(loop.index, function () {
  202. _this.runDecimation(settings, loop.index, function () {
  203. loop.executeNext();
  204. });
  205. }, settings.optimizeMesh);
  206. }, function () {
  207. setTimeout(function () {
  208. successCallback(_this._reconstructedMesh);
  209. }, 0);
  210. });
  211. };
  212. QuadraticErrorSimplification.prototype.runDecimation = function (settings, submeshIndex, successCallback) {
  213. var _this = this;
  214. var targetCount = ~~(this.triangles.length * settings.quality);
  215. var deletedTriangles = 0;
  216. var triangleCount = this.triangles.length;
  217. var iterationFunction = function (iteration, callback) {
  218. setTimeout(function () {
  219. if (iteration % 5 === 0) {
  220. _this.updateMesh(iteration === 0);
  221. }
  222. for (var i = 0; i < _this.triangles.length; ++i) {
  223. _this.triangles[i].isDirty = false;
  224. }
  225. var threshold = 0.000000001 * Math.pow((iteration + 3), _this.aggressiveness);
  226. var trianglesIterator = function (i) {
  227. var tIdx = ~~(((_this.triangles.length / 2) + i) % _this.triangles.length);
  228. var t = _this.triangles[tIdx];
  229. if (!t)
  230. return;
  231. if (t.error[3] > threshold || t.deleted || t.isDirty) {
  232. return;
  233. }
  234. for (var j = 0; j < 3; ++j) {
  235. if (t.error[j] < threshold) {
  236. var deleted0 = [];
  237. var deleted1 = [];
  238. var v0 = t.vertices[j];
  239. var v1 = t.vertices[(j + 1) % 3];
  240. if (v0.isBorder || v1.isBorder)
  241. continue;
  242. var p = BABYLON.Vector3.Zero();
  243. var n = BABYLON.Vector3.Zero();
  244. var uv = BABYLON.Vector2.Zero();
  245. var color = new BABYLON.Color4(0, 0, 0, 1);
  246. _this.calculateError(v0, v1, p, n, uv, color);
  247. var delTr = new Array();
  248. if (_this.isFlipped(v0, v1, p, deleted0, t.borderFactor, delTr))
  249. continue;
  250. if (_this.isFlipped(v1, v0, p, deleted1, t.borderFactor, delTr))
  251. continue;
  252. if (deleted0.indexOf(true) < 0 || deleted1.indexOf(true) < 0)
  253. continue;
  254. var uniqueArray = new Array();
  255. delTr.forEach(function (deletedT) {
  256. if (uniqueArray.indexOf(deletedT) === -1) {
  257. deletedT.deletePending = true;
  258. uniqueArray.push(deletedT);
  259. }
  260. });
  261. if (uniqueArray.length % 2 !== 0) {
  262. continue;
  263. }
  264. v0.q = v1.q.add(v0.q);
  265. v0.updatePosition(p);
  266. var tStart = _this.references.length;
  267. deletedTriangles = _this.updateTriangles(v0, v0, deleted0, deletedTriangles);
  268. deletedTriangles = _this.updateTriangles(v0, v1, deleted1, deletedTriangles);
  269. var tCount = _this.references.length - tStart;
  270. if (tCount <= v0.triangleCount) {
  271. if (tCount) {
  272. for (var c = 0; c < tCount; c++) {
  273. _this.references[v0.triangleStart + c] = _this.references[tStart + c];
  274. }
  275. }
  276. }
  277. else {
  278. v0.triangleStart = tStart;
  279. }
  280. v0.triangleCount = tCount;
  281. break;
  282. }
  283. }
  284. };
  285. BABYLON.AsyncLoop.SyncAsyncForLoop(_this.triangles.length, _this.syncIterations, trianglesIterator, callback, function () { return (triangleCount - deletedTriangles <= targetCount); });
  286. }, 0);
  287. };
  288. BABYLON.AsyncLoop.Run(this.decimationIterations, function (loop) {
  289. if (triangleCount - deletedTriangles <= targetCount)
  290. loop.breakLoop();
  291. else {
  292. iterationFunction(loop.index, function () {
  293. loop.executeNext();
  294. });
  295. }
  296. }, function () {
  297. setTimeout(function () {
  298. //reconstruct this part of the mesh
  299. _this.reconstructMesh(submeshIndex);
  300. successCallback();
  301. }, 0);
  302. });
  303. };
  304. QuadraticErrorSimplification.prototype.initWithMesh = function (submeshIndex, callback, optimizeMesh) {
  305. var _this = this;
  306. this.vertices = [];
  307. this.triangles = [];
  308. var positionData = this._mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
  309. var indices = this._mesh.getIndices();
  310. var submesh = this._mesh.subMeshes[submeshIndex];
  311. var findInVertices = function (positionToSearch) {
  312. if (optimizeMesh) {
  313. for (var ii = 0; ii < _this.vertices.length; ++ii) {
  314. if (_this.vertices[ii].position.equals(positionToSearch)) {
  315. return _this.vertices[ii];
  316. }
  317. }
  318. }
  319. return null;
  320. };
  321. var vertexReferences = [];
  322. var vertexInit = function (i) {
  323. if (!positionData) {
  324. return;
  325. }
  326. var offset = i + submesh.verticesStart;
  327. var position = BABYLON.Vector3.FromArray(positionData, offset * 3);
  328. var vertex = findInVertices(position) || new DecimationVertex(position, _this.vertices.length);
  329. vertex.originalOffsets.push(offset);
  330. if (vertex.id === _this.vertices.length) {
  331. _this.vertices.push(vertex);
  332. }
  333. vertexReferences.push(vertex.id);
  334. };
  335. //var totalVertices = mesh.getTotalVertices();
  336. var totalVertices = submesh.verticesCount;
  337. BABYLON.AsyncLoop.SyncAsyncForLoop(totalVertices, (this.syncIterations / 4) >> 0, vertexInit, function () {
  338. var indicesInit = function (i) {
  339. if (!indices) {
  340. return;
  341. }
  342. var offset = (submesh.indexStart / 3) + i;
  343. var pos = (offset * 3);
  344. var i0 = indices[pos + 0];
  345. var i1 = indices[pos + 1];
  346. var i2 = indices[pos + 2];
  347. var v0 = _this.vertices[vertexReferences[i0 - submesh.verticesStart]];
  348. var v1 = _this.vertices[vertexReferences[i1 - submesh.verticesStart]];
  349. var v2 = _this.vertices[vertexReferences[i2 - submesh.verticesStart]];
  350. var triangle = new DecimationTriangle([v0, v1, v2]);
  351. triangle.originalOffset = pos;
  352. _this.triangles.push(triangle);
  353. };
  354. BABYLON.AsyncLoop.SyncAsyncForLoop(submesh.indexCount / 3, _this.syncIterations, indicesInit, function () {
  355. _this.init(callback);
  356. });
  357. });
  358. };
  359. QuadraticErrorSimplification.prototype.init = function (callback) {
  360. var _this = this;
  361. var triangleInit1 = function (i) {
  362. var t = _this.triangles[i];
  363. t.normal = BABYLON.Vector3.Cross(t.vertices[1].position.subtract(t.vertices[0].position), t.vertices[2].position.subtract(t.vertices[0].position)).normalize();
  364. for (var j = 0; j < 3; j++) {
  365. 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))));
  366. }
  367. };
  368. BABYLON.AsyncLoop.SyncAsyncForLoop(this.triangles.length, this.syncIterations, triangleInit1, function () {
  369. var triangleInit2 = function (i) {
  370. var t = _this.triangles[i];
  371. for (var j = 0; j < 3; ++j) {
  372. t.error[j] = _this.calculateError(t.vertices[j], t.vertices[(j + 1) % 3]);
  373. }
  374. t.error[3] = Math.min(t.error[0], t.error[1], t.error[2]);
  375. };
  376. BABYLON.AsyncLoop.SyncAsyncForLoop(_this.triangles.length, _this.syncIterations, triangleInit2, function () {
  377. callback();
  378. });
  379. });
  380. };
  381. QuadraticErrorSimplification.prototype.reconstructMesh = function (submeshIndex) {
  382. var newTriangles = [];
  383. var i;
  384. for (i = 0; i < this.vertices.length; ++i) {
  385. this.vertices[i].triangleCount = 0;
  386. }
  387. var t;
  388. var j;
  389. for (i = 0; i < this.triangles.length; ++i) {
  390. if (!this.triangles[i].deleted) {
  391. t = this.triangles[i];
  392. for (j = 0; j < 3; ++j) {
  393. t.vertices[j].triangleCount = 1;
  394. }
  395. newTriangles.push(t);
  396. }
  397. }
  398. var newPositionData = (this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.PositionKind) || []);
  399. var newNormalData = (this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.NormalKind) || []);
  400. var newUVsData = (this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.UVKind) || []);
  401. var newColorsData = (this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.ColorKind) || []);
  402. var normalData = this._mesh.getVerticesData(BABYLON.VertexBuffer.NormalKind);
  403. var uvs = this._mesh.getVerticesData(BABYLON.VertexBuffer.UVKind);
  404. var colorsData = this._mesh.getVerticesData(BABYLON.VertexBuffer.ColorKind);
  405. var vertexCount = 0;
  406. for (i = 0; i < this.vertices.length; ++i) {
  407. var vertex = this.vertices[i];
  408. vertex.id = vertexCount;
  409. if (vertex.triangleCount) {
  410. vertex.originalOffsets.forEach(function (originalOffset) {
  411. if (!normalData) {
  412. return;
  413. }
  414. newPositionData.push(vertex.position.x);
  415. newPositionData.push(vertex.position.y);
  416. newPositionData.push(vertex.position.z);
  417. newNormalData.push(normalData[originalOffset * 3]);
  418. newNormalData.push(normalData[(originalOffset * 3) + 1]);
  419. newNormalData.push(normalData[(originalOffset * 3) + 2]);
  420. if (uvs && uvs.length) {
  421. newUVsData.push(uvs[(originalOffset * 2)]);
  422. newUVsData.push(uvs[(originalOffset * 2) + 1]);
  423. }
  424. else if (colorsData && colorsData.length) {
  425. newColorsData.push(colorsData[(originalOffset * 4)]);
  426. newColorsData.push(colorsData[(originalOffset * 4) + 1]);
  427. newColorsData.push(colorsData[(originalOffset * 4) + 2]);
  428. newColorsData.push(colorsData[(originalOffset * 4) + 3]);
  429. }
  430. ++vertexCount;
  431. });
  432. }
  433. }
  434. var startingIndex = this._reconstructedMesh.getTotalIndices();
  435. var startingVertex = this._reconstructedMesh.getTotalVertices();
  436. var submeshesArray = this._reconstructedMesh.subMeshes;
  437. this._reconstructedMesh.subMeshes = [];
  438. var newIndicesArray = this._reconstructedMesh.getIndices(); //[];
  439. var originalIndices = this._mesh.getIndices();
  440. for (i = 0; i < newTriangles.length; ++i) {
  441. t = newTriangles[i]; //now get the new referencing point for each vertex
  442. [0, 1, 2].forEach(function (idx) {
  443. var id = originalIndices[t.originalOffset + idx];
  444. var offset = t.vertices[idx].originalOffsets.indexOf(id);
  445. if (offset < 0)
  446. offset = 0;
  447. newIndicesArray.push(t.vertices[idx].id + offset + startingVertex);
  448. });
  449. }
  450. //overwriting the old vertex buffers and indices.
  451. this._reconstructedMesh.setIndices(newIndicesArray);
  452. this._reconstructedMesh.setVerticesData(BABYLON.VertexBuffer.PositionKind, newPositionData);
  453. this._reconstructedMesh.setVerticesData(BABYLON.VertexBuffer.NormalKind, newNormalData);
  454. if (newUVsData.length > 0)
  455. this._reconstructedMesh.setVerticesData(BABYLON.VertexBuffer.UVKind, newUVsData);
  456. if (newColorsData.length > 0)
  457. this._reconstructedMesh.setVerticesData(BABYLON.VertexBuffer.ColorKind, newColorsData);
  458. //create submesh
  459. var originalSubmesh = this._mesh.subMeshes[submeshIndex];
  460. if (submeshIndex > 0) {
  461. this._reconstructedMesh.subMeshes = [];
  462. submeshesArray.forEach(function (submesh) {
  463. BABYLON.SubMesh.AddToMesh(submesh.materialIndex, submesh.verticesStart, submesh.verticesCount, /* 0, newPositionData.length/3, */ submesh.indexStart, submesh.indexCount, submesh.getMesh());
  464. });
  465. BABYLON.SubMesh.AddToMesh(originalSubmesh.materialIndex, startingVertex, vertexCount, /* 0, newPositionData.length / 3, */ startingIndex, newTriangles.length * 3, this._reconstructedMesh);
  466. }
  467. };
  468. QuadraticErrorSimplification.prototype.initDecimatedMesh = function () {
  469. this._reconstructedMesh = new BABYLON.Mesh(this._mesh.name + "Decimated", this._mesh.getScene());
  470. this._reconstructedMesh.material = this._mesh.material;
  471. this._reconstructedMesh.parent = this._mesh.parent;
  472. this._reconstructedMesh.isVisible = false;
  473. this._reconstructedMesh.renderingGroupId = this._mesh.renderingGroupId;
  474. };
  475. QuadraticErrorSimplification.prototype.isFlipped = function (vertex1, vertex2, point, deletedArray, borderFactor, delTr) {
  476. for (var i = 0; i < vertex1.triangleCount; ++i) {
  477. var t = this.triangles[this.references[vertex1.triangleStart + i].triangleId];
  478. if (t.deleted)
  479. continue;
  480. var s = this.references[vertex1.triangleStart + i].vertexId;
  481. var v1 = t.vertices[(s + 1) % 3];
  482. var v2 = t.vertices[(s + 2) % 3];
  483. if ((v1 === vertex2 || v2 === vertex2)) {
  484. deletedArray[i] = true;
  485. delTr.push(t);
  486. continue;
  487. }
  488. var d1 = v1.position.subtract(point);
  489. d1 = d1.normalize();
  490. var d2 = v2.position.subtract(point);
  491. d2 = d2.normalize();
  492. if (Math.abs(BABYLON.Vector3.Dot(d1, d2)) > 0.999)
  493. return true;
  494. var normal = BABYLON.Vector3.Cross(d1, d2).normalize();
  495. deletedArray[i] = false;
  496. if (BABYLON.Vector3.Dot(normal, t.normal) < 0.2)
  497. return true;
  498. }
  499. return false;
  500. };
  501. QuadraticErrorSimplification.prototype.updateTriangles = function (origVertex, vertex, deletedArray, deletedTriangles) {
  502. var newDeleted = deletedTriangles;
  503. for (var i = 0; i < vertex.triangleCount; ++i) {
  504. var ref = this.references[vertex.triangleStart + i];
  505. var t = this.triangles[ref.triangleId];
  506. if (t.deleted)
  507. continue;
  508. if (deletedArray[i] && t.deletePending) {
  509. t.deleted = true;
  510. newDeleted++;
  511. continue;
  512. }
  513. t.vertices[ref.vertexId] = origVertex;
  514. t.isDirty = true;
  515. t.error[0] = this.calculateError(t.vertices[0], t.vertices[1]) + (t.borderFactor / 2);
  516. t.error[1] = this.calculateError(t.vertices[1], t.vertices[2]) + (t.borderFactor / 2);
  517. t.error[2] = this.calculateError(t.vertices[2], t.vertices[0]) + (t.borderFactor / 2);
  518. t.error[3] = Math.min(t.error[0], t.error[1], t.error[2]);
  519. this.references.push(ref);
  520. }
  521. return newDeleted;
  522. };
  523. QuadraticErrorSimplification.prototype.identifyBorder = function () {
  524. for (var i = 0; i < this.vertices.length; ++i) {
  525. var vCount = [];
  526. var vId = [];
  527. var v = this.vertices[i];
  528. var j;
  529. for (j = 0; j < v.triangleCount; ++j) {
  530. var triangle = this.triangles[this.references[v.triangleStart + j].triangleId];
  531. for (var ii = 0; ii < 3; ii++) {
  532. var ofs = 0;
  533. var vv = triangle.vertices[ii];
  534. while (ofs < vCount.length) {
  535. if (vId[ofs] === vv.id)
  536. break;
  537. ++ofs;
  538. }
  539. if (ofs === vCount.length) {
  540. vCount.push(1);
  541. vId.push(vv.id);
  542. }
  543. else {
  544. vCount[ofs]++;
  545. }
  546. }
  547. }
  548. for (j = 0; j < vCount.length; ++j) {
  549. if (vCount[j] === 1) {
  550. this.vertices[vId[j]].isBorder = true;
  551. }
  552. else {
  553. this.vertices[vId[j]].isBorder = false;
  554. }
  555. }
  556. }
  557. };
  558. QuadraticErrorSimplification.prototype.updateMesh = function (identifyBorders) {
  559. if (identifyBorders === void 0) { identifyBorders = false; }
  560. var i;
  561. if (!identifyBorders) {
  562. var newTrianglesVector = [];
  563. for (i = 0; i < this.triangles.length; ++i) {
  564. if (!this.triangles[i].deleted) {
  565. newTrianglesVector.push(this.triangles[i]);
  566. }
  567. }
  568. this.triangles = newTrianglesVector;
  569. }
  570. for (i = 0; i < this.vertices.length; ++i) {
  571. this.vertices[i].triangleCount = 0;
  572. this.vertices[i].triangleStart = 0;
  573. }
  574. var t;
  575. var j;
  576. var v;
  577. for (i = 0; i < this.triangles.length; ++i) {
  578. t = this.triangles[i];
  579. for (j = 0; j < 3; ++j) {
  580. v = t.vertices[j];
  581. v.triangleCount++;
  582. }
  583. }
  584. var tStart = 0;
  585. for (i = 0; i < this.vertices.length; ++i) {
  586. this.vertices[i].triangleStart = tStart;
  587. tStart += this.vertices[i].triangleCount;
  588. this.vertices[i].triangleCount = 0;
  589. }
  590. var newReferences = new Array(this.triangles.length * 3);
  591. for (i = 0; i < this.triangles.length; ++i) {
  592. t = this.triangles[i];
  593. for (j = 0; j < 3; ++j) {
  594. v = t.vertices[j];
  595. newReferences[v.triangleStart + v.triangleCount] = new Reference(j, i);
  596. v.triangleCount++;
  597. }
  598. }
  599. this.references = newReferences;
  600. if (identifyBorders) {
  601. this.identifyBorder();
  602. }
  603. };
  604. QuadraticErrorSimplification.prototype.vertexError = function (q, point) {
  605. var x = point.x;
  606. var y = point.y;
  607. var z = point.z;
  608. 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
  609. + 2 * q.data[5] * y * z + 2 * q.data[6] * y + q.data[7] * z * z + 2 * q.data[8] * z + q.data[9];
  610. };
  611. QuadraticErrorSimplification.prototype.calculateError = function (vertex1, vertex2, pointResult, normalResult, uvResult, colorResult) {
  612. var q = vertex1.q.add(vertex2.q);
  613. var border = vertex1.isBorder && vertex2.isBorder;
  614. var error = 0;
  615. var qDet = q.det(0, 1, 2, 1, 4, 5, 2, 5, 7);
  616. if (qDet !== 0 && !border) {
  617. if (!pointResult) {
  618. pointResult = BABYLON.Vector3.Zero();
  619. }
  620. pointResult.x = -1 / qDet * (q.det(1, 2, 3, 4, 5, 6, 5, 7, 8));
  621. pointResult.y = 1 / qDet * (q.det(0, 2, 3, 1, 5, 6, 2, 7, 8));
  622. pointResult.z = -1 / qDet * (q.det(0, 1, 3, 1, 4, 6, 2, 5, 8));
  623. error = this.vertexError(q, pointResult);
  624. }
  625. else {
  626. var p3 = (vertex1.position.add(vertex2.position)).divide(new BABYLON.Vector3(2, 2, 2));
  627. //var norm3 = (vertex1.normal.add(vertex2.normal)).divide(new Vector3(2, 2, 2)).normalize();
  628. var error1 = this.vertexError(q, vertex1.position);
  629. var error2 = this.vertexError(q, vertex2.position);
  630. var error3 = this.vertexError(q, p3);
  631. error = Math.min(error1, error2, error3);
  632. if (error === error1) {
  633. if (pointResult) {
  634. pointResult.copyFrom(vertex1.position);
  635. }
  636. }
  637. else if (error === error2) {
  638. if (pointResult) {
  639. pointResult.copyFrom(vertex2.position);
  640. }
  641. }
  642. else {
  643. if (pointResult) {
  644. pointResult.copyFrom(p3);
  645. }
  646. }
  647. }
  648. return error;
  649. };
  650. return QuadraticErrorSimplification;
  651. }());
  652. BABYLON.QuadraticErrorSimplification = QuadraticErrorSimplification;
  653. })(BABYLON || (BABYLON = {}));
  654. //# sourceMappingURL=babylon.meshSimplification.js.map
  655. var BABYLON;
  656. (function (BABYLON) {
  657. var MeshLODLevel = /** @class */ (function () {
  658. function MeshLODLevel(distance, mesh) {
  659. this.distance = distance;
  660. this.mesh = mesh;
  661. }
  662. return MeshLODLevel;
  663. }());
  664. BABYLON.MeshLODLevel = MeshLODLevel;
  665. })(BABYLON || (BABYLON = {}));
  666. //# sourceMappingURL=babylon.meshLODLevel.js.map
  667. 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}";
  668. 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}";
  669. var BABYLON;
  670. (function (BABYLON) {
  671. // Standard optimizations
  672. var SceneOptimization = /** @class */ (function () {
  673. function SceneOptimization(priority) {
  674. if (priority === void 0) { priority = 0; }
  675. this.priority = priority;
  676. this.apply = function (scene) {
  677. return true; // Return true if everything that can be done was applied
  678. };
  679. }
  680. return SceneOptimization;
  681. }());
  682. BABYLON.SceneOptimization = SceneOptimization;
  683. var TextureOptimization = /** @class */ (function (_super) {
  684. __extends(TextureOptimization, _super);
  685. function TextureOptimization(priority, maximumSize) {
  686. if (priority === void 0) { priority = 0; }
  687. if (maximumSize === void 0) { maximumSize = 1024; }
  688. var _this = _super.call(this, priority) || this;
  689. _this.priority = priority;
  690. _this.maximumSize = maximumSize;
  691. _this.apply = function (scene) {
  692. var allDone = true;
  693. for (var index = 0; index < scene.textures.length; index++) {
  694. var texture = scene.textures[index];
  695. if (!texture.canRescale || texture.getContext) {
  696. continue;
  697. }
  698. var currentSize = texture.getSize();
  699. var maxDimension = Math.max(currentSize.width, currentSize.height);
  700. if (maxDimension > _this.maximumSize) {
  701. texture.scale(0.5);
  702. allDone = false;
  703. }
  704. }
  705. return allDone;
  706. };
  707. return _this;
  708. }
  709. return TextureOptimization;
  710. }(SceneOptimization));
  711. BABYLON.TextureOptimization = TextureOptimization;
  712. var HardwareScalingOptimization = /** @class */ (function (_super) {
  713. __extends(HardwareScalingOptimization, _super);
  714. function HardwareScalingOptimization(priority, maximumScale) {
  715. if (priority === void 0) { priority = 0; }
  716. if (maximumScale === void 0) { maximumScale = 2; }
  717. var _this = _super.call(this, priority) || this;
  718. _this.priority = priority;
  719. _this.maximumScale = maximumScale;
  720. _this._currentScale = 1;
  721. _this.apply = function (scene) {
  722. _this._currentScale++;
  723. scene.getEngine().setHardwareScalingLevel(_this._currentScale);
  724. return _this._currentScale >= _this.maximumScale;
  725. };
  726. return _this;
  727. }
  728. return HardwareScalingOptimization;
  729. }(SceneOptimization));
  730. BABYLON.HardwareScalingOptimization = HardwareScalingOptimization;
  731. var ShadowsOptimization = /** @class */ (function (_super) {
  732. __extends(ShadowsOptimization, _super);
  733. function ShadowsOptimization() {
  734. var _this = _super !== null && _super.apply(this, arguments) || this;
  735. _this.apply = function (scene) {
  736. scene.shadowsEnabled = false;
  737. return true;
  738. };
  739. return _this;
  740. }
  741. return ShadowsOptimization;
  742. }(SceneOptimization));
  743. BABYLON.ShadowsOptimization = ShadowsOptimization;
  744. var PostProcessesOptimization = /** @class */ (function (_super) {
  745. __extends(PostProcessesOptimization, _super);
  746. function PostProcessesOptimization() {
  747. var _this = _super !== null && _super.apply(this, arguments) || this;
  748. _this.apply = function (scene) {
  749. scene.postProcessesEnabled = false;
  750. return true;
  751. };
  752. return _this;
  753. }
  754. return PostProcessesOptimization;
  755. }(SceneOptimization));
  756. BABYLON.PostProcessesOptimization = PostProcessesOptimization;
  757. var LensFlaresOptimization = /** @class */ (function (_super) {
  758. __extends(LensFlaresOptimization, _super);
  759. function LensFlaresOptimization() {
  760. var _this = _super !== null && _super.apply(this, arguments) || this;
  761. _this.apply = function (scene) {
  762. scene.lensFlaresEnabled = false;
  763. return true;
  764. };
  765. return _this;
  766. }
  767. return LensFlaresOptimization;
  768. }(SceneOptimization));
  769. BABYLON.LensFlaresOptimization = LensFlaresOptimization;
  770. var ParticlesOptimization = /** @class */ (function (_super) {
  771. __extends(ParticlesOptimization, _super);
  772. function ParticlesOptimization() {
  773. var _this = _super !== null && _super.apply(this, arguments) || this;
  774. _this.apply = function (scene) {
  775. scene.particlesEnabled = false;
  776. return true;
  777. };
  778. return _this;
  779. }
  780. return ParticlesOptimization;
  781. }(SceneOptimization));
  782. BABYLON.ParticlesOptimization = ParticlesOptimization;
  783. var RenderTargetsOptimization = /** @class */ (function (_super) {
  784. __extends(RenderTargetsOptimization, _super);
  785. function RenderTargetsOptimization() {
  786. var _this = _super !== null && _super.apply(this, arguments) || this;
  787. _this.apply = function (scene) {
  788. scene.renderTargetsEnabled = false;
  789. return true;
  790. };
  791. return _this;
  792. }
  793. return RenderTargetsOptimization;
  794. }(SceneOptimization));
  795. BABYLON.RenderTargetsOptimization = RenderTargetsOptimization;
  796. var MergeMeshesOptimization = /** @class */ (function (_super) {
  797. __extends(MergeMeshesOptimization, _super);
  798. function MergeMeshesOptimization() {
  799. var _this = _super !== null && _super.apply(this, arguments) || this;
  800. _this._canBeMerged = function (abstractMesh) {
  801. if (!(abstractMesh instanceof BABYLON.Mesh)) {
  802. return false;
  803. }
  804. var mesh = abstractMesh;
  805. if (!mesh.isVisible || !mesh.isEnabled()) {
  806. return false;
  807. }
  808. if (mesh.instances.length > 0) {
  809. return false;
  810. }
  811. if (mesh.skeleton || mesh.hasLODLevels) {
  812. return false;
  813. }
  814. if (mesh.parent) {
  815. return false;
  816. }
  817. return true;
  818. };
  819. _this.apply = function (scene, updateSelectionTree) {
  820. var globalPool = scene.meshes.slice(0);
  821. var globalLength = globalPool.length;
  822. for (var index = 0; index < globalLength; index++) {
  823. var currentPool = new Array();
  824. var current = globalPool[index];
  825. // Checks
  826. if (!_this._canBeMerged(current)) {
  827. continue;
  828. }
  829. currentPool.push(current);
  830. // Find compatible meshes
  831. for (var subIndex = index + 1; subIndex < globalLength; subIndex++) {
  832. var otherMesh = globalPool[subIndex];
  833. if (!_this._canBeMerged(otherMesh)) {
  834. continue;
  835. }
  836. if (otherMesh.material !== current.material) {
  837. continue;
  838. }
  839. if (otherMesh.checkCollisions !== current.checkCollisions) {
  840. continue;
  841. }
  842. currentPool.push(otherMesh);
  843. globalLength--;
  844. globalPool.splice(subIndex, 1);
  845. subIndex--;
  846. }
  847. if (currentPool.length < 2) {
  848. continue;
  849. }
  850. // Merge meshes
  851. BABYLON.Mesh.MergeMeshes(currentPool);
  852. }
  853. if (updateSelectionTree != undefined) {
  854. if (updateSelectionTree) {
  855. scene.createOrUpdateSelectionOctree();
  856. }
  857. }
  858. else if (MergeMeshesOptimization.UpdateSelectionTree) {
  859. scene.createOrUpdateSelectionOctree();
  860. }
  861. return true;
  862. };
  863. return _this;
  864. }
  865. Object.defineProperty(MergeMeshesOptimization, "UpdateSelectionTree", {
  866. get: function () {
  867. return MergeMeshesOptimization._UpdateSelectionTree;
  868. },
  869. set: function (value) {
  870. MergeMeshesOptimization._UpdateSelectionTree = value;
  871. },
  872. enumerable: true,
  873. configurable: true
  874. });
  875. MergeMeshesOptimization._UpdateSelectionTree = false;
  876. return MergeMeshesOptimization;
  877. }(SceneOptimization));
  878. BABYLON.MergeMeshesOptimization = MergeMeshesOptimization;
  879. // Options
  880. var SceneOptimizerOptions = /** @class */ (function () {
  881. function SceneOptimizerOptions(targetFrameRate, trackerDuration) {
  882. if (targetFrameRate === void 0) { targetFrameRate = 60; }
  883. if (trackerDuration === void 0) { trackerDuration = 2000; }
  884. this.targetFrameRate = targetFrameRate;
  885. this.trackerDuration = trackerDuration;
  886. this.optimizations = new Array();
  887. }
  888. SceneOptimizerOptions.LowDegradationAllowed = function (targetFrameRate) {
  889. var result = new SceneOptimizerOptions(targetFrameRate);
  890. var priority = 0;
  891. result.optimizations.push(new MergeMeshesOptimization(priority));
  892. result.optimizations.push(new ShadowsOptimization(priority));
  893. result.optimizations.push(new LensFlaresOptimization(priority));
  894. // Next priority
  895. priority++;
  896. result.optimizations.push(new PostProcessesOptimization(priority));
  897. result.optimizations.push(new ParticlesOptimization(priority));
  898. // Next priority
  899. priority++;
  900. result.optimizations.push(new TextureOptimization(priority, 1024));
  901. return result;
  902. };
  903. SceneOptimizerOptions.ModerateDegradationAllowed = function (targetFrameRate) {
  904. var result = new SceneOptimizerOptions(targetFrameRate);
  905. var priority = 0;
  906. result.optimizations.push(new MergeMeshesOptimization(priority));
  907. result.optimizations.push(new ShadowsOptimization(priority));
  908. result.optimizations.push(new LensFlaresOptimization(priority));
  909. // Next priority
  910. priority++;
  911. result.optimizations.push(new PostProcessesOptimization(priority));
  912. result.optimizations.push(new ParticlesOptimization(priority));
  913. // Next priority
  914. priority++;
  915. result.optimizations.push(new TextureOptimization(priority, 512));
  916. // Next priority
  917. priority++;
  918. result.optimizations.push(new RenderTargetsOptimization(priority));
  919. // Next priority
  920. priority++;
  921. result.optimizations.push(new HardwareScalingOptimization(priority, 2));
  922. return result;
  923. };
  924. SceneOptimizerOptions.HighDegradationAllowed = function (targetFrameRate) {
  925. var result = new SceneOptimizerOptions(targetFrameRate);
  926. var priority = 0;
  927. result.optimizations.push(new MergeMeshesOptimization(priority));
  928. result.optimizations.push(new ShadowsOptimization(priority));
  929. result.optimizations.push(new LensFlaresOptimization(priority));
  930. // Next priority
  931. priority++;
  932. result.optimizations.push(new PostProcessesOptimization(priority));
  933. result.optimizations.push(new ParticlesOptimization(priority));
  934. // Next priority
  935. priority++;
  936. result.optimizations.push(new TextureOptimization(priority, 256));
  937. // Next priority
  938. priority++;
  939. result.optimizations.push(new RenderTargetsOptimization(priority));
  940. // Next priority
  941. priority++;
  942. result.optimizations.push(new HardwareScalingOptimization(priority, 4));
  943. return result;
  944. };
  945. return SceneOptimizerOptions;
  946. }());
  947. BABYLON.SceneOptimizerOptions = SceneOptimizerOptions;
  948. // Scene optimizer tool
  949. var SceneOptimizer = /** @class */ (function () {
  950. function SceneOptimizer() {
  951. }
  952. SceneOptimizer._CheckCurrentState = function (scene, options, currentPriorityLevel, onSuccess, onFailure) {
  953. // TODO: add an epsilon
  954. if (scene.getEngine().getFps() >= options.targetFrameRate) {
  955. if (onSuccess) {
  956. onSuccess();
  957. }
  958. return;
  959. }
  960. // Apply current level of optimizations
  961. var allDone = true;
  962. var noOptimizationApplied = true;
  963. for (var index = 0; index < options.optimizations.length; index++) {
  964. var optimization = options.optimizations[index];
  965. if (optimization.priority === currentPriorityLevel) {
  966. noOptimizationApplied = false;
  967. allDone = allDone && optimization.apply(scene);
  968. }
  969. }
  970. // If no optimization was applied, this is a failure :(
  971. if (noOptimizationApplied) {
  972. if (onFailure) {
  973. onFailure();
  974. }
  975. return;
  976. }
  977. // If all optimizations were done, move to next level
  978. if (allDone) {
  979. currentPriorityLevel++;
  980. }
  981. // Let's the system running for a specific amount of time before checking FPS
  982. scene.executeWhenReady(function () {
  983. setTimeout(function () {
  984. SceneOptimizer._CheckCurrentState(scene, options, currentPriorityLevel, onSuccess, onFailure);
  985. }, options.trackerDuration);
  986. });
  987. };
  988. SceneOptimizer.OptimizeAsync = function (scene, options, onSuccess, onFailure) {
  989. if (!options) {
  990. options = SceneOptimizerOptions.ModerateDegradationAllowed();
  991. }
  992. // Let's the system running for a specific amount of time before checking FPS
  993. scene.executeWhenReady(function () {
  994. setTimeout(function () {
  995. SceneOptimizer._CheckCurrentState(scene, options, 0, onSuccess, onFailure);
  996. }, options.trackerDuration);
  997. });
  998. };
  999. return SceneOptimizer;
  1000. }());
  1001. BABYLON.SceneOptimizer = SceneOptimizer;
  1002. })(BABYLON || (BABYLON = {}));
  1003. //# sourceMappingURL=babylon.sceneOptimizer.js.map
  1004. BABYLON.Effect.IncludesShadersStore['depthPrePass'] = "#ifdef DEPTHPREPASS\ngl_FragColor=vec4(0.,0.,0.,1.0);\nreturn;\n#endif";
  1005. 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";
  1006. 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";
  1007. BABYLON.Effect.IncludesShadersStore['pointCloudVertexDeclaration'] = "#ifdef POINTSIZE\nuniform float pointSize;\n#endif";
  1008. BABYLON.Effect.IncludesShadersStore['bumpVertexDeclaration'] = "#if defined(BUMP) || defined(PARALLAX)\n#if defined(TANGENT) && defined(NORMAL) \nvarying mat3 vTBN;\n#endif\n#endif\n";
  1009. BABYLON.Effect.IncludesShadersStore['clipPlaneVertexDeclaration'] = "#ifdef CLIPPLANE\nuniform vec4 vClipPlane;\nvarying float fClipDistance;\n#endif";
  1010. BABYLON.Effect.IncludesShadersStore['fogVertexDeclaration'] = "#ifdef FOG\nvarying vec3 vFogDistance;\n#endif";
  1011. BABYLON.Effect.IncludesShadersStore['morphTargetsVertexGlobalDeclaration'] = "#ifdef MORPHTARGETS\nuniform float morphTargetInfluences[NUM_MORPH_INFLUENCERS];\n#endif";
  1012. 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";
  1013. BABYLON.Effect.IncludesShadersStore['logDepthDeclaration'] = "#ifdef LOGARITHMICDEPTH\nuniform float logarithmicDepthConstant;\nvarying float vFragmentDepth;\n#endif";
  1014. 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";
  1015. BABYLON.Effect.IncludesShadersStore['instancesVertex'] = "#ifdef INSTANCES\nmat4 finalWorld=mat4(world0,world1,world2,world3);\n#else\nmat4 finalWorld=world;\n#endif";
  1016. 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";
  1017. 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";
  1018. BABYLON.Effect.IncludesShadersStore['clipPlaneVertex'] = "#ifdef CLIPPLANE\nfClipDistance=dot(worldPos,vClipPlane);\n#endif";
  1019. BABYLON.Effect.IncludesShadersStore['fogVertex'] = "#ifdef FOG\nvFogDistance=(view*worldPos).xyz;\n#endif";
  1020. 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";
  1021. BABYLON.Effect.IncludesShadersStore['pointCloudVertex'] = "#ifdef POINTSIZE\ngl_PointSize=pointSize;\n#endif";
  1022. BABYLON.Effect.IncludesShadersStore['logDepthVertex'] = "#ifdef LOGARITHMICDEPTH\nvFragmentDepth=1.0+gl_Position.w;\ngl_Position.z=log2(max(0.000001,vFragmentDepth))*logarithmicDepthConstant;\n#endif";
  1023. 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}";
  1024. 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";
  1025. 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";
  1026. 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";
  1027. 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";
  1028. 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";
  1029. 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};";
  1030. 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";
  1031. 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";
  1032. 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}";
  1033. 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";
  1034. 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}";
  1035. 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";
  1036. BABYLON.Effect.IncludesShadersStore['clipPlaneFragmentDeclaration'] = "#ifdef CLIPPLANE\nvarying float fClipDistance;\n#endif";
  1037. 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";
  1038. BABYLON.Effect.IncludesShadersStore['clipPlaneFragment'] = "#ifdef CLIPPLANE\nif (fClipDistance>0.0)\n{\ndiscard;\n}\n#endif";
  1039. 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";
  1040. 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";
  1041. BABYLON.Effect.IncludesShadersStore['logDepthFragment'] = "#ifdef LOGARITHMICDEPTH\ngl_FragDepthEXT=log2(vFragmentDepth)*logarithmicDepthConstant*0.5;\n#endif";
  1042. BABYLON.Effect.IncludesShadersStore['fogFragment'] = "#ifdef FOG\nfloat fog=CalcFogFactor();\ncolor.rgb=fog*color.rgb+(1.0-fog)*vFogColor;\n#endif";
  1043. var SimplificationSettings = BABYLON.SimplificationSettings;
  1044. var SimplificationQueue = BABYLON.SimplificationQueue;
  1045. var SimplificationType = BABYLON.SimplificationType;
  1046. var DecimationTriangle = BABYLON.DecimationTriangle;
  1047. var DecimationVertex = BABYLON.DecimationVertex;
  1048. var QuadraticMatrix = BABYLON.QuadraticMatrix;
  1049. var Reference = BABYLON.Reference;
  1050. var QuadraticErrorSimplification = BABYLON.QuadraticErrorSimplification;
  1051. var MeshLODLevel = BABYLON.MeshLODLevel;
  1052. var SceneOptimization = BABYLON.SceneOptimization;
  1053. var TextureOptimization = BABYLON.TextureOptimization;
  1054. var HardwareScalingOptimization = BABYLON.HardwareScalingOptimization;
  1055. var ShadowsOptimization = BABYLON.ShadowsOptimization;
  1056. var PostProcessesOptimization = BABYLON.PostProcessesOptimization;
  1057. var LensFlaresOptimization = BABYLON.LensFlaresOptimization;
  1058. var ParticlesOptimization = BABYLON.ParticlesOptimization;
  1059. var RenderTargetsOptimization = BABYLON.RenderTargetsOptimization;
  1060. var MergeMeshesOptimization = BABYLON.MergeMeshesOptimization;
  1061. var SceneOptimizerOptions = BABYLON.SceneOptimizerOptions;
  1062. var SceneOptimizer = BABYLON.SceneOptimizer;
  1063. export { SimplificationSettings,SimplificationQueue,SimplificationType,DecimationTriangle,DecimationVertex,QuadraticMatrix,Reference,QuadraticErrorSimplification,MeshLODLevel,SceneOptimization,TextureOptimization,HardwareScalingOptimization,ShadowsOptimization,PostProcessesOptimization,LensFlaresOptimization,ParticlesOptimization,RenderTargetsOptimization,MergeMeshesOptimization,SceneOptimizerOptions,SceneOptimizer };