index.js 113 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257
  1. if(typeof require !== 'undefined'){
  2. var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : this);
  3. var BABYLON = globalObject["BABYLON"] || {};
  4. var BABYLON0 = require('babylonjs/core');
  5. if(BABYLON !== BABYLON0) __extends(BABYLON, BABYLON0);
  6. var BABYLON;
  7. (function (BABYLON) {
  8. var SolidParticle = /** @class */ (function () {
  9. /**
  10. * Creates a Solid Particle object.
  11. * Don't create particles manually, use instead the Solid Particle System internal tools like _addParticle()
  12. * `particleIndex` (integer) is the particle index in the Solid Particle System pool. It's also the particle identifier.
  13. * `positionIndex` (integer) is the starting index of the particle vertices in the SPS "positions" array.
  14. * `indiceIndex` (integer) is the starting index of the particle indices in the SPS "indices" array.
  15. * `model` (ModelShape) is a reference to the model shape on what the particle is designed.
  16. * `shapeId` (integer) is the model shape identifier in the SPS.
  17. * `idxInShape` (integer) is the index of the particle in the current model (ex: the 10th box of addShape(box, 30))
  18. * `modelBoundingInfo` is the reference to the model BoundingInfo used for intersection computations.
  19. */
  20. function SolidParticle(particleIndex, positionIndex, indiceIndex, model, shapeId, idxInShape, sps, modelBoundingInfo) {
  21. if (modelBoundingInfo === void 0) { modelBoundingInfo = null; }
  22. this.idx = 0; // particle global index
  23. this.color = new BABYLON.Color4(1.0, 1.0, 1.0, 1.0); // color
  24. this.position = BABYLON.Vector3.Zero(); // position
  25. this.rotation = BABYLON.Vector3.Zero(); // rotation
  26. this.scaling = BABYLON.Vector3.One(); // scaling
  27. this.uvs = new BABYLON.Vector4(0.0, 0.0, 1.0, 1.0); // uvs
  28. this.velocity = BABYLON.Vector3.Zero(); // velocity
  29. this.pivot = BABYLON.Vector3.Zero(); // pivot point in the particle local space
  30. this.alive = true; // alive
  31. this.isVisible = true; // visibility
  32. this._pos = 0; // index of this particle in the global "positions" array
  33. this._ind = 0; // index of this particle in the global "indices" array
  34. this.shapeId = 0; // model shape id
  35. this.idxInShape = 0; // index of the particle in its shape id
  36. this._stillInvisible = false; // still set as invisible in order to skip useless computations
  37. this.idx = particleIndex;
  38. this._pos = positionIndex;
  39. this._ind = indiceIndex;
  40. this._model = model;
  41. this.shapeId = shapeId;
  42. this.idxInShape = idxInShape;
  43. this._sps = sps;
  44. if (modelBoundingInfo) {
  45. this._modelBoundingInfo = modelBoundingInfo;
  46. this._boundingInfo = new BABYLON.BoundingInfo(modelBoundingInfo.minimum, modelBoundingInfo.maximum);
  47. }
  48. }
  49. Object.defineProperty(SolidParticle.prototype, "scale", {
  50. /**
  51. * legacy support, changed scale to scaling
  52. */
  53. get: function () {
  54. return this.scaling;
  55. },
  56. set: function (scale) {
  57. this.scaling = scale;
  58. },
  59. enumerable: true,
  60. configurable: true
  61. });
  62. Object.defineProperty(SolidParticle.prototype, "quaternion", {
  63. /**
  64. * legacy support, changed quaternion to rotationQuaternion
  65. */
  66. get: function () {
  67. return this.rotationQuaternion;
  68. },
  69. set: function (q) {
  70. this.rotationQuaternion = q;
  71. },
  72. enumerable: true,
  73. configurable: true
  74. });
  75. /**
  76. * Returns a boolean. True if the particle intersects another particle or another mesh, else false.
  77. * The intersection is computed on the particle bounding sphere and Axis Aligned Bounding Box (AABB)
  78. * `target` is the object (solid particle or mesh) what the intersection is computed against.
  79. */
  80. SolidParticle.prototype.intersectsMesh = function (target) {
  81. if (!this._boundingInfo || !target._boundingInfo) {
  82. return false;
  83. }
  84. if (this._sps._bSphereOnly) {
  85. return BABYLON.BoundingSphere.Intersects(this._boundingInfo.boundingSphere, target._boundingInfo.boundingSphere);
  86. }
  87. return this._boundingInfo.intersects(target._boundingInfo, false);
  88. };
  89. return SolidParticle;
  90. }());
  91. BABYLON.SolidParticle = SolidParticle;
  92. var ModelShape = /** @class */ (function () {
  93. /**
  94. * Creates a ModelShape object. This is an internal simplified reference to a mesh used as for a model to replicate particles from by the SPS.
  95. * SPS internal tool, don't use it manually.
  96. */
  97. function ModelShape(id, shape, indicesLength, shapeUV, posFunction, vtxFunction) {
  98. this._indicesLength = 0; // length of the shape in the model indices array
  99. this.shapeID = id;
  100. this._shape = shape;
  101. this._indicesLength = indicesLength;
  102. this._shapeUV = shapeUV;
  103. this._positionFunction = posFunction;
  104. this._vertexFunction = vtxFunction;
  105. }
  106. return ModelShape;
  107. }());
  108. BABYLON.ModelShape = ModelShape;
  109. var DepthSortedParticle = /** @class */ (function () {
  110. function DepthSortedParticle() {
  111. this.ind = 0; // index of the particle in the "indices" array
  112. this.indicesLength = 0; // length of the particle shape in the "indices" array
  113. this.sqDistance = 0.0; // squared distance from the particle to the camera
  114. }
  115. return DepthSortedParticle;
  116. }());
  117. BABYLON.DepthSortedParticle = DepthSortedParticle;
  118. })(BABYLON || (BABYLON = {}));
  119. //# sourceMappingURL=babylon.solidParticle.js.map
  120. var BABYLON;
  121. (function (BABYLON) {
  122. /**
  123. * Full documentation here : http://doc.babylonjs.com/overviews/Solid_Particle_System
  124. */
  125. var SolidParticleSystem = /** @class */ (function () {
  126. /**
  127. * Creates a SPS (Solid Particle System) object.
  128. * `name` (String) is the SPS name, this will be the underlying mesh name.
  129. * `scene` (Scene) is the scene in which the SPS is added.
  130. * `updatable` (optional boolean, default true) : if the SPS must be updatable or immutable.
  131. * `isPickable` (optional boolean, default false) : if the solid particles must be pickable.
  132. * `enableDepthSort` (optional boolean, default false) : if the solid particles must be sorted in the geometry according to their distance to the camera.
  133. * `particleIntersection` (optional boolean, default false) : if the solid particle intersections must be computed.
  134. * `boundingSphereOnly` (optional boolean, default false) : if the particle intersection must be computed only with the bounding sphere (no bounding box computation, so faster).
  135. * `bSphereRadiusFactor` (optional float, default 1.0) : a number to multiply the boundind sphere radius by in order to reduce it for instance.
  136. * Example : bSphereRadiusFactor = 1.0 / Math.sqrt(3.0) => the bounding sphere exactly matches a spherical mesh.
  137. */
  138. function SolidParticleSystem(name, scene, options) {
  139. // public members
  140. /**
  141. * The SPS array of Solid Particle objects. Just access each particle as with any classic array.
  142. * Example : var p = SPS.particles[i];
  143. */
  144. this.particles = new Array();
  145. /**
  146. * The SPS total number of particles. Read only. Use SPS.counter instead if you need to set your own value.
  147. */
  148. this.nbParticles = 0;
  149. /**
  150. * If the particles must ever face the camera (default false). Useful for planar particles.
  151. */
  152. this.billboard = false;
  153. /**
  154. * Recompute normals when adding a shape
  155. */
  156. this.recomputeNormals = true;
  157. /**
  158. * This a counter ofr your own usage. It's not set by any SPS functions.
  159. */
  160. this.counter = 0;
  161. /**
  162. * This empty object is intended to store some SPS specific or temporary values in order to lower the Garbage Collector activity.
  163. * Please read : http://doc.babylonjs.com/overviews/Solid_Particle_System#garbage-collector-concerns
  164. */
  165. this.vars = {};
  166. this._positions = new Array();
  167. this._indices = new Array();
  168. this._normals = new Array();
  169. this._colors = new Array();
  170. this._uvs = new Array();
  171. this._index = 0; // indices index
  172. this._updatable = true;
  173. this._pickable = false;
  174. this._isVisibilityBoxLocked = false;
  175. this._alwaysVisible = false;
  176. this._depthSort = false;
  177. this._shapeCounter = 0;
  178. this._copy = new BABYLON.SolidParticle(0, 0, 0, null, 0, 0, this);
  179. this._color = new BABYLON.Color4(0, 0, 0, 0);
  180. this._computeParticleColor = true;
  181. this._computeParticleTexture = true;
  182. this._computeParticleRotation = true;
  183. this._computeParticleVertex = false;
  184. this._computeBoundingBox = false;
  185. this._depthSortParticles = true;
  186. this._cam_axisZ = BABYLON.Vector3.Zero();
  187. this._cam_axisY = BABYLON.Vector3.Zero();
  188. this._cam_axisX = BABYLON.Vector3.Zero();
  189. this._axisZ = BABYLON.Axis.Z;
  190. this._camDir = BABYLON.Vector3.Zero();
  191. this._camInvertedPosition = BABYLON.Vector3.Zero();
  192. this._rotMatrix = new BABYLON.Matrix();
  193. this._invertMatrix = new BABYLON.Matrix();
  194. this._rotated = BABYLON.Vector3.Zero();
  195. this._quaternion = new BABYLON.Quaternion();
  196. this._vertex = BABYLON.Vector3.Zero();
  197. this._normal = BABYLON.Vector3.Zero();
  198. this._yaw = 0.0;
  199. this._pitch = 0.0;
  200. this._roll = 0.0;
  201. this._halfroll = 0.0;
  202. this._halfpitch = 0.0;
  203. this._halfyaw = 0.0;
  204. this._sinRoll = 0.0;
  205. this._cosRoll = 0.0;
  206. this._sinPitch = 0.0;
  207. this._cosPitch = 0.0;
  208. this._sinYaw = 0.0;
  209. this._cosYaw = 0.0;
  210. this._mustUnrotateFixedNormals = false;
  211. this._minimum = BABYLON.Tmp.Vector3[0];
  212. this._maximum = BABYLON.Tmp.Vector3[1];
  213. this._minBbox = BABYLON.Tmp.Vector3[4];
  214. this._maxBbox = BABYLON.Tmp.Vector3[5];
  215. this._particlesIntersect = false;
  216. this._depthSortFunction = function (p1, p2) {
  217. return (p2.sqDistance - p1.sqDistance);
  218. };
  219. this._needs32Bits = false;
  220. this._bSphereOnly = false;
  221. this._bSphereRadiusFactor = 1.0;
  222. this.name = name;
  223. this._scene = scene || BABYLON.Engine.LastCreatedScene;
  224. this._camera = scene.activeCamera;
  225. this._pickable = options ? options.isPickable : false;
  226. this._depthSort = options ? options.enableDepthSort : false;
  227. this._particlesIntersect = options ? options.particleIntersection : false;
  228. this._bSphereOnly = options ? options.boundingSphereOnly : false;
  229. this._bSphereRadiusFactor = (options && options.bSphereRadiusFactor) ? options.bSphereRadiusFactor : 1.0;
  230. if (options && options.updatable) {
  231. this._updatable = options.updatable;
  232. }
  233. else {
  234. this._updatable = true;
  235. }
  236. if (this._pickable) {
  237. this.pickedParticles = [];
  238. }
  239. if (this._depthSort) {
  240. this.depthSortedParticles = [];
  241. }
  242. }
  243. /**
  244. * Builds the SPS underlying mesh. Returns a standard Mesh.
  245. * If no model shape was added to the SPS, the returned mesh is just a single triangular plane.
  246. */
  247. SolidParticleSystem.prototype.buildMesh = function () {
  248. if (this.nbParticles === 0) {
  249. var triangle = BABYLON.MeshBuilder.CreateDisc("", { radius: 1, tessellation: 3 }, this._scene);
  250. this.addShape(triangle, 1);
  251. triangle.dispose();
  252. }
  253. this._indices32 = (this._needs32Bits) ? new Uint32Array(this._indices) : new Uint16Array(this._indices);
  254. this._positions32 = new Float32Array(this._positions);
  255. this._uvs32 = new Float32Array(this._uvs);
  256. this._colors32 = new Float32Array(this._colors);
  257. if (this.recomputeNormals) {
  258. BABYLON.VertexData.ComputeNormals(this._positions32, this._indices, this._normals);
  259. }
  260. this._normals32 = new Float32Array(this._normals);
  261. this._fixedNormal32 = new Float32Array(this._normals);
  262. if (this._mustUnrotateFixedNormals) {
  263. this._unrotateFixedNormals();
  264. }
  265. var vertexData = new BABYLON.VertexData();
  266. vertexData.indices = (this._depthSort) ? this._indices : this._indices32;
  267. vertexData.set(this._positions32, BABYLON.VertexBuffer.PositionKind);
  268. vertexData.set(this._normals32, BABYLON.VertexBuffer.NormalKind);
  269. if (this._uvs32) {
  270. vertexData.set(this._uvs32, BABYLON.VertexBuffer.UVKind);
  271. ;
  272. }
  273. if (this._colors32) {
  274. vertexData.set(this._colors32, BABYLON.VertexBuffer.ColorKind);
  275. }
  276. var mesh = new BABYLON.Mesh(this.name, this._scene);
  277. vertexData.applyToMesh(mesh, this._updatable);
  278. this.mesh = mesh;
  279. this.mesh.isPickable = this._pickable;
  280. // free memory
  281. if (!this._depthSort) {
  282. this._indices = null;
  283. }
  284. this._positions = null;
  285. this._normals = null;
  286. this._uvs = null;
  287. this._colors = null;
  288. if (!this._updatable) {
  289. this.particles.length = 0;
  290. }
  291. return mesh;
  292. };
  293. /**
  294. * Digests the mesh and generates as many solid particles in the system as wanted. Returns the SPS.
  295. * These particles will have the same geometry than the mesh parts and will be positioned at the same localisation than the mesh original places.
  296. * Thus the particles generated from `digest()` have their property `position` set yet.
  297. * `mesh` ( Mesh ) is the mesh to be digested
  298. * `facetNb` (optional integer, default 1) is the number of mesh facets per particle, this parameter is overriden by the parameter `number` if any
  299. * `delta` (optional integer, default 0) is the random extra number of facets per particle , each particle will have between `facetNb` and `facetNb + delta` facets
  300. * `number` (optional positive integer) is the wanted number of particles : each particle is built with `mesh_total_facets / number` facets
  301. */
  302. SolidParticleSystem.prototype.digest = function (mesh, options) {
  303. var size = (options && options.facetNb) || 1;
  304. var number = (options && options.number) || 0;
  305. var delta = (options && options.delta) || 0;
  306. var meshPos = mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
  307. var meshInd = mesh.getIndices();
  308. var meshUV = mesh.getVerticesData(BABYLON.VertexBuffer.UVKind);
  309. var meshCol = mesh.getVerticesData(BABYLON.VertexBuffer.ColorKind);
  310. var meshNor = mesh.getVerticesData(BABYLON.VertexBuffer.NormalKind);
  311. var f = 0; // facet counter
  312. var totalFacets = meshInd.length / 3; // a facet is a triangle, so 3 indices
  313. // compute size from number
  314. if (number) {
  315. number = (number > totalFacets) ? totalFacets : number;
  316. size = Math.round(totalFacets / number);
  317. delta = 0;
  318. }
  319. else {
  320. size = (size > totalFacets) ? totalFacets : size;
  321. }
  322. var facetPos = []; // submesh positions
  323. var facetInd = []; // submesh indices
  324. var facetUV = []; // submesh UV
  325. var facetCol = []; // submesh colors
  326. var barycenter = BABYLON.Tmp.Vector3[0];
  327. var sizeO = size;
  328. while (f < totalFacets) {
  329. size = sizeO + Math.floor((1 + delta) * Math.random());
  330. if (f > totalFacets - size) {
  331. size = totalFacets - f;
  332. }
  333. // reset temp arrays
  334. facetPos.length = 0;
  335. facetInd.length = 0;
  336. facetUV.length = 0;
  337. facetCol.length = 0;
  338. // iterate over "size" facets
  339. var fi = 0;
  340. for (var j = f * 3; j < (f + size) * 3; j++) {
  341. facetInd.push(fi);
  342. var i = meshInd[j];
  343. facetPos.push(meshPos[i * 3], meshPos[i * 3 + 1], meshPos[i * 3 + 2]);
  344. if (meshUV) {
  345. facetUV.push(meshUV[i * 2], meshUV[i * 2 + 1]);
  346. }
  347. if (meshCol) {
  348. facetCol.push(meshCol[i * 4], meshCol[i * 4 + 1], meshCol[i * 4 + 2], meshCol[i * 4 + 3]);
  349. }
  350. fi++;
  351. }
  352. // create a model shape for each single particle
  353. var idx = this.nbParticles;
  354. var shape = this._posToShape(facetPos);
  355. var shapeUV = this._uvsToShapeUV(facetUV);
  356. // compute the barycenter of the shape
  357. var v;
  358. for (v = 0; v < shape.length; v++) {
  359. barycenter.addInPlace(shape[v]);
  360. }
  361. barycenter.scaleInPlace(1 / shape.length);
  362. // shift the shape from its barycenter to the origin
  363. for (v = 0; v < shape.length; v++) {
  364. shape[v].subtractInPlace(barycenter);
  365. }
  366. var bInfo;
  367. if (this._particlesIntersect) {
  368. bInfo = new BABYLON.BoundingInfo(barycenter, barycenter);
  369. }
  370. var modelShape = new BABYLON.ModelShape(this._shapeCounter, shape, size * 3, shapeUV, null, null);
  371. // add the particle in the SPS
  372. var currentPos = this._positions.length;
  373. var currentInd = this._indices.length;
  374. this._meshBuilder(this._index, shape, this._positions, facetInd, this._indices, facetUV, this._uvs, facetCol, this._colors, meshNor, this._normals, idx, 0, null);
  375. this._addParticle(idx, currentPos, currentInd, modelShape, this._shapeCounter, 0, bInfo);
  376. // initialize the particle position
  377. this.particles[this.nbParticles].position.addInPlace(barycenter);
  378. this._index += shape.length;
  379. idx++;
  380. this.nbParticles++;
  381. this._shapeCounter++;
  382. f += size;
  383. }
  384. return this;
  385. };
  386. // unrotate the fixed normals in case the mesh was built with pre-rotated particles, ex : use of positionFunction in addShape()
  387. SolidParticleSystem.prototype._unrotateFixedNormals = function () {
  388. var index = 0;
  389. var idx = 0;
  390. for (var p = 0; p < this.particles.length; p++) {
  391. this._particle = this.particles[p];
  392. this._shape = this._particle._model._shape;
  393. if (this._particle.rotationQuaternion) {
  394. this._quaternion.copyFrom(this._particle.rotationQuaternion);
  395. }
  396. else {
  397. this._yaw = this._particle.rotation.y;
  398. this._pitch = this._particle.rotation.x;
  399. this._roll = this._particle.rotation.z;
  400. this._quaternionRotationYPR();
  401. }
  402. this._quaternionToRotationMatrix();
  403. this._rotMatrix.invertToRef(this._invertMatrix);
  404. for (var pt = 0; pt < this._shape.length; pt++) {
  405. idx = index + pt * 3;
  406. BABYLON.Vector3.TransformNormalFromFloatsToRef(this._normals32[idx], this._normals32[idx + 1], this._normals32[idx + 2], this._invertMatrix, this._normal);
  407. this._fixedNormal32[idx] = this._normal.x;
  408. this._fixedNormal32[idx + 1] = this._normal.y;
  409. this._fixedNormal32[idx + 2] = this._normal.z;
  410. }
  411. index = idx + 3;
  412. }
  413. };
  414. //reset copy
  415. SolidParticleSystem.prototype._resetCopy = function () {
  416. this._copy.position.x = 0;
  417. this._copy.position.y = 0;
  418. this._copy.position.z = 0;
  419. this._copy.rotation.x = 0;
  420. this._copy.rotation.y = 0;
  421. this._copy.rotation.z = 0;
  422. this._copy.rotationQuaternion = null;
  423. this._copy.scaling.x = 1.0;
  424. this._copy.scaling.y = 1.0;
  425. this._copy.scaling.z = 1.0;
  426. this._copy.uvs.x = 0;
  427. this._copy.uvs.y = 0;
  428. this._copy.uvs.z = 1.0;
  429. this._copy.uvs.w = 1.0;
  430. this._copy.color = null;
  431. };
  432. // _meshBuilder : inserts the shape model in the global SPS mesh
  433. SolidParticleSystem.prototype._meshBuilder = function (p, shape, positions, meshInd, indices, meshUV, uvs, meshCol, colors, meshNor, normals, idx, idxInShape, options) {
  434. var i;
  435. var u = 0;
  436. var c = 0;
  437. var n = 0;
  438. this._resetCopy();
  439. if (options && options.positionFunction) {
  440. options.positionFunction(this._copy, idx, idxInShape);
  441. this._mustUnrotateFixedNormals = true;
  442. }
  443. if (this._copy.rotationQuaternion) {
  444. this._quaternion.copyFrom(this._copy.rotationQuaternion);
  445. }
  446. else {
  447. this._yaw = this._copy.rotation.y;
  448. this._pitch = this._copy.rotation.x;
  449. this._roll = this._copy.rotation.z;
  450. this._quaternionRotationYPR();
  451. }
  452. this._quaternionToRotationMatrix();
  453. for (i = 0; i < shape.length; i++) {
  454. this._vertex.x = shape[i].x;
  455. this._vertex.y = shape[i].y;
  456. this._vertex.z = shape[i].z;
  457. if (options && options.vertexFunction) {
  458. options.vertexFunction(this._copy, this._vertex, i);
  459. }
  460. this._vertex.x *= this._copy.scaling.x;
  461. this._vertex.y *= this._copy.scaling.y;
  462. this._vertex.z *= this._copy.scaling.z;
  463. this._vertex.x += this._copy.pivot.x;
  464. this._vertex.y += this._copy.pivot.y;
  465. this._vertex.z += this._copy.pivot.z;
  466. BABYLON.Vector3.TransformCoordinatesToRef(this._vertex, this._rotMatrix, this._rotated);
  467. positions.push(this._copy.position.x + this._rotated.x, this._copy.position.y + this._rotated.y, this._copy.position.z + this._rotated.z);
  468. if (meshUV) {
  469. uvs.push((this._copy.uvs.z - this._copy.uvs.x) * meshUV[u] + this._copy.uvs.x, (this._copy.uvs.w - this._copy.uvs.y) * meshUV[u + 1] + this._copy.uvs.y);
  470. u += 2;
  471. }
  472. if (this._copy.color) {
  473. this._color = this._copy.color;
  474. }
  475. else if (meshCol && meshCol[c] !== undefined) {
  476. this._color.r = meshCol[c];
  477. this._color.g = meshCol[c + 1];
  478. this._color.b = meshCol[c + 2];
  479. this._color.a = meshCol[c + 3];
  480. }
  481. else {
  482. this._color.r = 1.0;
  483. this._color.g = 1.0;
  484. this._color.b = 1.0;
  485. this._color.a = 1.0;
  486. }
  487. colors.push(this._color.r, this._color.g, this._color.b, this._color.a);
  488. c += 4;
  489. if (!this.recomputeNormals && meshNor) {
  490. this._normal.x = meshNor[n];
  491. this._normal.y = meshNor[n + 1];
  492. this._normal.z = meshNor[n + 2];
  493. BABYLON.Vector3.TransformNormalToRef(this._normal, this._rotMatrix, this._normal);
  494. normals.push(this._normal.x, this._normal.y, this._normal.z);
  495. n += 3;
  496. }
  497. }
  498. for (i = 0; i < meshInd.length; i++) {
  499. var current_ind = p + meshInd[i];
  500. indices.push(current_ind);
  501. if (current_ind > 65535) {
  502. this._needs32Bits = true;
  503. }
  504. }
  505. if (this._pickable) {
  506. var nbfaces = meshInd.length / 3;
  507. for (i = 0; i < nbfaces; i++) {
  508. this.pickedParticles.push({ idx: idx, faceId: i });
  509. }
  510. }
  511. if (this._depthSort) {
  512. this.depthSortedParticles.push(new BABYLON.DepthSortedParticle());
  513. }
  514. return this._copy;
  515. };
  516. // returns a shape array from positions array
  517. SolidParticleSystem.prototype._posToShape = function (positions) {
  518. var shape = [];
  519. for (var i = 0; i < positions.length; i += 3) {
  520. shape.push(new BABYLON.Vector3(positions[i], positions[i + 1], positions[i + 2]));
  521. }
  522. return shape;
  523. };
  524. // returns a shapeUV array from a Vector4 uvs
  525. SolidParticleSystem.prototype._uvsToShapeUV = function (uvs) {
  526. var shapeUV = [];
  527. if (uvs) {
  528. for (var i = 0; i < uvs.length; i++)
  529. shapeUV.push(uvs[i]);
  530. }
  531. return shapeUV;
  532. };
  533. // adds a new particle object in the particles array
  534. SolidParticleSystem.prototype._addParticle = function (idx, idxpos, idxind, model, shapeId, idxInShape, bInfo) {
  535. if (bInfo === void 0) { bInfo = null; }
  536. var sp = new BABYLON.SolidParticle(idx, idxpos, idxind, model, shapeId, idxInShape, this, bInfo);
  537. this.particles.push(sp);
  538. return sp;
  539. };
  540. /**
  541. * Adds some particles to the SPS from the model shape. Returns the shape id.
  542. * Please read the doc : http://doc.babylonjs.com/overviews/Solid_Particle_System#create-an-immutable-sps
  543. * `mesh` is any Mesh object that will be used as a model for the solid particles.
  544. * `nb` (positive integer) the number of particles to be created from this model
  545. * `positionFunction` is an optional javascript function to called for each particle on SPS creation.
  546. * `vertexFunction` is an optional javascript function to called for each vertex of each particle on SPS creation
  547. */
  548. SolidParticleSystem.prototype.addShape = function (mesh, nb, options) {
  549. var meshPos = mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
  550. var meshInd = mesh.getIndices();
  551. var meshUV = mesh.getVerticesData(BABYLON.VertexBuffer.UVKind);
  552. var meshCol = mesh.getVerticesData(BABYLON.VertexBuffer.ColorKind);
  553. var meshNor = mesh.getVerticesData(BABYLON.VertexBuffer.NormalKind);
  554. var bbInfo;
  555. if (this._particlesIntersect) {
  556. bbInfo = mesh.getBoundingInfo();
  557. }
  558. var shape = this._posToShape(meshPos);
  559. var shapeUV = this._uvsToShapeUV(meshUV);
  560. var posfunc = options ? options.positionFunction : null;
  561. var vtxfunc = options ? options.vertexFunction : null;
  562. var modelShape = new BABYLON.ModelShape(this._shapeCounter, shape, meshInd.length, shapeUV, posfunc, vtxfunc);
  563. // particles
  564. var sp;
  565. var currentCopy;
  566. var idx = this.nbParticles;
  567. for (var i = 0; i < nb; i++) {
  568. var currentPos = this._positions.length;
  569. var currentInd = this._indices.length;
  570. currentCopy = this._meshBuilder(this._index, shape, this._positions, meshInd, this._indices, meshUV, this._uvs, meshCol, this._colors, meshNor, this._normals, idx, i, options);
  571. if (this._updatable) {
  572. sp = this._addParticle(idx, currentPos, currentInd, modelShape, this._shapeCounter, i, bbInfo);
  573. sp.position.copyFrom(currentCopy.position);
  574. sp.rotation.copyFrom(currentCopy.rotation);
  575. if (currentCopy.rotationQuaternion && sp.rotationQuaternion) {
  576. sp.rotationQuaternion.copyFrom(currentCopy.rotationQuaternion);
  577. }
  578. if (currentCopy.color && sp.color) {
  579. sp.color.copyFrom(currentCopy.color);
  580. }
  581. sp.scaling.copyFrom(currentCopy.scaling);
  582. sp.uvs.copyFrom(currentCopy.uvs);
  583. }
  584. this._index += shape.length;
  585. idx++;
  586. }
  587. this.nbParticles += nb;
  588. this._shapeCounter++;
  589. return this._shapeCounter - 1;
  590. };
  591. // rebuilds a particle back to its just built status : if needed, recomputes the custom positions and vertices
  592. SolidParticleSystem.prototype._rebuildParticle = function (particle) {
  593. this._resetCopy();
  594. if (particle._model._positionFunction) {
  595. particle._model._positionFunction(this._copy, particle.idx, particle.idxInShape);
  596. }
  597. if (this._copy.rotationQuaternion) {
  598. this._quaternion.copyFrom(this._copy.rotationQuaternion);
  599. }
  600. else {
  601. this._yaw = this._copy.rotation.y;
  602. this._pitch = this._copy.rotation.x;
  603. this._roll = this._copy.rotation.z;
  604. this._quaternionRotationYPR();
  605. }
  606. this._quaternionToRotationMatrix();
  607. this._shape = particle._model._shape;
  608. for (var pt = 0; pt < this._shape.length; pt++) {
  609. this._vertex.x = this._shape[pt].x;
  610. this._vertex.y = this._shape[pt].y;
  611. this._vertex.z = this._shape[pt].z;
  612. if (particle._model._vertexFunction) {
  613. particle._model._vertexFunction(this._copy, this._vertex, pt); // recall to stored vertexFunction
  614. }
  615. this._vertex.x *= this._copy.scaling.x;
  616. this._vertex.y *= this._copy.scaling.y;
  617. this._vertex.z *= this._copy.scaling.z;
  618. this._vertex.x += this._copy.pivot.x;
  619. this._vertex.y += this._copy.pivot.y;
  620. this._vertex.z += this._copy.pivot.z;
  621. BABYLON.Vector3.TransformCoordinatesToRef(this._vertex, this._rotMatrix, this._rotated);
  622. this._positions32[particle._pos + pt * 3] = this._copy.position.x + this._rotated.x;
  623. this._positions32[particle._pos + pt * 3 + 1] = this._copy.position.y + this._rotated.y;
  624. this._positions32[particle._pos + pt * 3 + 2] = this._copy.position.z + this._rotated.z;
  625. }
  626. particle.position.x = 0.0;
  627. particle.position.y = 0.0;
  628. particle.position.z = 0.0;
  629. particle.rotation.x = 0.0;
  630. particle.rotation.y = 0.0;
  631. particle.rotation.z = 0.0;
  632. particle.rotationQuaternion = null;
  633. particle.scaling.x = 1.0;
  634. particle.scaling.y = 1.0;
  635. particle.scaling.z = 1.0;
  636. };
  637. /**
  638. * Rebuilds the whole mesh and updates the VBO : custom positions and vertices are recomputed if needed.
  639. * Returns the SPS.
  640. */
  641. SolidParticleSystem.prototype.rebuildMesh = function () {
  642. for (var p = 0; p < this.particles.length; p++) {
  643. this._rebuildParticle(this.particles[p]);
  644. }
  645. this.mesh.updateVerticesData(BABYLON.VertexBuffer.PositionKind, this._positions32, false, false);
  646. return this;
  647. };
  648. /**
  649. * Sets all the particles : this method actually really updates the mesh according to the particle positions, rotations, colors, textures, etc.
  650. * This method calls `updateParticle()` for each particle of the SPS.
  651. * For an animated SPS, it is usually called within the render loop.
  652. * @param start The particle index in the particle array where to start to compute the particle property values _(default 0)_
  653. * @param end The particle index in the particle array where to stop to compute the particle property values _(default nbParticle - 1)_
  654. * @param update If the mesh must be finally updated on this call after all the particle computations _(default true)_
  655. * Returns the SPS.
  656. */
  657. SolidParticleSystem.prototype.setParticles = function (start, end, update) {
  658. if (start === void 0) { start = 0; }
  659. if (end === void 0) { end = this.nbParticles - 1; }
  660. if (update === void 0) { update = true; }
  661. if (!this._updatable) {
  662. return this;
  663. }
  664. // custom beforeUpdate
  665. this.beforeUpdateParticles(start, end, update);
  666. this._cam_axisX.x = 1.0;
  667. this._cam_axisX.y = 0.0;
  668. this._cam_axisX.z = 0.0;
  669. this._cam_axisY.x = 0.0;
  670. this._cam_axisY.y = 1.0;
  671. this._cam_axisY.z = 0.0;
  672. this._cam_axisZ.x = 0.0;
  673. this._cam_axisZ.y = 0.0;
  674. this._cam_axisZ.z = 1.0;
  675. // cases when the World Matrix is to be computed first
  676. if (this.billboard || this._depthSort) {
  677. this.mesh.computeWorldMatrix(true);
  678. this.mesh._worldMatrix.invertToRef(this._invertMatrix);
  679. }
  680. // if the particles will always face the camera
  681. if (this.billboard) {
  682. // compute the camera position and un-rotate it by the current mesh rotation
  683. this._camera.getDirectionToRef(this._axisZ, this._camDir);
  684. BABYLON.Vector3.TransformNormalToRef(this._camDir, this._invertMatrix, this._cam_axisZ);
  685. this._cam_axisZ.normalize();
  686. // same for camera up vector extracted from the cam view matrix
  687. var view = this._camera.getViewMatrix(true);
  688. BABYLON.Vector3.TransformNormalFromFloatsToRef(view.m[1], view.m[5], view.m[9], this._invertMatrix, this._cam_axisY);
  689. BABYLON.Vector3.CrossToRef(this._cam_axisY, this._cam_axisZ, this._cam_axisX);
  690. this._cam_axisY.normalize();
  691. this._cam_axisX.normalize();
  692. }
  693. // if depthSort, compute the camera global position in the mesh local system
  694. if (this._depthSort) {
  695. BABYLON.Vector3.TransformCoordinatesToRef(this._camera.globalPosition, this._invertMatrix, this._camInvertedPosition); // then un-rotate the camera
  696. }
  697. BABYLON.Matrix.IdentityToRef(this._rotMatrix);
  698. var idx = 0; // current position index in the global array positions32
  699. var index = 0; // position start index in the global array positions32 of the current particle
  700. var colidx = 0; // current color index in the global array colors32
  701. var colorIndex = 0; // color start index in the global array colors32 of the current particle
  702. var uvidx = 0; // current uv index in the global array uvs32
  703. var uvIndex = 0; // uv start index in the global array uvs32 of the current particle
  704. var pt = 0; // current index in the particle model shape
  705. if (this.mesh.isFacetDataEnabled) {
  706. this._computeBoundingBox = true;
  707. }
  708. end = (end >= this.nbParticles) ? this.nbParticles - 1 : end;
  709. if (this._computeBoundingBox) {
  710. if (start == 0 && end == this.nbParticles - 1) {
  711. BABYLON.Vector3.FromFloatsToRef(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, this._minimum);
  712. BABYLON.Vector3.FromFloatsToRef(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, this._maximum);
  713. }
  714. else {
  715. if (this.mesh._boundingInfo) {
  716. this._minimum.copyFrom(this.mesh._boundingInfo.boundingBox.minimum);
  717. this._maximum.copyFrom(this.mesh._boundingInfo.boundingBox.maximum);
  718. }
  719. }
  720. }
  721. // particle loop
  722. index = this.particles[start]._pos;
  723. var vpos = (index / 3) | 0;
  724. colorIndex = vpos * 4;
  725. uvIndex = vpos * 2;
  726. for (var p = start; p <= end; p++) {
  727. this._particle = this.particles[p];
  728. this._shape = this._particle._model._shape;
  729. this._shapeUV = this._particle._model._shapeUV;
  730. // call to custom user function to update the particle properties
  731. this.updateParticle(this._particle);
  732. // camera-particle distance for depth sorting
  733. if (this._depthSort && this._depthSortParticles) {
  734. var dsp = this.depthSortedParticles[p];
  735. dsp.ind = this._particle._ind;
  736. dsp.indicesLength = this._particle._model._indicesLength;
  737. dsp.sqDistance = BABYLON.Vector3.DistanceSquared(this._particle.position, this._camInvertedPosition);
  738. }
  739. // skip the computations for inactive or already invisible particles
  740. if (!this._particle.alive || (this._particle._stillInvisible && !this._particle.isVisible)) {
  741. // increment indexes for the next particle
  742. pt = this._shape.length;
  743. index += pt * 3;
  744. colorIndex += pt * 4;
  745. uvIndex += pt * 2;
  746. continue;
  747. }
  748. if (this._particle.isVisible) {
  749. this._particle._stillInvisible = false; // un-mark permanent invisibility
  750. // particle rotation matrix
  751. if (this.billboard) {
  752. this._particle.rotation.x = 0.0;
  753. this._particle.rotation.y = 0.0;
  754. }
  755. if (this._computeParticleRotation || this.billboard) {
  756. if (this._particle.rotationQuaternion) {
  757. this._quaternion.copyFrom(this._particle.rotationQuaternion);
  758. }
  759. else {
  760. this._yaw = this._particle.rotation.y;
  761. this._pitch = this._particle.rotation.x;
  762. this._roll = this._particle.rotation.z;
  763. this._quaternionRotationYPR();
  764. }
  765. this._quaternionToRotationMatrix();
  766. }
  767. // particle vertex loop
  768. for (pt = 0; pt < this._shape.length; pt++) {
  769. idx = index + pt * 3;
  770. colidx = colorIndex + pt * 4;
  771. uvidx = uvIndex + pt * 2;
  772. this._vertex.x = this._shape[pt].x;
  773. this._vertex.y = this._shape[pt].y;
  774. this._vertex.z = this._shape[pt].z;
  775. if (this._computeParticleVertex) {
  776. this.updateParticleVertex(this._particle, this._vertex, pt);
  777. }
  778. // positions
  779. this._vertex.x *= this._particle.scaling.x;
  780. this._vertex.y *= this._particle.scaling.y;
  781. this._vertex.z *= this._particle.scaling.z;
  782. this._vertex.x += this._particle.pivot.x;
  783. this._vertex.y += this._particle.pivot.y;
  784. this._vertex.z += this._particle.pivot.z;
  785. this._rotated.x = this._vertex.x * this._rotMatrix.m[0] + this._vertex.y * this._rotMatrix.m[4] + this._vertex.z * this._rotMatrix.m[8];
  786. this._rotated.y = this._vertex.x * this._rotMatrix.m[1] + this._vertex.y * this._rotMatrix.m[5] + this._vertex.z * this._rotMatrix.m[9];
  787. this._rotated.z = this._vertex.x * this._rotMatrix.m[2] + this._vertex.y * this._rotMatrix.m[6] + this._vertex.z * this._rotMatrix.m[10];
  788. this._positions32[idx] = this._particle.position.x + this._cam_axisX.x * this._rotated.x + this._cam_axisY.x * this._rotated.y + this._cam_axisZ.x * this._rotated.z;
  789. this._positions32[idx + 1] = this._particle.position.y + this._cam_axisX.y * this._rotated.x + this._cam_axisY.y * this._rotated.y + this._cam_axisZ.y * this._rotated.z;
  790. this._positions32[idx + 2] = this._particle.position.z + this._cam_axisX.z * this._rotated.x + this._cam_axisY.z * this._rotated.y + this._cam_axisZ.z * this._rotated.z;
  791. if (this._computeBoundingBox) {
  792. if (this._positions32[idx] < this._minimum.x) {
  793. this._minimum.x = this._positions32[idx];
  794. }
  795. if (this._positions32[idx] > this._maximum.x) {
  796. this._maximum.x = this._positions32[idx];
  797. }
  798. if (this._positions32[idx + 1] < this._minimum.y) {
  799. this._minimum.y = this._positions32[idx + 1];
  800. }
  801. if (this._positions32[idx + 1] > this._maximum.y) {
  802. this._maximum.y = this._positions32[idx + 1];
  803. }
  804. if (this._positions32[idx + 2] < this._minimum.z) {
  805. this._minimum.z = this._positions32[idx + 2];
  806. }
  807. if (this._positions32[idx + 2] > this._maximum.z) {
  808. this._maximum.z = this._positions32[idx + 2];
  809. }
  810. }
  811. // normals : if the particles can't be morphed then just rotate the normals, what is much more faster than ComputeNormals()
  812. if (!this._computeParticleVertex) {
  813. this._normal.x = this._fixedNormal32[idx];
  814. this._normal.y = this._fixedNormal32[idx + 1];
  815. this._normal.z = this._fixedNormal32[idx + 2];
  816. this._rotated.x = this._normal.x * this._rotMatrix.m[0] + this._normal.y * this._rotMatrix.m[4] + this._normal.z * this._rotMatrix.m[8];
  817. this._rotated.y = this._normal.x * this._rotMatrix.m[1] + this._normal.y * this._rotMatrix.m[5] + this._normal.z * this._rotMatrix.m[9];
  818. this._rotated.z = this._normal.x * this._rotMatrix.m[2] + this._normal.y * this._rotMatrix.m[6] + this._normal.z * this._rotMatrix.m[10];
  819. this._normals32[idx] = this._cam_axisX.x * this._rotated.x + this._cam_axisY.x * this._rotated.y + this._cam_axisZ.x * this._rotated.z;
  820. this._normals32[idx + 1] = this._cam_axisX.y * this._rotated.x + this._cam_axisY.y * this._rotated.y + this._cam_axisZ.y * this._rotated.z;
  821. this._normals32[idx + 2] = this._cam_axisX.z * this._rotated.x + this._cam_axisY.z * this._rotated.y + this._cam_axisZ.z * this._rotated.z;
  822. }
  823. if (this._computeParticleColor && this._particle.color) {
  824. this._colors32[colidx] = this._particle.color.r;
  825. this._colors32[colidx + 1] = this._particle.color.g;
  826. this._colors32[colidx + 2] = this._particle.color.b;
  827. this._colors32[colidx + 3] = this._particle.color.a;
  828. }
  829. if (this._computeParticleTexture) {
  830. this._uvs32[uvidx] = this._shapeUV[pt * 2] * (this._particle.uvs.z - this._particle.uvs.x) + this._particle.uvs.x;
  831. this._uvs32[uvidx + 1] = this._shapeUV[pt * 2 + 1] * (this._particle.uvs.w - this._particle.uvs.y) + this._particle.uvs.y;
  832. }
  833. }
  834. }
  835. else {
  836. this._particle._stillInvisible = true; // mark the particle as invisible
  837. for (pt = 0; pt < this._shape.length; pt++) {
  838. idx = index + pt * 3;
  839. colidx = colorIndex + pt * 4;
  840. uvidx = uvIndex + pt * 2;
  841. this._positions32[idx] = 0.0;
  842. this._positions32[idx + 1] = 0.0;
  843. this._positions32[idx + 2] = 0.0;
  844. this._normals32[idx] = 0.0;
  845. this._normals32[idx + 1] = 0.0;
  846. this._normals32[idx + 2] = 0.0;
  847. if (this._computeParticleColor && this._particle.color) {
  848. this._colors32[colidx] = this._particle.color.r;
  849. this._colors32[colidx + 1] = this._particle.color.g;
  850. this._colors32[colidx + 2] = this._particle.color.b;
  851. this._colors32[colidx + 3] = this._particle.color.a;
  852. }
  853. if (this._computeParticleTexture) {
  854. this._uvs32[uvidx] = this._shapeUV[pt * 2] * (this._particle.uvs.z - this._particle.uvs.x) + this._particle.uvs.x;
  855. this._uvs32[uvidx + 1] = this._shapeUV[pt * 2 + 1] * (this._particle.uvs.w - this._particle.uvs.y) + this._particle.uvs.y;
  856. }
  857. }
  858. }
  859. // if the particle intersections must be computed : update the bbInfo
  860. if (this._particlesIntersect) {
  861. var bInfo = this._particle._boundingInfo;
  862. var bBox = bInfo.boundingBox;
  863. var bSphere = bInfo.boundingSphere;
  864. if (!this._bSphereOnly) {
  865. // place, scale and rotate the particle bbox within the SPS local system, then update it
  866. for (var b = 0; b < bBox.vectors.length; b++) {
  867. this._vertex.x = this._particle._modelBoundingInfo.boundingBox.vectors[b].x * this._particle.scaling.x;
  868. this._vertex.y = this._particle._modelBoundingInfo.boundingBox.vectors[b].y * this._particle.scaling.y;
  869. this._vertex.z = this._particle._modelBoundingInfo.boundingBox.vectors[b].z * this._particle.scaling.z;
  870. this._rotated.x = this._vertex.x * this._rotMatrix.m[0] + this._vertex.y * this._rotMatrix.m[4] + this._vertex.z * this._rotMatrix.m[8];
  871. this._rotated.y = this._vertex.x * this._rotMatrix.m[1] + this._vertex.y * this._rotMatrix.m[5] + this._vertex.z * this._rotMatrix.m[9];
  872. this._rotated.z = this._vertex.x * this._rotMatrix.m[2] + this._vertex.y * this._rotMatrix.m[6] + this._vertex.z * this._rotMatrix.m[10];
  873. bBox.vectors[b].x = this._particle.position.x + this._cam_axisX.x * this._rotated.x + this._cam_axisY.x * this._rotated.y + this._cam_axisZ.x * this._rotated.z;
  874. bBox.vectors[b].y = this._particle.position.y + this._cam_axisX.y * this._rotated.x + this._cam_axisY.y * this._rotated.y + this._cam_axisZ.y * this._rotated.z;
  875. bBox.vectors[b].z = this._particle.position.z + this._cam_axisX.z * this._rotated.x + this._cam_axisY.z * this._rotated.y + this._cam_axisZ.z * this._rotated.z;
  876. }
  877. bBox._update(this.mesh._worldMatrix);
  878. }
  879. // place and scale the particle bouding sphere in the SPS local system, then update it
  880. this._minBbox.x = this._particle._modelBoundingInfo.minimum.x * this._particle.scaling.x;
  881. this._minBbox.y = this._particle._modelBoundingInfo.minimum.y * this._particle.scaling.y;
  882. this._minBbox.z = this._particle._modelBoundingInfo.minimum.z * this._particle.scaling.z;
  883. this._maxBbox.x = this._particle._modelBoundingInfo.maximum.x * this._particle.scaling.x;
  884. this._maxBbox.y = this._particle._modelBoundingInfo.maximum.y * this._particle.scaling.y;
  885. this._maxBbox.z = this._particle._modelBoundingInfo.maximum.z * this._particle.scaling.z;
  886. bSphere.center.x = this._particle.position.x + (this._minBbox.x + this._maxBbox.x) * 0.5;
  887. bSphere.center.y = this._particle.position.y + (this._minBbox.y + this._maxBbox.y) * 0.5;
  888. bSphere.center.z = this._particle.position.z + (this._minBbox.z + this._maxBbox.z) * 0.5;
  889. bSphere.radius = this._bSphereRadiusFactor * 0.5 * Math.sqrt((this._maxBbox.x - this._minBbox.x) * (this._maxBbox.x - this._minBbox.x) + (this._maxBbox.y - this._minBbox.y) * (this._maxBbox.y - this._minBbox.y) + (this._maxBbox.z - this._minBbox.z) * (this._maxBbox.z - this._minBbox.z));
  890. bSphere._update(this.mesh._worldMatrix);
  891. }
  892. // increment indexes for the next particle
  893. index = idx + 3;
  894. colorIndex = colidx + 4;
  895. uvIndex = uvidx + 2;
  896. }
  897. // if the VBO must be updated
  898. if (update) {
  899. if (this._computeParticleColor) {
  900. this.mesh.updateVerticesData(BABYLON.VertexBuffer.ColorKind, this._colors32, false, false);
  901. }
  902. if (this._computeParticleTexture) {
  903. this.mesh.updateVerticesData(BABYLON.VertexBuffer.UVKind, this._uvs32, false, false);
  904. }
  905. this.mesh.updateVerticesData(BABYLON.VertexBuffer.PositionKind, this._positions32, false, false);
  906. if (!this.mesh.areNormalsFrozen || this.mesh.isFacetDataEnabled) {
  907. if (this._computeParticleVertex || this.mesh.isFacetDataEnabled) {
  908. // recompute the normals only if the particles can be morphed, update then also the normal reference array _fixedNormal32[]
  909. var params = this.mesh.isFacetDataEnabled ? this.mesh.getFacetDataParameters() : null;
  910. BABYLON.VertexData.ComputeNormals(this._positions32, this._indices, this._normals32, params);
  911. for (var i = 0; i < this._normals32.length; i++) {
  912. this._fixedNormal32[i] = this._normals32[i];
  913. }
  914. }
  915. if (!this.mesh.areNormalsFrozen) {
  916. this.mesh.updateVerticesData(BABYLON.VertexBuffer.NormalKind, this._normals32, false, false);
  917. }
  918. }
  919. if (this._depthSort && this._depthSortParticles) {
  920. this.depthSortedParticles.sort(this._depthSortFunction);
  921. var dspl = this.depthSortedParticles.length;
  922. var sorted = 0;
  923. var lind = 0;
  924. var sind = 0;
  925. var sid = 0;
  926. for (sorted = 0; sorted < dspl; sorted++) {
  927. lind = this.depthSortedParticles[sorted].indicesLength;
  928. sind = this.depthSortedParticles[sorted].ind;
  929. for (var i = 0; i < lind; i++) {
  930. this._indices32[sid] = this._indices[sind + i];
  931. sid++;
  932. }
  933. }
  934. this.mesh.updateIndices(this._indices32);
  935. }
  936. }
  937. if (this._computeBoundingBox) {
  938. this.mesh._boundingInfo = new BABYLON.BoundingInfo(this._minimum, this._maximum);
  939. this.mesh._boundingInfo.update(this.mesh._worldMatrix);
  940. }
  941. this.afterUpdateParticles(start, end, update);
  942. return this;
  943. };
  944. SolidParticleSystem.prototype._quaternionRotationYPR = function () {
  945. this._halfroll = this._roll * 0.5;
  946. this._halfpitch = this._pitch * 0.5;
  947. this._halfyaw = this._yaw * 0.5;
  948. this._sinRoll = Math.sin(this._halfroll);
  949. this._cosRoll = Math.cos(this._halfroll);
  950. this._sinPitch = Math.sin(this._halfpitch);
  951. this._cosPitch = Math.cos(this._halfpitch);
  952. this._sinYaw = Math.sin(this._halfyaw);
  953. this._cosYaw = Math.cos(this._halfyaw);
  954. this._quaternion.x = this._cosYaw * this._sinPitch * this._cosRoll + this._sinYaw * this._cosPitch * this._sinRoll;
  955. this._quaternion.y = this._sinYaw * this._cosPitch * this._cosRoll - this._cosYaw * this._sinPitch * this._sinRoll;
  956. this._quaternion.z = this._cosYaw * this._cosPitch * this._sinRoll - this._sinYaw * this._sinPitch * this._cosRoll;
  957. this._quaternion.w = this._cosYaw * this._cosPitch * this._cosRoll + this._sinYaw * this._sinPitch * this._sinRoll;
  958. };
  959. SolidParticleSystem.prototype._quaternionToRotationMatrix = function () {
  960. this._rotMatrix.m[0] = 1.0 - (2.0 * (this._quaternion.y * this._quaternion.y + this._quaternion.z * this._quaternion.z));
  961. this._rotMatrix.m[1] = 2.0 * (this._quaternion.x * this._quaternion.y + this._quaternion.z * this._quaternion.w);
  962. this._rotMatrix.m[2] = 2.0 * (this._quaternion.z * this._quaternion.x - this._quaternion.y * this._quaternion.w);
  963. this._rotMatrix.m[3] = 0;
  964. this._rotMatrix.m[4] = 2.0 * (this._quaternion.x * this._quaternion.y - this._quaternion.z * this._quaternion.w);
  965. this._rotMatrix.m[5] = 1.0 - (2.0 * (this._quaternion.z * this._quaternion.z + this._quaternion.x * this._quaternion.x));
  966. this._rotMatrix.m[6] = 2.0 * (this._quaternion.y * this._quaternion.z + this._quaternion.x * this._quaternion.w);
  967. this._rotMatrix.m[7] = 0;
  968. this._rotMatrix.m[8] = 2.0 * (this._quaternion.z * this._quaternion.x + this._quaternion.y * this._quaternion.w);
  969. this._rotMatrix.m[9] = 2.0 * (this._quaternion.y * this._quaternion.z - this._quaternion.x * this._quaternion.w);
  970. this._rotMatrix.m[10] = 1.0 - (2.0 * (this._quaternion.y * this._quaternion.y + this._quaternion.x * this._quaternion.x));
  971. this._rotMatrix.m[11] = 0;
  972. this._rotMatrix.m[12] = 0;
  973. this._rotMatrix.m[13] = 0;
  974. this._rotMatrix.m[14] = 0;
  975. this._rotMatrix.m[15] = 1.0;
  976. };
  977. /**
  978. * Disposes the SPS.
  979. * Returns nothing.
  980. */
  981. SolidParticleSystem.prototype.dispose = function () {
  982. this.mesh.dispose();
  983. this.vars = null;
  984. // drop references to internal big arrays for the GC
  985. this._positions = null;
  986. this._indices = null;
  987. this._normals = null;
  988. this._uvs = null;
  989. this._colors = null;
  990. this._indices32 = null;
  991. this._positions32 = null;
  992. this._normals32 = null;
  993. this._fixedNormal32 = null;
  994. this._uvs32 = null;
  995. this._colors32 = null;
  996. this.pickedParticles = null;
  997. };
  998. /**
  999. * Visibilty helper : Recomputes the visible size according to the mesh bounding box
  1000. * doc : http://doc.babylonjs.com/overviews/Solid_Particle_System#sps-visibility
  1001. * Returns the SPS.
  1002. */
  1003. SolidParticleSystem.prototype.refreshVisibleSize = function () {
  1004. if (!this._isVisibilityBoxLocked) {
  1005. this.mesh.refreshBoundingInfo();
  1006. }
  1007. return this;
  1008. };
  1009. /**
  1010. * Visibility helper : Sets the size of a visibility box, this sets the underlying mesh bounding box.
  1011. * @param size the size (float) of the visibility box
  1012. * note : this doesn't lock the SPS mesh bounding box.
  1013. * doc : http://doc.babylonjs.com/overviews/Solid_Particle_System#sps-visibility
  1014. */
  1015. SolidParticleSystem.prototype.setVisibilityBox = function (size) {
  1016. var vis = size / 2;
  1017. this.mesh._boundingInfo = new BABYLON.BoundingInfo(new BABYLON.Vector3(-vis, -vis, -vis), new BABYLON.Vector3(vis, vis, vis));
  1018. };
  1019. Object.defineProperty(SolidParticleSystem.prototype, "isAlwaysVisible", {
  1020. // getter and setter
  1021. get: function () {
  1022. return this._alwaysVisible;
  1023. },
  1024. /**
  1025. * Sets the SPS as always visible or not
  1026. * doc : http://doc.babylonjs.com/overviews/Solid_Particle_System#sps-visibility
  1027. */
  1028. set: function (val) {
  1029. this._alwaysVisible = val;
  1030. this.mesh.alwaysSelectAsActiveMesh = val;
  1031. },
  1032. enumerable: true,
  1033. configurable: true
  1034. });
  1035. Object.defineProperty(SolidParticleSystem.prototype, "isVisibilityBoxLocked", {
  1036. get: function () {
  1037. return this._isVisibilityBoxLocked;
  1038. },
  1039. /**
  1040. * Sets the SPS visibility box as locked or not. This enables/disables the underlying mesh bounding box updates.
  1041. * doc : http://doc.babylonjs.com/overviews/Solid_Particle_System#sps-visibility
  1042. */
  1043. set: function (val) {
  1044. this._isVisibilityBoxLocked = val;
  1045. var boundingInfo = this.mesh.getBoundingInfo();
  1046. boundingInfo.isLocked = val;
  1047. },
  1048. enumerable: true,
  1049. configurable: true
  1050. });
  1051. Object.defineProperty(SolidParticleSystem.prototype, "computeParticleRotation", {
  1052. // getters
  1053. get: function () {
  1054. return this._computeParticleRotation;
  1055. },
  1056. // Optimizer setters
  1057. /**
  1058. * Tells to `setParticles()` to compute the particle rotations or not.
  1059. * Default value : true. The SPS is faster when it's set to false.
  1060. * Note : the particle rotations aren't stored values, so setting `computeParticleRotation` to false will prevents the particle to rotate.
  1061. */
  1062. set: function (val) {
  1063. this._computeParticleRotation = val;
  1064. },
  1065. enumerable: true,
  1066. configurable: true
  1067. });
  1068. Object.defineProperty(SolidParticleSystem.prototype, "computeParticleColor", {
  1069. get: function () {
  1070. return this._computeParticleColor;
  1071. },
  1072. /**
  1073. * Tells to `setParticles()` to compute the particle colors or not.
  1074. * Default value : true. The SPS is faster when it's set to false.
  1075. * Note : the particle colors are stored values, so setting `computeParticleColor` to false will keep yet the last colors set.
  1076. */
  1077. set: function (val) {
  1078. this._computeParticleColor = val;
  1079. },
  1080. enumerable: true,
  1081. configurable: true
  1082. });
  1083. Object.defineProperty(SolidParticleSystem.prototype, "computeParticleTexture", {
  1084. get: function () {
  1085. return this._computeParticleTexture;
  1086. },
  1087. /**
  1088. * Tells to `setParticles()` to compute the particle textures or not.
  1089. * Default value : true. The SPS is faster when it's set to false.
  1090. * Note : the particle textures are stored values, so setting `computeParticleTexture` to false will keep yet the last colors set.
  1091. */
  1092. set: function (val) {
  1093. this._computeParticleTexture = val;
  1094. },
  1095. enumerable: true,
  1096. configurable: true
  1097. });
  1098. Object.defineProperty(SolidParticleSystem.prototype, "computeParticleVertex", {
  1099. get: function () {
  1100. return this._computeParticleVertex;
  1101. },
  1102. /**
  1103. * Tells to `setParticles()` to call the vertex function for each vertex of each particle, or not.
  1104. * Default value : false. The SPS is faster when it's set to false.
  1105. * Note : the particle custom vertex positions aren't stored values.
  1106. */
  1107. set: function (val) {
  1108. this._computeParticleVertex = val;
  1109. },
  1110. enumerable: true,
  1111. configurable: true
  1112. });
  1113. Object.defineProperty(SolidParticleSystem.prototype, "computeBoundingBox", {
  1114. get: function () {
  1115. return this._computeBoundingBox;
  1116. },
  1117. /**
  1118. * Tells to `setParticles()` to compute or not the mesh bounding box when computing the particle positions.
  1119. */
  1120. set: function (val) {
  1121. this._computeBoundingBox = val;
  1122. },
  1123. enumerable: true,
  1124. configurable: true
  1125. });
  1126. Object.defineProperty(SolidParticleSystem.prototype, "depthSortParticles", {
  1127. get: function () {
  1128. return this._depthSortParticles;
  1129. },
  1130. /**
  1131. * Tells to `setParticles()` to sort or not the distance between each particle and the camera.
  1132. * Skipped when `enableDepthSort` is set to `false` (default) at construction time.
  1133. * Default : `true`
  1134. */
  1135. set: function (val) {
  1136. this._depthSortParticles = val;
  1137. },
  1138. enumerable: true,
  1139. configurable: true
  1140. });
  1141. // =======================================================================
  1142. // Particle behavior logic
  1143. // these following methods may be overwritten by the user to fit his needs
  1144. /**
  1145. * This function does nothing. It may be overwritten to set all the particle first values.
  1146. * The SPS doesn't call this function, you may have to call it by your own.
  1147. * doc : http://doc.babylonjs.com/overviews/Solid_Particle_System#particle-management
  1148. */
  1149. SolidParticleSystem.prototype.initParticles = function () {
  1150. };
  1151. /**
  1152. * This function does nothing. It may be overwritten to recycle a particle.
  1153. * The SPS doesn't call this function, you may have to call it by your own.
  1154. * doc : http://doc.babylonjs.com/overviews/Solid_Particle_System#particle-management
  1155. */
  1156. SolidParticleSystem.prototype.recycleParticle = function (particle) {
  1157. return particle;
  1158. };
  1159. /**
  1160. * Updates a particle : this function should be overwritten by the user.
  1161. * It is called on each particle by `setParticles()`. This is the place to code each particle behavior.
  1162. * doc : http://doc.babylonjs.com/overviews/Solid_Particle_System#particle-management
  1163. * ex : just set a particle position or velocity and recycle conditions
  1164. */
  1165. SolidParticleSystem.prototype.updateParticle = function (particle) {
  1166. return particle;
  1167. };
  1168. /**
  1169. * Updates a vertex of a particle : it can be overwritten by the user.
  1170. * This will be called on each vertex particle by `setParticles()` if `computeParticleVertex` is set to true only.
  1171. * @param particle the current particle
  1172. * @param vertex the current index of the current particle
  1173. * @param pt the index of the current vertex in the particle shape
  1174. * doc : http://doc.babylonjs.com/overviews/Solid_Particle_System#update-each-particle-shape
  1175. * ex : just set a vertex particle position
  1176. */
  1177. SolidParticleSystem.prototype.updateParticleVertex = function (particle, vertex, pt) {
  1178. return vertex;
  1179. };
  1180. /**
  1181. * This will be called before any other treatment by `setParticles()` and will be passed three parameters.
  1182. * This does nothing and may be overwritten by the user.
  1183. * @param start the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()
  1184. * @param stop the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()
  1185. * @param update the boolean update value actually passed to setParticles()
  1186. */
  1187. SolidParticleSystem.prototype.beforeUpdateParticles = function (start, stop, update) {
  1188. };
  1189. /**
  1190. * This will be called by `setParticles()` after all the other treatments and just before the actual mesh update.
  1191. * This will be passed three parameters.
  1192. * This does nothing and may be overwritten by the user.
  1193. * @param start the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()
  1194. * @param stop the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()
  1195. * @param update the boolean update value actually passed to setParticles()
  1196. */
  1197. SolidParticleSystem.prototype.afterUpdateParticles = function (start, stop, update) {
  1198. };
  1199. return SolidParticleSystem;
  1200. }());
  1201. BABYLON.SolidParticleSystem = SolidParticleSystem;
  1202. })(BABYLON || (BABYLON = {}));
  1203. //# sourceMappingURL=babylon.solidParticleSystem.js.map
  1204. 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}";
  1205. 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}";
  1206. BABYLON.Effect.IncludesShadersStore['depthPrePass'] = "#ifdef DEPTHPREPASS\ngl_FragColor=vec4(0.,0.,0.,1.0);\nreturn;\n#endif";
  1207. 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";
  1208. 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";
  1209. BABYLON.Effect.IncludesShadersStore['pointCloudVertexDeclaration'] = "#ifdef POINTSIZE\nuniform float pointSize;\n#endif";
  1210. BABYLON.Effect.IncludesShadersStore['bumpVertexDeclaration'] = "#if defined(BUMP) || defined(PARALLAX)\n#if defined(TANGENT) && defined(NORMAL) \nvarying mat3 vTBN;\n#endif\n#endif\n";
  1211. BABYLON.Effect.IncludesShadersStore['clipPlaneVertexDeclaration'] = "#ifdef CLIPPLANE\nuniform vec4 vClipPlane;\nvarying float fClipDistance;\n#endif";
  1212. BABYLON.Effect.IncludesShadersStore['fogVertexDeclaration'] = "#ifdef FOG\nvarying vec3 vFogDistance;\n#endif";
  1213. BABYLON.Effect.IncludesShadersStore['morphTargetsVertexGlobalDeclaration'] = "#ifdef MORPHTARGETS\nuniform float morphTargetInfluences[NUM_MORPH_INFLUENCERS];\n#endif";
  1214. 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";
  1215. BABYLON.Effect.IncludesShadersStore['logDepthDeclaration'] = "#ifdef LOGARITHMICDEPTH\nuniform float logarithmicDepthConstant;\nvarying float vFragmentDepth;\n#endif";
  1216. 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";
  1217. BABYLON.Effect.IncludesShadersStore['instancesVertex'] = "#ifdef INSTANCES\nmat4 finalWorld=mat4(world0,world1,world2,world3);\n#else\nmat4 finalWorld=world;\n#endif";
  1218. 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";
  1219. 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";
  1220. BABYLON.Effect.IncludesShadersStore['clipPlaneVertex'] = "#ifdef CLIPPLANE\nfClipDistance=dot(worldPos,vClipPlane);\n#endif";
  1221. BABYLON.Effect.IncludesShadersStore['fogVertex'] = "#ifdef FOG\nvFogDistance=(view*worldPos).xyz;\n#endif";
  1222. 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";
  1223. BABYLON.Effect.IncludesShadersStore['pointCloudVertex'] = "#ifdef POINTSIZE\ngl_PointSize=pointSize;\n#endif";
  1224. BABYLON.Effect.IncludesShadersStore['logDepthVertex'] = "#ifdef LOGARITHMICDEPTH\nvFragmentDepth=1.0+gl_Position.w;\ngl_Position.z=log2(max(0.000001,vFragmentDepth))*logarithmicDepthConstant;\n#endif";
  1225. 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}";
  1226. 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";
  1227. 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";
  1228. 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";
  1229. 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";
  1230. 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";
  1231. 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};";
  1232. 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";
  1233. 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";
  1234. 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}";
  1235. 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";
  1236. 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}";
  1237. 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";
  1238. BABYLON.Effect.IncludesShadersStore['clipPlaneFragmentDeclaration'] = "#ifdef CLIPPLANE\nvarying float fClipDistance;\n#endif";
  1239. 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";
  1240. BABYLON.Effect.IncludesShadersStore['clipPlaneFragment'] = "#ifdef CLIPPLANE\nif (fClipDistance>0.0)\n{\ndiscard;\n}\n#endif";
  1241. 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";
  1242. 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";
  1243. BABYLON.Effect.IncludesShadersStore['logDepthFragment'] = "#ifdef LOGARITHMICDEPTH\ngl_FragDepthEXT=log2(vFragmentDepth)*logarithmicDepthConstant*0.5;\n#endif";
  1244. BABYLON.Effect.IncludesShadersStore['fogFragment'] = "#ifdef FOG\nfloat fog=CalcFogFactor();\ncolor.rgb=fog*color.rgb+(1.0-fog)*vFogColor;\n#endif";
  1245. (function() {
  1246. var EXPORTS = {};EXPORTS['SolidParticle'] = BABYLON['SolidParticle'];EXPORTS['ModelShape'] = BABYLON['ModelShape'];EXPORTS['DepthSortedParticle'] = BABYLON['DepthSortedParticle'];EXPORTS['SolidParticleSystem'] = BABYLON['SolidParticleSystem'];
  1247. globalObject["BABYLON"] = globalObject["BABYLON"] || BABYLON;
  1248. module.exports = EXPORTS;
  1249. })();
  1250. }