babylon.gridmaterial.ts 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /// <reference path="../../../dist/preview release/babylon.d.ts"/>
  2. module BABYLON {
  3. class GridMaterialDefines extends MaterialDefines {
  4. public OPACITY = false;
  5. public TRANSPARENT = false;
  6. public FOG = false;
  7. public PREMULTIPLYALPHA = false;
  8. public UV1 = false;
  9. public UV2 = false;
  10. constructor() {
  11. super();
  12. this.rebuild();
  13. }
  14. }
  15. /**
  16. * The grid materials allows you to wrap any shape with a grid.
  17. * Colors are customizable.
  18. */
  19. export class GridMaterial extends BABYLON.PushMaterial {
  20. /**
  21. * Main color of the grid (e.g. between lines)
  22. */
  23. @serializeAsColor3()
  24. public mainColor = Color3.Black();
  25. /**
  26. * Color of the grid lines.
  27. */
  28. @serializeAsColor3()
  29. public lineColor = Color3.Teal();
  30. /**
  31. * The scale of the grid compared to unit.
  32. */
  33. @serialize()
  34. public gridRatio = 1.0;
  35. /**
  36. * Allows setting an offset for the grid lines.
  37. */
  38. @serializeAsColor3()
  39. public gridOffset = Vector3.Zero();
  40. /**
  41. * The frequency of thicker lines.
  42. */
  43. @serialize()
  44. public majorUnitFrequency = 10;
  45. /**
  46. * The visibility of minor units in the grid.
  47. */
  48. @serialize()
  49. public minorUnitVisibility = 0.33;
  50. /**
  51. * The grid opacity outside of the lines.
  52. */
  53. @serialize()
  54. public opacity = 1.0;
  55. /**
  56. * Determine RBG output is premultiplied by alpha value.
  57. */
  58. @serialize()
  59. public preMultiplyAlpha = false;
  60. @serializeAsTexture("opacityTexture")
  61. private _opacityTexture: BaseTexture;
  62. @expandToProperty("_markAllSubMeshesAsTexturesDirty")
  63. public opacityTexture: BaseTexture;
  64. private _gridControl: Vector4 = new Vector4(this.gridRatio, this.majorUnitFrequency, this.minorUnitVisibility, this.opacity);
  65. private _renderId: number;
  66. /**
  67. * constructor
  68. * @param name The name given to the material in order to identify it afterwards.
  69. * @param scene The scene the material is used in.
  70. */
  71. constructor(name: string, scene: Scene) {
  72. super(name, scene);
  73. }
  74. /**
  75. * Returns wehter or not the grid requires alpha blending.
  76. */
  77. public needAlphaBlending(): boolean {
  78. return this.opacity < 1.0 || this._opacityTexture && this._opacityTexture.isReady();
  79. }
  80. public needAlphaBlendingForMesh(mesh: AbstractMesh): boolean {
  81. return this.needAlphaBlending();
  82. }
  83. public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
  84. if (this.isFrozen) {
  85. if (this._wasPreviouslyReady && subMesh.effect) {
  86. return true;
  87. }
  88. }
  89. if (!subMesh._materialDefines) {
  90. subMesh._materialDefines = new GridMaterialDefines();
  91. }
  92. var defines = <GridMaterialDefines>subMesh._materialDefines;
  93. var scene = this.getScene();
  94. if (!this.checkReadyOnEveryCall && subMesh.effect) {
  95. if (this._renderId === scene.getRenderId()) {
  96. return true;
  97. }
  98. }
  99. if (defines.TRANSPARENT !== (this.opacity < 1.0)) {
  100. defines.TRANSPARENT = !defines.TRANSPARENT;
  101. defines.markAsUnprocessed();
  102. }
  103. if (defines.PREMULTIPLYALPHA != this.preMultiplyAlpha) {
  104. defines.PREMULTIPLYALPHA = !defines.PREMULTIPLYALPHA;
  105. defines.markAsUnprocessed();
  106. }
  107. // Textures
  108. if (defines._areTexturesDirty) {
  109. defines._needUVs = false;
  110. if (scene.texturesEnabled) {
  111. if (this._opacityTexture && StandardMaterial.OpacityTextureEnabled) {
  112. if (!this._opacityTexture.isReady()) {
  113. return false;
  114. } else {
  115. defines._needUVs = true;
  116. defines.OPACITY = true;
  117. }
  118. }
  119. }
  120. }
  121. MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, false, defines);
  122. // Get correct effect
  123. if (defines.isDirty) {
  124. defines.markAsProcessed();
  125. scene.resetCachedMaterial();
  126. // Attribs
  127. MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, false);
  128. //Attributes
  129. var attribs = [VertexBuffer.PositionKind, VertexBuffer.NormalKind];
  130. if (defines.UV1) {
  131. attribs.push(VertexBuffer.UVKind);
  132. }
  133. if (defines.UV2) {
  134. attribs.push(VertexBuffer.UV2Kind);
  135. }
  136. // Defines
  137. var join = defines.toString();
  138. subMesh.setEffect(scene.getEngine().createEffect("grid",
  139. attribs,
  140. ["projection", "worldView", "mainColor", "lineColor", "gridControl", "gridOffset", "vFogInfos", "vFogColor", "world", "view",
  141. "opacityMatrix", "vOpacityInfos"],
  142. ["opacitySampler"],
  143. join,
  144. undefined,
  145. this.onCompiled,
  146. this.onError), defines);
  147. }
  148. if (!subMesh.effect || !subMesh.effect.isReady()) {
  149. return false;
  150. }
  151. this._renderId = scene.getRenderId();
  152. this._wasPreviouslyReady = true;
  153. return true;
  154. }
  155. public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
  156. var scene = this.getScene();
  157. var defines = <GridMaterialDefines>subMesh._materialDefines;
  158. if (!defines) {
  159. return;
  160. }
  161. var effect = subMesh.effect;
  162. if (!effect) {
  163. return;
  164. }
  165. this._activeEffect = effect;
  166. // Matrices
  167. this.bindOnlyWorldMatrix(world);
  168. this._activeEffect.setMatrix("worldView", world.multiply(scene.getViewMatrix()));
  169. this._activeEffect.setMatrix("view", scene.getViewMatrix());
  170. this._activeEffect.setMatrix("projection", scene.getProjectionMatrix());
  171. // Uniforms
  172. if (this._mustRebind(scene, effect)) {
  173. this._activeEffect.setColor3("mainColor", this.mainColor);
  174. this._activeEffect.setColor3("lineColor", this.lineColor);
  175. this._activeEffect.setVector3("gridOffset", this.gridOffset);
  176. this._gridControl.x = this.gridRatio;
  177. this._gridControl.y = Math.round(this.majorUnitFrequency);
  178. this._gridControl.z = this.minorUnitVisibility;
  179. this._gridControl.w = this.opacity;
  180. this._activeEffect.setVector4("gridControl", this._gridControl);
  181. if (this._opacityTexture && StandardMaterial.OpacityTextureEnabled) {
  182. this._activeEffect.setTexture("opacitySampler", this._opacityTexture);
  183. this._activeEffect.setFloat2("vOpacityInfos", this._opacityTexture.coordinatesIndex, this._opacityTexture.level);
  184. this._activeEffect.setMatrix("opacityMatrix", this._opacityTexture.getTextureMatrix());
  185. }
  186. }
  187. // Fog
  188. MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
  189. this._afterBind(mesh, this._activeEffect);
  190. }
  191. public dispose(forceDisposeEffect?: boolean): void {
  192. super.dispose(forceDisposeEffect);
  193. }
  194. public clone(name: string): GridMaterial {
  195. return SerializationHelper.Clone(() => new GridMaterial(name, this.getScene()), this);
  196. }
  197. public serialize(): any {
  198. var serializationObject = SerializationHelper.Serialize(this);
  199. serializationObject.customType = "BABYLON.GridMaterial";
  200. return serializationObject;
  201. }
  202. public getClassName(): string {
  203. return "GridMaterial";
  204. }
  205. public static Parse(source: any, scene: Scene, rootUrl: string): GridMaterial {
  206. return SerializationHelper.Parse(() => new GridMaterial(source.name, scene), source, scene, rootUrl);
  207. }
  208. }
  209. }