babylon.shaderMaterial.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. var __extends = (this && this.__extends) || function (d, b) {
  2. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  3. function __() { this.constructor = d; }
  4. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  5. };
  6. var BABYLON;
  7. (function (BABYLON) {
  8. var ShaderMaterial = (function (_super) {
  9. __extends(ShaderMaterial, _super);
  10. function ShaderMaterial(name, scene, shaderPath, options) {
  11. _super.call(this, name, scene);
  12. this._textures = {};
  13. this._textureArrays = {};
  14. this._floats = {};
  15. this._floatsArrays = {};
  16. this._colors3 = {};
  17. this._colors4 = {};
  18. this._vectors2 = {};
  19. this._vectors3 = {};
  20. this._vectors4 = {};
  21. this._matrices = {};
  22. this._matrices3x3 = {};
  23. this._matrices2x2 = {};
  24. this._vectors3Arrays = {};
  25. this._cachedWorldViewMatrix = new BABYLON.Matrix();
  26. this._shaderPath = shaderPath;
  27. options.needAlphaBlending = options.needAlphaBlending || false;
  28. options.needAlphaTesting = options.needAlphaTesting || false;
  29. options.attributes = options.attributes || ["position", "normal", "uv"];
  30. options.uniforms = options.uniforms || ["worldViewProjection"];
  31. options.samplers = options.samplers || [];
  32. options.defines = options.defines || [];
  33. this._options = options;
  34. }
  35. ShaderMaterial.prototype.needAlphaBlending = function () {
  36. return this._options.needAlphaBlending;
  37. };
  38. ShaderMaterial.prototype.needAlphaTesting = function () {
  39. return this._options.needAlphaTesting;
  40. };
  41. ShaderMaterial.prototype._checkUniform = function (uniformName) {
  42. if (this._options.uniforms.indexOf(uniformName) === -1) {
  43. this._options.uniforms.push(uniformName);
  44. }
  45. };
  46. ShaderMaterial.prototype.setTexture = function (name, texture) {
  47. if (this._options.samplers.indexOf(name) === -1) {
  48. this._options.samplers.push(name);
  49. }
  50. this._textures[name] = texture;
  51. return this;
  52. };
  53. ShaderMaterial.prototype.setTextureArray = function (name, textures) {
  54. if (this._options.samplers.indexOf(name) === -1) {
  55. this._options.samplers.push(name);
  56. }
  57. this._checkUniform(name);
  58. this._textureArrays[name] = textures;
  59. return this;
  60. };
  61. ShaderMaterial.prototype.setFloat = function (name, value) {
  62. this._checkUniform(name);
  63. this._floats[name] = value;
  64. return this;
  65. };
  66. ShaderMaterial.prototype.setFloats = function (name, value) {
  67. this._checkUniform(name);
  68. this._floatsArrays[name] = value;
  69. return this;
  70. };
  71. ShaderMaterial.prototype.setColor3 = function (name, value) {
  72. this._checkUniform(name);
  73. this._colors3[name] = value;
  74. return this;
  75. };
  76. ShaderMaterial.prototype.setColor4 = function (name, value) {
  77. this._checkUniform(name);
  78. this._colors4[name] = value;
  79. return this;
  80. };
  81. ShaderMaterial.prototype.setVector2 = function (name, value) {
  82. this._checkUniform(name);
  83. this._vectors2[name] = value;
  84. return this;
  85. };
  86. ShaderMaterial.prototype.setVector3 = function (name, value) {
  87. this._checkUniform(name);
  88. this._vectors3[name] = value;
  89. return this;
  90. };
  91. ShaderMaterial.prototype.setVector4 = function (name, value) {
  92. this._checkUniform(name);
  93. this._vectors4[name] = value;
  94. return this;
  95. };
  96. ShaderMaterial.prototype.setMatrix = function (name, value) {
  97. this._checkUniform(name);
  98. this._matrices[name] = value;
  99. return this;
  100. };
  101. ShaderMaterial.prototype.setMatrix3x3 = function (name, value) {
  102. this._checkUniform(name);
  103. this._matrices3x3[name] = value;
  104. return this;
  105. };
  106. ShaderMaterial.prototype.setMatrix2x2 = function (name, value) {
  107. this._checkUniform(name);
  108. this._matrices2x2[name] = value;
  109. return this;
  110. };
  111. ShaderMaterial.prototype.setArray3 = function (name, value) {
  112. this._checkUniform(name);
  113. this._vectors3Arrays[name] = value;
  114. return this;
  115. };
  116. ShaderMaterial.prototype.isReady = function (mesh, useInstances) {
  117. var scene = this.getScene();
  118. var engine = scene.getEngine();
  119. if (!this.checkReadyOnEveryCall) {
  120. if (this._renderId === scene.getRenderId()) {
  121. return true;
  122. }
  123. }
  124. // Instances
  125. var defines = [];
  126. var fallbacks = new BABYLON.EffectFallbacks();
  127. if (useInstances) {
  128. defines.push("#define INSTANCES");
  129. }
  130. for (var index = 0; index < this._options.defines.length; index++) {
  131. defines.push(this._options.defines[index]);
  132. }
  133. // Bones
  134. if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
  135. defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
  136. defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
  137. fallbacks.addCPUSkinningFallback(0, mesh);
  138. }
  139. // Alpha test
  140. if (engine.getAlphaTesting()) {
  141. defines.push("#define ALPHATEST");
  142. }
  143. var previousEffect = this._effect;
  144. var join = defines.join("\n");
  145. this._effect = engine.createEffect(this._shaderPath, this._options.attributes, this._options.uniforms, this._options.samplers, join, fallbacks, this.onCompiled, this.onError);
  146. if (!this._effect.isReady()) {
  147. return false;
  148. }
  149. if (previousEffect !== this._effect) {
  150. scene.resetCachedMaterial();
  151. }
  152. this._renderId = scene.getRenderId();
  153. return true;
  154. };
  155. ShaderMaterial.prototype.bindOnlyWorldMatrix = function (world) {
  156. var scene = this.getScene();
  157. if (this._options.uniforms.indexOf("world") !== -1) {
  158. this._effect.setMatrix("world", world);
  159. }
  160. if (this._options.uniforms.indexOf("worldView") !== -1) {
  161. world.multiplyToRef(scene.getViewMatrix(), this._cachedWorldViewMatrix);
  162. this._effect.setMatrix("worldView", this._cachedWorldViewMatrix);
  163. }
  164. if (this._options.uniforms.indexOf("worldViewProjection") !== -1) {
  165. this._effect.setMatrix("worldViewProjection", world.multiply(scene.getTransformMatrix()));
  166. }
  167. };
  168. ShaderMaterial.prototype.bind = function (world, mesh) {
  169. // Std values
  170. this.bindOnlyWorldMatrix(world);
  171. if (this.getScene().getCachedMaterial() !== this) {
  172. if (this._options.uniforms.indexOf("view") !== -1) {
  173. this._effect.setMatrix("view", this.getScene().getViewMatrix());
  174. }
  175. if (this._options.uniforms.indexOf("projection") !== -1) {
  176. this._effect.setMatrix("projection", this.getScene().getProjectionMatrix());
  177. }
  178. if (this._options.uniforms.indexOf("viewProjection") !== -1) {
  179. this._effect.setMatrix("viewProjection", this.getScene().getTransformMatrix());
  180. }
  181. // Bones
  182. BABYLON.MaterialHelper.BindBonesParameters(mesh, this._effect);
  183. var name;
  184. // Texture
  185. for (name in this._textures) {
  186. this._effect.setTexture(name, this._textures[name]);
  187. }
  188. // Texture arrays
  189. for (name in this._textureArrays) {
  190. this._effect.setTextureArray(name, this._textureArrays[name]);
  191. }
  192. // Float
  193. for (name in this._floats) {
  194. this._effect.setFloat(name, this._floats[name]);
  195. }
  196. // Float s
  197. for (name in this._floatsArrays) {
  198. this._effect.setArray(name, this._floatsArrays[name]);
  199. }
  200. // Color3
  201. for (name in this._colors3) {
  202. this._effect.setColor3(name, this._colors3[name]);
  203. }
  204. // Color4
  205. for (name in this._colors4) {
  206. var color = this._colors4[name];
  207. this._effect.setFloat4(name, color.r, color.g, color.b, color.a);
  208. }
  209. // Vector2
  210. for (name in this._vectors2) {
  211. this._effect.setVector2(name, this._vectors2[name]);
  212. }
  213. // Vector3
  214. for (name in this._vectors3) {
  215. this._effect.setVector3(name, this._vectors3[name]);
  216. }
  217. // Vector4
  218. for (name in this._vectors4) {
  219. this._effect.setVector4(name, this._vectors4[name]);
  220. }
  221. // Matrix
  222. for (name in this._matrices) {
  223. this._effect.setMatrix(name, this._matrices[name]);
  224. }
  225. // Matrix 3x3
  226. for (name in this._matrices3x3) {
  227. this._effect.setMatrix3x3(name, this._matrices3x3[name]);
  228. }
  229. // Matrix 2x2
  230. for (name in this._matrices2x2) {
  231. this._effect.setMatrix2x2(name, this._matrices2x2[name]);
  232. }
  233. // Vector3Array
  234. for (name in this._vectors3Arrays) {
  235. this._effect.setArray3(name, this._vectors3Arrays[name]);
  236. }
  237. }
  238. _super.prototype.bind.call(this, world, mesh);
  239. };
  240. ShaderMaterial.prototype.clone = function (name) {
  241. var newShaderMaterial = new ShaderMaterial(name, this.getScene(), this._shaderPath, this._options);
  242. return newShaderMaterial;
  243. };
  244. ShaderMaterial.prototype.dispose = function (forceDisposeEffect, forceDisposeTextures) {
  245. if (forceDisposeTextures) {
  246. var name;
  247. for (name in this._textures) {
  248. this._textures[name].dispose();
  249. }
  250. for (name in this._textureArrays) {
  251. var array = this._textureArrays[name];
  252. for (var index = 0; index < array.length; index++) {
  253. array[index].dispose();
  254. }
  255. }
  256. }
  257. this._textures = {};
  258. _super.prototype.dispose.call(this, forceDisposeEffect, forceDisposeTextures);
  259. };
  260. ShaderMaterial.prototype.serialize = function () {
  261. var serializationObject = BABYLON.SerializationHelper.Serialize(this);
  262. serializationObject.customType = "BABYLON.ShaderMaterial";
  263. serializationObject.options = this._options;
  264. serializationObject.shaderPath = this._shaderPath;
  265. var name;
  266. // Texture
  267. serializationObject.textures = {};
  268. for (name in this._textures) {
  269. serializationObject.textures[name] = this._textures[name].serialize();
  270. }
  271. // Texture arrays
  272. serializationObject.textureArrays = {};
  273. for (name in this._textureArrays) {
  274. serializationObject.textureArrays[name] = [];
  275. var array = this._textureArrays[name];
  276. for (var index = 0; index < array.length; index++) {
  277. serializationObject.textureArrays[name].push(array[index].serialize());
  278. }
  279. }
  280. // Float
  281. serializationObject.floats = {};
  282. for (name in this._floats) {
  283. serializationObject.floats[name] = this._floats[name];
  284. }
  285. // Float s
  286. serializationObject.floatArrays = {};
  287. for (name in this._floatsArrays) {
  288. serializationObject.floatArrays[name] = this._floatsArrays[name];
  289. }
  290. // Color3
  291. serializationObject.colors3 = {};
  292. for (name in this._colors3) {
  293. serializationObject.colors3[name] = this._colors3[name].asArray();
  294. }
  295. // Color4
  296. serializationObject.colors4 = {};
  297. for (name in this._colors4) {
  298. serializationObject.colors4[name] = this._colors4[name].asArray();
  299. }
  300. // Vector2
  301. serializationObject.vectors2 = {};
  302. for (name in this._vectors2) {
  303. serializationObject.vectors2[name] = this._vectors2[name].asArray();
  304. }
  305. // Vector3
  306. serializationObject.vectors3 = {};
  307. for (name in this._vectors3) {
  308. serializationObject.vectors3[name] = this._vectors3[name].asArray();
  309. }
  310. // Vector4
  311. serializationObject.vectors4 = {};
  312. for (name in this._vectors4) {
  313. serializationObject.vectors4[name] = this._vectors4[name].asArray();
  314. }
  315. // Matrix
  316. serializationObject.matrices = {};
  317. for (name in this._matrices) {
  318. serializationObject.matrices[name] = this._matrices[name].asArray();
  319. }
  320. // Matrix 3x3
  321. serializationObject.matrices3x3 = {};
  322. for (name in this._matrices3x3) {
  323. serializationObject.matrices3x3[name] = this._matrices3x3[name];
  324. }
  325. // Matrix 2x2
  326. serializationObject.matrices2x2 = {};
  327. for (name in this._matrices2x2) {
  328. serializationObject.matrices2x2[name] = this._matrices2x2[name];
  329. }
  330. // Vector3Array
  331. serializationObject.vectors3Arrays = {};
  332. for (name in this._vectors3Arrays) {
  333. serializationObject.vectors3Arrays[name] = this._vectors3Arrays[name];
  334. }
  335. return serializationObject;
  336. };
  337. ShaderMaterial.Parse = function (source, scene, rootUrl) {
  338. var material = BABYLON.SerializationHelper.Parse(function () { return new ShaderMaterial(source.name, scene, source.shaderPath, source.options); }, source, scene, rootUrl);
  339. var name;
  340. // Texture
  341. for (name in source.textures) {
  342. material.setTexture(name, BABYLON.Texture.Parse(source.textures[name], scene, rootUrl));
  343. }
  344. // Texture arrays
  345. for (name in source.textureArrays) {
  346. var array = source.textureArrays[name];
  347. var textureArray = new Array();
  348. for (var index = 0; index < array.length; index++) {
  349. textureArray.push(BABYLON.Texture.Parse(array[index], scene, rootUrl));
  350. }
  351. material.setTextureArray(name, textureArray);
  352. }
  353. // Float
  354. for (name in source.floats) {
  355. material.setFloat(name, source.floats[name]);
  356. }
  357. // Float s
  358. for (name in source.floatsArrays) {
  359. material.setFloats(name, source.floatsArrays[name]);
  360. }
  361. // Color3
  362. for (name in source.colors3) {
  363. material.setColor3(name, BABYLON.Color3.FromArray(source.colors3[name]));
  364. }
  365. // Color4
  366. for (name in source.colors4) {
  367. material.setColor4(name, BABYLON.Color4.FromArray(source.colors4[name]));
  368. }
  369. // Vector2
  370. for (name in source.vectors2) {
  371. material.setVector2(name, BABYLON.Vector2.FromArray(source.vectors2[name]));
  372. }
  373. // Vector3
  374. for (name in source.vectors3) {
  375. material.setVector3(name, BABYLON.Vector3.FromArray(source.vectors3[name]));
  376. }
  377. // Vector4
  378. for (name in source.vectors4) {
  379. material.setVector4(name, BABYLON.Vector4.FromArray(source.vectors4[name]));
  380. }
  381. // Matrix
  382. for (name in source.matrices) {
  383. material.setMatrix(name, BABYLON.Matrix.FromArray(source.matrices[name]));
  384. }
  385. // Matrix 3x3
  386. for (name in source.matrices3x3) {
  387. material.setMatrix3x3(name, source.matrices3x3[name]);
  388. }
  389. // Matrix 2x2
  390. for (name in source.matrices2x2) {
  391. material.setMatrix2x2(name, source.matrices2x2[name]);
  392. }
  393. // Vector3Array
  394. for (name in source.vectors3Arrays) {
  395. material.setArray3(name, source.vectors3Arrays[name]);
  396. }
  397. return material;
  398. };
  399. return ShaderMaterial;
  400. }(BABYLON.Material));
  401. BABYLON.ShaderMaterial = ShaderMaterial;
  402. })(BABYLON || (BABYLON = {}));