fluentMaterial.ts 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
  2. module BABYLON.GUI {
  3. /** @hidden */
  4. export class FluentMaterialDefines extends MaterialDefines {
  5. public INNERGLOW = false;
  6. public BORDER = false;
  7. public HOVERLIGHT = false;
  8. constructor() {
  9. super();
  10. this.rebuild();
  11. }
  12. }
  13. /**
  14. * Class used to render controls with fluent desgin
  15. */
  16. export class FluentMaterial extends PushMaterial {
  17. /**
  18. * Gets or sets inner glow intensity. A value of 0 means no glow (default is 0.5)
  19. */
  20. @serialize()
  21. @expandToProperty("_markAllSubMeshesAsTexturesDirty")
  22. public innerGlowColorIntensity = 0.5;
  23. /**
  24. * Gets or sets the inner glow color (white by default)
  25. */
  26. @serializeAsColor3()
  27. public innerGlowColor = new Color3(1.0, 1.0, 1.0);
  28. /**
  29. * Gets or sets alpha value (default is 1.0)
  30. */
  31. @serialize()
  32. public alpha = 1.0;
  33. /**
  34. * Gets or sets the albedo color (Default is Color3(0.3, 0.35, 0.4))
  35. */
  36. @serializeAsColor3()
  37. public albedoColor = new Color3(0.3, 0.35, 0.4);
  38. /**
  39. * Gets or sets a boolean indicating if borders must be rendered (default is false)
  40. */
  41. @serialize()
  42. @expandToProperty("_markAllSubMeshesAsTexturesDirty")
  43. public renderBorders = false;
  44. /**
  45. * Gets or sets border width (default is 0.5)
  46. */
  47. @serialize()
  48. public borderWidth = 0.5;
  49. /**
  50. * Gets or sets a value indicating the smoothing value applied to border edges (0.02 by default)
  51. */
  52. @serialize()
  53. public edgeSmoothingValue = 0.02;
  54. /**
  55. * Gets or sets the minimum value that can be applied to border width (default is 0.1)
  56. */
  57. @serialize()
  58. public borderMinValue = 0.1;
  59. /**
  60. * Gets or sets a boolean indicating if hover light must be rendered (default is false)
  61. */
  62. @serialize()
  63. @expandToProperty("_markAllSubMeshesAsTexturesDirty")
  64. public renderHoverLight = false;
  65. /**
  66. * Gets or sets the radius used to render the hover light (default is 0.15)
  67. */
  68. @serialize()
  69. public hoverRadius = 1.0;
  70. /**
  71. * Gets or sets the color used to render the hover light (default is Color4(0.3, 0.3, 0.3, 1.0))
  72. */
  73. @serializeAsColor4()
  74. public hoverColor = new Color4(0.3, 0.3, 0.3, 1.0);
  75. /**
  76. * Gets or sets the hover light position in world space (default is Vector3.Zero())
  77. */
  78. @serializeAsVector3()
  79. public hoverPosition = Vector3.Zero();
  80. /**
  81. * Creates a new Fluent material
  82. * @param name defines the name of the material
  83. * @param scene defines the hosting scene
  84. */
  85. constructor(name: string, scene: Scene) {
  86. super(name, scene);
  87. }
  88. public needAlphaBlending(): boolean {
  89. return this.alpha !== 1.0;
  90. }
  91. public needAlphaTesting(): boolean {
  92. return false;
  93. }
  94. public getAlphaTestTexture(): Nullable<BaseTexture> {
  95. return null;
  96. }
  97. public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
  98. if (this.isFrozen) {
  99. if (this._wasPreviouslyReady && subMesh.effect) {
  100. return true;
  101. }
  102. }
  103. if (!subMesh._materialDefines) {
  104. subMesh._materialDefines = new FluentMaterialDefines();
  105. }
  106. var scene = this.getScene();
  107. var defines = <FluentMaterialDefines>subMesh._materialDefines;
  108. if (!this.checkReadyOnEveryCall && subMesh.effect) {
  109. if (defines._renderId === scene.getRenderId()) {
  110. return true;
  111. }
  112. }
  113. if (defines._areTexturesDirty) {
  114. defines.INNERGLOW = this.innerGlowColorIntensity > 0;
  115. defines.BORDER = this.renderBorders;
  116. defines.HOVERLIGHT = this.renderHoverLight;
  117. }
  118. var engine = scene.getEngine();
  119. // Get correct effect
  120. if (defines.isDirty) {
  121. defines.markAsProcessed();
  122. scene.resetCachedMaterial();
  123. //Attributes
  124. var attribs = [VertexBuffer.PositionKind];
  125. attribs.push(VertexBuffer.NormalKind);
  126. attribs.push(VertexBuffer.UVKind);
  127. var shaderName = "fluent";
  128. var uniforms = ["world", "viewProjection", "innerGlowColor", "albedoColor", "borderWidth", "edgeSmoothingValue", "scaleFactor", "borderMinValue",
  129. "hoverColor", "hoverPosition", "hoverRadius"
  130. ];
  131. var samplers = new Array<String>();
  132. var uniformBuffers = new Array<string>();
  133. MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
  134. uniformsNames: uniforms,
  135. uniformBuffersNames: uniformBuffers,
  136. samplers: samplers,
  137. defines: defines,
  138. maxSimultaneousLights: 4
  139. });
  140. var join = defines.toString();
  141. subMesh.setEffect(scene.getEngine().createEffect(shaderName,
  142. <EffectCreationOptions>{
  143. attributes: attribs,
  144. uniformsNames: uniforms,
  145. uniformBuffersNames: uniformBuffers,
  146. samplers: samplers,
  147. defines: join,
  148. fallbacks: null,
  149. onCompiled: this.onCompiled,
  150. onError: this.onError,
  151. indexParameters: { maxSimultaneousLights: 4 }
  152. }, engine));
  153. }
  154. if (!subMesh.effect || !subMesh.effect.isReady()) {
  155. return false;
  156. }
  157. defines._renderId = scene.getRenderId();
  158. this._wasPreviouslyReady = true;
  159. return true;
  160. }
  161. public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
  162. var scene = this.getScene();
  163. var defines = <FluentMaterialDefines>subMesh._materialDefines;
  164. if (!defines) {
  165. return;
  166. }
  167. var effect = subMesh.effect;
  168. if (!effect) {
  169. return;
  170. }
  171. this._activeEffect = effect;
  172. // Matrices
  173. this.bindOnlyWorldMatrix(world);
  174. this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
  175. if (this._mustRebind(scene, effect)) {
  176. this._activeEffect.setColor4("albedoColor", this.albedoColor, this.alpha);
  177. if (defines.INNERGLOW) {
  178. this._activeEffect.setColor4("innerGlowColor", this.innerGlowColor, this.innerGlowColorIntensity);
  179. }
  180. if (defines.BORDER) {
  181. this._activeEffect.setFloat("borderWidth", this.borderWidth);
  182. this._activeEffect.setFloat("edgeSmoothingValue", this.edgeSmoothingValue);
  183. this._activeEffect.setFloat("borderMinValue", this.borderMinValue);
  184. mesh.getBoundingInfo().boundingBox.extendSize.multiplyToRef(mesh.scaling, Tmp.Vector3[0]);
  185. this._activeEffect.setVector3("scaleFactor", Tmp.Vector3[0]);
  186. }
  187. if (defines.HOVERLIGHT) {
  188. this._activeEffect.setDirectColor4("hoverColor", this.hoverColor);
  189. this._activeEffect.setFloat("hoverRadius", this.hoverRadius);
  190. this._activeEffect.setVector3("hoverPosition", this.hoverPosition);
  191. }
  192. }
  193. this._afterBind(mesh, this._activeEffect);
  194. }
  195. public getActiveTextures(): BaseTexture[] {
  196. var activeTextures = super.getActiveTextures();
  197. return activeTextures;
  198. }
  199. public hasTexture(texture: BaseTexture): boolean {
  200. if (super.hasTexture(texture)) {
  201. return true;
  202. }
  203. return false;
  204. }
  205. public dispose(forceDisposeEffect?: boolean): void {
  206. super.dispose(forceDisposeEffect);
  207. }
  208. public clone(name: string): FluentMaterial {
  209. return SerializationHelper.Clone(() => new FluentMaterial(name, this.getScene()), this);
  210. }
  211. public serialize(): any {
  212. var serializationObject = SerializationHelper.Serialize(this);
  213. serializationObject.customType = "BABYLON.GUI.FluentMaterial";
  214. return serializationObject;
  215. }
  216. public getClassName(): string {
  217. return "FluentMaterial";
  218. }
  219. // Statics
  220. public static Parse(source: any, scene: Scene, rootUrl: string): FluentMaterial {
  221. return SerializationHelper.Parse(() => new FluentMaterial(source.name, scene), source, scene, rootUrl);
  222. }
  223. }
  224. }