babylon.shaderMaterial.js 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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. __.prototype = b.prototype;
  5. d.prototype = new __();
  6. };
  7. var BABYLON;
  8. (function (BABYLON) {
  9. var ShaderMaterial = (function (_super) {
  10. __extends(ShaderMaterial, _super);
  11. function ShaderMaterial(name, scene, shaderPath, options) {
  12. _super.call(this, name, scene);
  13. this._textures = new Array();
  14. this._floats = new Array();
  15. this._floatsArrays = {};
  16. this._colors3 = new Array();
  17. this._colors4 = new Array();
  18. this._vectors2 = new Array();
  19. this._vectors3 = new Array();
  20. this._vectors4 = new Array();
  21. this._matrices = new Array();
  22. this._matrices3x3 = new Array();
  23. this._matrices2x2 = new Array();
  24. this._cachedWorldViewMatrix = new BABYLON.Matrix();
  25. this._shaderPath = shaderPath;
  26. options.needAlphaBlending = options.needAlphaBlending || false;
  27. options.needAlphaTesting = options.needAlphaTesting || false;
  28. options.attributes = options.attributes || ["position", "normal", "uv"];
  29. options.uniforms = options.uniforms || ["worldViewProjection"];
  30. options.samplers = options.samplers || [];
  31. this._options = options;
  32. }
  33. ShaderMaterial.prototype.needAlphaBlending = function () {
  34. return this._options.needAlphaBlending;
  35. };
  36. ShaderMaterial.prototype.needAlphaTesting = function () {
  37. return this._options.needAlphaTesting;
  38. };
  39. ShaderMaterial.prototype._checkUniform = function (uniformName) {
  40. if (this._options.uniforms.indexOf(uniformName) === -1) {
  41. this._options.uniforms.push(uniformName);
  42. }
  43. };
  44. ShaderMaterial.prototype.setTexture = function (name, texture) {
  45. if (this._options.samplers.indexOf(name) === -1) {
  46. this._options.samplers.push(name);
  47. }
  48. this._textures[name] = texture;
  49. return this;
  50. };
  51. ShaderMaterial.prototype.setFloat = function (name, value) {
  52. this._checkUniform(name);
  53. this._floats[name] = value;
  54. return this;
  55. };
  56. ShaderMaterial.prototype.setFloats = function (name, value) {
  57. this._checkUniform(name);
  58. this._floatsArrays[name] = value;
  59. return this;
  60. };
  61. ShaderMaterial.prototype.setColor3 = function (name, value) {
  62. this._checkUniform(name);
  63. this._colors3[name] = value;
  64. return this;
  65. };
  66. ShaderMaterial.prototype.setColor4 = function (name, value) {
  67. this._checkUniform(name);
  68. this._colors4[name] = value;
  69. return this;
  70. };
  71. ShaderMaterial.prototype.setVector2 = function (name, value) {
  72. this._checkUniform(name);
  73. this._vectors2[name] = value;
  74. return this;
  75. };
  76. ShaderMaterial.prototype.setVector3 = function (name, value) {
  77. this._checkUniform(name);
  78. this._vectors3[name] = value;
  79. return this;
  80. };
  81. ShaderMaterial.prototype.setVector4 = function (name, value) {
  82. this._checkUniform(name);
  83. this._vectors4[name] = value;
  84. return this;
  85. };
  86. ShaderMaterial.prototype.setMatrix = function (name, value) {
  87. this._checkUniform(name);
  88. this._matrices[name] = value;
  89. return this;
  90. };
  91. ShaderMaterial.prototype.setMatrix3x3 = function (name, value) {
  92. this._checkUniform(name);
  93. this._matrices3x3[name] = value;
  94. return this;
  95. };
  96. ShaderMaterial.prototype.setMatrix2x2 = function (name, value) {
  97. this._checkUniform(name);
  98. this._matrices2x2[name] = value;
  99. return this;
  100. };
  101. ShaderMaterial.prototype.isReady = function (mesh, useInstances) {
  102. var scene = this.getScene();
  103. var engine = scene.getEngine();
  104. if (!this.checkReadyOnEveryCall) {
  105. if (this._renderId === scene.getRenderId()) {
  106. return true;
  107. }
  108. }
  109. // Instances
  110. var defines = [];
  111. var fallbacks = new BABYLON.EffectFallbacks();
  112. if (useInstances) {
  113. defines.push("#define INSTANCES");
  114. }
  115. // Bones
  116. if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
  117. defines.push("#define BONES");
  118. defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
  119. defines.push("#define BONES4");
  120. fallbacks.addFallback(0, "BONES4");
  121. }
  122. // Alpha test
  123. if (engine.getAlphaTesting()) {
  124. defines.push("#define ALPHATEST");
  125. }
  126. var previousEffect = this._effect;
  127. var join = defines.join("\n");
  128. this._effect = engine.createEffect(this._shaderPath, this._options.attributes, this._options.uniforms, this._options.samplers, join, fallbacks, this.onCompiled, this.onError);
  129. if (!this._effect.isReady()) {
  130. return false;
  131. }
  132. if (previousEffect !== this._effect) {
  133. scene.resetCachedMaterial();
  134. }
  135. this._renderId = scene.getRenderId();
  136. return true;
  137. };
  138. ShaderMaterial.prototype.bindOnlyWorldMatrix = function (world) {
  139. var scene = this.getScene();
  140. if (this._options.uniforms.indexOf("world") !== -1) {
  141. this._effect.setMatrix("world", world);
  142. }
  143. if (this._options.uniforms.indexOf("worldView") !== -1) {
  144. world.multiplyToRef(scene.getViewMatrix(), this._cachedWorldViewMatrix);
  145. this._effect.setMatrix("worldView", this._cachedWorldViewMatrix);
  146. }
  147. if (this._options.uniforms.indexOf("worldViewProjection") !== -1) {
  148. this._effect.setMatrix("worldViewProjection", world.multiply(scene.getTransformMatrix()));
  149. }
  150. };
  151. ShaderMaterial.prototype.bind = function (world, mesh) {
  152. // Std values
  153. this.bindOnlyWorldMatrix(world);
  154. if (this.getScene().getCachedMaterial() !== this) {
  155. if (this._options.uniforms.indexOf("view") !== -1) {
  156. this._effect.setMatrix("view", this.getScene().getViewMatrix());
  157. }
  158. if (this._options.uniforms.indexOf("projection") !== -1) {
  159. this._effect.setMatrix("projection", this.getScene().getProjectionMatrix());
  160. }
  161. if (this._options.uniforms.indexOf("viewProjection") !== -1) {
  162. this._effect.setMatrix("viewProjection", this.getScene().getTransformMatrix());
  163. }
  164. // Bones
  165. if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
  166. this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
  167. }
  168. // Texture
  169. for (var name in this._textures) {
  170. this._effect.setTexture(name, this._textures[name]);
  171. }
  172. // Float
  173. for (name in this._floats) {
  174. this._effect.setFloat(name, this._floats[name]);
  175. }
  176. // Float s
  177. for (name in this._floatsArrays) {
  178. this._effect.setArray(name, this._floatsArrays[name]);
  179. }
  180. // Color3
  181. for (name in this._colors3) {
  182. this._effect.setColor3(name, this._colors3[name]);
  183. }
  184. // Color4
  185. for (name in this._colors4) {
  186. var color = this._colors4[name];
  187. this._effect.setFloat4(name, color.r, color.g, color.b, color.a);
  188. }
  189. // Vector2
  190. for (name in this._vectors2) {
  191. this._effect.setVector2(name, this._vectors2[name]);
  192. }
  193. // Vector3
  194. for (name in this._vectors3) {
  195. this._effect.setVector3(name, this._vectors3[name]);
  196. }
  197. // Vector4
  198. for (name in this._vectors4) {
  199. this._effect.setVector4(name, this._vectors4[name]);
  200. }
  201. // Matrix
  202. for (name in this._matrices) {
  203. this._effect.setMatrix(name, this._matrices[name]);
  204. }
  205. // Matrix 3x3
  206. for (name in this._matrices3x3) {
  207. this._effect.setMatrix3x3(name, this._matrices3x3[name]);
  208. }
  209. // Matrix 2x2
  210. for (name in this._matrices2x2) {
  211. this._effect.setMatrix2x2(name, this._matrices2x2[name]);
  212. }
  213. }
  214. _super.prototype.bind.call(this, world, mesh);
  215. };
  216. ShaderMaterial.prototype.clone = function (name) {
  217. var newShaderMaterial = new ShaderMaterial(name, this.getScene(), this._shaderPath, this._options);
  218. return newShaderMaterial;
  219. };
  220. ShaderMaterial.prototype.dispose = function (forceDisposeEffect) {
  221. for (var name in this._textures) {
  222. this._textures[name].dispose();
  223. }
  224. this._textures = [];
  225. _super.prototype.dispose.call(this, forceDisposeEffect);
  226. };
  227. return ShaderMaterial;
  228. })(BABYLON.Material);
  229. BABYLON.ShaderMaterial = ShaderMaterial;
  230. })(BABYLON || (BABYLON = {}));