babylon.shaderMaterial.ts 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. module BABYLON {
  2. export class ShaderMaterial extends Material {
  3. private _shaderPath: string;
  4. private _options: any;
  5. private _textures = new Array<Texture>();
  6. private _floats = new Array<number>();
  7. private _floatsArrays = {};
  8. private _colors3 = new Array<Color3>();
  9. private _colors4 = new Array<Color4>();
  10. private _vectors2 = new Array<Vector2>();
  11. private _vectors3 = new Array<Vector3>();
  12. private _matrices = new Array<Matrix>();
  13. private _cachedWorldViewMatrix = new BABYLON.Matrix();
  14. constructor(name: string, scene: Scene, shaderPath: string, options) {
  15. super(name, scene);
  16. this._shaderPath = shaderPath;
  17. options.needAlphaBlending = options.needAlphaBlending || false;
  18. options.needAlphaTesting = options.needAlphaTesting || false;
  19. options.attributes = options.attributes || ["position", "normal", "uv"];
  20. options.uniforms = options.uniforms || ["worldViewProjection"];
  21. options.samplers = options.samplers || [];
  22. this._options = options;
  23. }
  24. public needAlphaBlending(): boolean {
  25. return this._options.needAlphaBlending;
  26. }
  27. public needAlphaTesting(): boolean {
  28. return this._options.needAlphaTesting;
  29. }
  30. private _checkUniform(uniformName): void {
  31. if (this._options.uniforms.indexOf(uniformName) === -1) {
  32. this._options.uniforms.push(uniformName);
  33. }
  34. }
  35. public setTexture(name: string, texture: Texture): ShaderMaterial {
  36. if (this._options.samplers.indexOf(name) === -1) {
  37. this._options.samplers.push(name);
  38. }
  39. this._textures[name] = texture;
  40. return this;
  41. }
  42. public setFloat(name: string, value: number): ShaderMaterial {
  43. this._checkUniform(name);
  44. this._floats[name] = value;
  45. return this;
  46. }
  47. public setFloats(name: string, value: number[]): ShaderMaterial {
  48. this._checkUniform(name);
  49. this._floatsArrays[name] = value;
  50. return this;
  51. }
  52. public setColor3(name: string, value: Color3): ShaderMaterial {
  53. this._checkUniform(name);
  54. this._colors3[name] = value;
  55. return this;
  56. }
  57. public setColor4(name: string, value: Color4): ShaderMaterial {
  58. this._checkUniform(name);
  59. this._colors4[name] = value;
  60. return this;
  61. }
  62. public setVector2(name: string, value: Vector2): ShaderMaterial {
  63. this._checkUniform(name);
  64. this._vectors2[name] = value;
  65. return this;
  66. }
  67. public setVector3(name: string, value: Vector3): ShaderMaterial {
  68. this._checkUniform(name);
  69. this._vectors3[name] = value;
  70. return this;
  71. }
  72. public setMatrix(name: string, value: Matrix): ShaderMaterial {
  73. this._checkUniform(name);
  74. this._matrices[name] = value;
  75. return this;
  76. }
  77. public isReady(mesh?: Mesh): boolean {
  78. var engine = this.getScene().getEngine();
  79. this._effect = engine.createEffect(this._shaderPath,
  80. this._options.attributes,
  81. this._options.uniforms,
  82. this._options.samplers,
  83. "", null, this.onCompiled, this.onError);
  84. if (!this._effect.isReady()) {
  85. return false;
  86. }
  87. return true;
  88. }
  89. public bind(world: Matrix, mesh: Mesh): void {
  90. // Std values
  91. if (this._options.uniforms.indexOf("world") !== -1) {
  92. this._effect.setMatrix("world", world);
  93. }
  94. if (this._options.uniforms.indexOf("view") !== -1) {
  95. this._effect.setMatrix("view", this.getScene().getViewMatrix());
  96. }
  97. if (this._options.uniforms.indexOf("worldView") !== -1) {
  98. world.multiplyToRef(this.getScene().getViewMatrix(), this._cachedWorldViewMatrix);
  99. this._effect.setMatrix("worldView", this._cachedWorldViewMatrix);
  100. }
  101. if (this._options.uniforms.indexOf("projection") !== -1) {
  102. this._effect.setMatrix("projection", this.getScene().getProjectionMatrix());
  103. }
  104. if (this._options.uniforms.indexOf("worldViewProjection") !== -1) {
  105. this._effect.setMatrix("worldViewProjection", world.multiply(this.getScene().getTransformMatrix()));
  106. }
  107. // Texture
  108. for (var name in this._textures) {
  109. this._effect.setTexture(name, this._textures[name]);
  110. }
  111. // Float
  112. for (name in this._floats) {
  113. this._effect.setFloat(name, this._floats[name]);
  114. }
  115. // Float s
  116. for (name in this._floatsArrays) {
  117. this._effect.setArray(name, this._floatsArrays[name]);
  118. }
  119. // Color3
  120. for (name in this._colors3) {
  121. this._effect.setColor3(name, this._colors3[name]);
  122. }
  123. // Color4
  124. for (name in this._colors4) {
  125. var color = this._colors4[name];
  126. this._effect.setFloat4(name, color.r, color.g, color.b, color.a);
  127. }
  128. // Vector2
  129. for (name in this._vectors2) {
  130. this._effect.setVector2(name, this._vectors2[name]);
  131. }
  132. // Vector3
  133. for (name in this._vectors3) {
  134. this._effect.setVector3(name, this._vectors3[name]);
  135. }
  136. // Matrix
  137. for (name in this._matrices) {
  138. this._effect.setMatrix(name, this._matrices[name]);
  139. }
  140. }
  141. public dispose(forceDisposeEffect?: boolean): void {
  142. for (var name in this._textures) {
  143. this._textures[name].dispose();
  144. }
  145. this._textures = [];
  146. super.dispose(forceDisposeEffect);
  147. }
  148. }
  149. }