babylon.customMaterial.ts 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /// <reference path="../../../dist/preview release/babylon.d.ts"/>
  2. module BABYLON {
  3. export class CustomShaderStructure {
  4. public FragmentStore: string;
  5. public VertexStore: string;
  6. constructor() { }
  7. }
  8. export class ShaderSpecialParts {
  9. constructor() { }
  10. public Fragment_Begin: string;
  11. public Fragment_Definitions: string;
  12. public Fragment_MainBegin: string;
  13. // diffuseColor
  14. public Fragment_Custom_Diffuse: string;
  15. // alpha
  16. public Fragment_Custom_Alpha: string;
  17. public Fragment_Before_FragColor: string;
  18. public Vertex_Begin: string;
  19. public Vertex_Definitions: string;
  20. public Vertex_MainBegin: string;
  21. // positionUpdated
  22. public Vertex_Before_PositionUpdated: string;
  23. // normalUpdated
  24. public Vertex_Before_NormalUpdated: string;
  25. }
  26. export class CustomMaterial extends StandardMaterial {
  27. public static ShaderIndexer = 1;
  28. public CustomParts: ShaderSpecialParts;
  29. _isCreatedShader: boolean;
  30. _createdShaderName: string;
  31. _customUniform: string[];
  32. _newUniforms: string[];
  33. _newUniformInstances: any[];
  34. _newSamplerInstances: Texture[];
  35. public FragmentShader : string ;
  36. public VertexShader : string ;
  37. public AttachAfterBind(mesh: Mesh, effect: Effect) {
  38. for (var el in this._newUniformInstances) {
  39. var ea = el.toString().split('-');
  40. if (ea[0] == 'vec2') {
  41. effect.setVector2(ea[1], this._newUniformInstances[el]);
  42. }
  43. else if (ea[0] == 'vec3') {
  44. effect.setVector3(ea[1], this._newUniformInstances[el]);
  45. }
  46. else if (ea[0] == 'vec4') {
  47. effect.setVector4(ea[1], this._newUniformInstances[el]);
  48. }
  49. else if (ea[0] == 'mat4') {
  50. effect.setMatrix(ea[1], this._newUniformInstances[el]);
  51. }
  52. else if (ea[0] == 'float') {
  53. effect.setFloat(ea[1], this._newUniformInstances[el]);
  54. }
  55. }
  56. for (var el in this._newSamplerInstances) {
  57. var ea = el.toString().split('-');
  58. if (ea[0] == 'sampler2D' && this._newSamplerInstances[el].isReady && this._newSamplerInstances[el].isReady()) {
  59. effect.setTexture(ea[1], this._newSamplerInstances[el]);
  60. }
  61. }
  62. }
  63. public ReviewUniform(name: string, arr: string[]): string[] {
  64. if (name == "uniform") {
  65. for (var ind in this._newUniforms) {
  66. if (this._customUniform[ind].indexOf('sampler') == -1) {
  67. arr.push(this._newUniforms[ind]);
  68. }
  69. }
  70. }
  71. if (name == "sampler") {
  72. for (var ind in this._newUniforms) {
  73. if (this._customUniform[ind].indexOf('sampler') != -1) {
  74. arr.push(this._newUniforms[ind]);
  75. }
  76. }
  77. }
  78. return arr;
  79. }
  80. public Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines): string {
  81. if (this._isCreatedShader) {
  82. return this._createdShaderName;
  83. }
  84. this._isCreatedShader = false;
  85. CustomMaterial.ShaderIndexer++;
  86. var name: string = "custom_" + CustomMaterial.ShaderIndexer;
  87. this.ReviewUniform("uniform", uniforms);
  88. this.ReviewUniform("sampler", samplers);
  89. var fn_afterBind = this._afterBind.bind(this);
  90. this._afterBind = (m, e) => {
  91. if (!e) {
  92. return;
  93. }
  94. this.AttachAfterBind(m, e);
  95. try { fn_afterBind(m, e); }
  96. catch (e) { }
  97. };
  98. BABYLON.Effect.ShadersStore[name + "VertexShader"] = this.VertexShader
  99. .replace('#define CUSTOM_VERTEX_BEGIN', (this.CustomParts.Vertex_Begin ? this.CustomParts.Vertex_Begin : ""))
  100. .replace('#define CUSTOM_VERTEX_DEFINITIONS', (this._customUniform ? this._customUniform.join("\n") : "") + (this.CustomParts.Vertex_Definitions ? this.CustomParts.Vertex_Definitions : ""))
  101. .replace('#define CUSTOM_VERTEX_MAIN_BEGIN', (this.CustomParts.Vertex_MainBegin ? this.CustomParts.Vertex_MainBegin : ""))
  102. .replace('#define CUSTOM_VERTEX_UPDATE_POSITION', (this.CustomParts.Vertex_Before_PositionUpdated ? this.CustomParts.Vertex_Before_PositionUpdated : ""))
  103. .replace('#define CUSTOM_VERTEX_UPDATE_NORMAL', (this.CustomParts.Vertex_Before_NormalUpdated ? this.CustomParts.Vertex_Before_NormalUpdated : ""));
  104. // #define CUSTOM_VERTEX_MAIN_END
  105. BABYLON.Effect.ShadersStore[name + "PixelShader"] = this.FragmentShader
  106. .replace('#define CUSTOM_FRAGMENT_BEGIN', (this.CustomParts.Fragment_Begin ? this.CustomParts.Fragment_Begin : ""))
  107. .replace('#define CUSTOM_FRAGMENT_MAIN_BEGIN', (this.CustomParts.Fragment_MainBegin ? this.CustomParts.Fragment_MainBegin : ""))
  108. .replace('#define CUSTOM_FRAGMENT_DEFINITIONS', (this._customUniform ? this._customUniform.join("\n") : "") + (this.CustomParts.Fragment_Definitions ? this.CustomParts.Fragment_Definitions : ""))
  109. .replace('#define CUSTOM_FRAGMENT_UPDATE_DIFFUSE', (this.CustomParts.Fragment_Custom_Diffuse ? this.CustomParts.Fragment_Custom_Diffuse : ""))
  110. .replace('#define CUSTOM_FRAGMENT_UPDATE_ALPHA', (this.CustomParts.Fragment_Custom_Alpha ? this.CustomParts.Fragment_Custom_Alpha : ""))
  111. .replace('#define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR', (this.CustomParts.Fragment_Before_FragColor ? this.CustomParts.Fragment_Before_FragColor : ""));
  112. // #define CUSTOM_FRAGMENT_BEFORE_LIGHTS
  113. // #define CUSTOM_FRAGMENT_BEFORE_FOG
  114. this._isCreatedShader = true;
  115. this._createdShaderName = name;
  116. return name;
  117. }
  118. constructor(name: string, scene: Scene) {
  119. super(name, scene);
  120. this.CustomParts = new ShaderSpecialParts();
  121. this.customShaderNameResolve = this.Builder;
  122. this.FragmentShader = BABYLON.Effect.ShadersStore["defaultPixelShader"];
  123. this.VertexShader = BABYLON.Effect.ShadersStore["defaultVertexShader"];
  124. }
  125. public AddUniform(name: string, kind: string, param: any): CustomMaterial {
  126. if (!this._customUniform) {
  127. this._customUniform = new Array();
  128. this._newUniforms = new Array();
  129. this._newSamplerInstances = new Array();
  130. this._newUniformInstances = new Array();
  131. }
  132. if (param) {
  133. if (kind.indexOf("sampler") == -1) {
  134. (<any>this._newUniformInstances)[kind + "-" + name] = param;
  135. }
  136. else {
  137. (<any>this._newUniformInstances)[kind + "-" + name] = param;
  138. }
  139. }
  140. this._customUniform.push("uniform " + kind + " " + name + ";");
  141. this._newUniforms.push(name);
  142. return this;
  143. }
  144. public Fragment_Begin(shaderPart: string): CustomMaterial {
  145. this.CustomParts.Fragment_Begin = shaderPart;
  146. return this;
  147. }
  148. public Fragment_Definitions(shaderPart: string): CustomMaterial {
  149. this.CustomParts.Fragment_Definitions = shaderPart;
  150. return this;
  151. }
  152. public Fragment_MainBegin(shaderPart: string): CustomMaterial {
  153. this.CustomParts.Fragment_MainBegin = shaderPart;
  154. return this;
  155. }
  156. public Fragment_Custom_Diffuse(shaderPart: string): CustomMaterial {
  157. this.CustomParts.Fragment_Custom_Diffuse = shaderPart.replace("result", "diffuseColor");
  158. return this;
  159. }
  160. public Fragment_Custom_Alpha(shaderPart: string): CustomMaterial {
  161. this.CustomParts.Fragment_Custom_Alpha = shaderPart.replace("result", "alpha");
  162. return this;
  163. }
  164. public Fragment_Before_FragColor(shaderPart: string): CustomMaterial {
  165. this.CustomParts.Fragment_Before_FragColor = shaderPart.replace("result", "color");
  166. return this;
  167. }
  168. public Vertex_Begin(shaderPart: string): CustomMaterial {
  169. this.CustomParts.Vertex_Begin = shaderPart;
  170. return this;
  171. }
  172. public Vertex_Definitions(shaderPart: string): CustomMaterial {
  173. this.CustomParts.Vertex_Definitions = shaderPart;
  174. return this;
  175. }
  176. public Vertex_MainBegin(shaderPart: string): CustomMaterial {
  177. this.CustomParts.Vertex_MainBegin = shaderPart;
  178. return this;
  179. }
  180. public Vertex_Before_PositionUpdated(shaderPart: string): CustomMaterial {
  181. this.CustomParts.Vertex_Before_PositionUpdated = shaderPart.replace("result", "positionUpdated");
  182. return this;
  183. }
  184. public Vertex_Before_NormalUpdated(shaderPart: string): CustomMaterial {
  185. this.CustomParts.Vertex_Before_NormalUpdated = shaderPart.replace("result", "normalUpdated");
  186. return this;
  187. }
  188. }
  189. }