babylon.gridmaterial.ts 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /// <reference path="../../../dist/preview release/babylon.d.ts"/>
  2. module BABYLON {
  3. class GRIDMaterialDefines extends MaterialDefines {
  4. public TRANSPARENT = false;
  5. constructor() {
  6. super();
  7. this._keys = Object.keys(this);
  8. }
  9. }
  10. /**
  11. * The grid materials allows you to wrap any shape with a grid.
  12. * Colors are customizable.
  13. */
  14. export class GridMaterial extends BABYLON.Material {
  15. /**
  16. * Main color of the grid (e.g. between lines)
  17. */
  18. @serializeAsColor3()
  19. public mainColor = Color3.White();
  20. /**
  21. * Color of the grid lines.
  22. */
  23. @serializeAsColor3()
  24. public lineColor = Color3.Black();
  25. /**
  26. * The scale of the grid compared to unit.
  27. */
  28. @serialize()
  29. public gridRatio = 1.0;
  30. /**
  31. * The frequency of thicker lines.
  32. */
  33. @serialize()
  34. public majorUnitFrequency = 10;
  35. /**
  36. * The visibility of minor units in the grid.
  37. */
  38. @serialize()
  39. public minorUnitVisibility = 0.33;
  40. /**
  41. * The grid opacity outside of the lines.
  42. */
  43. @serialize()
  44. public opacity = 1.0;
  45. private _gridControl: Vector4 = new Vector4(this.gridRatio, this.majorUnitFrequency, this.minorUnitVisibility, this.opacity);
  46. private _renderId: number;
  47. private _defines = new GRIDMaterialDefines();
  48. private _cachedDefines: GRIDMaterialDefines = new GRIDMaterialDefines();
  49. /**
  50. * constructor
  51. * @param name The name given to the material in order to identify it afterwards.
  52. * @param scene The scene the material is used in.
  53. */
  54. constructor(name: string, scene: Scene) {
  55. super(name, scene);
  56. // Forces cache to be different on first creation.
  57. this._cachedDefines.TRANSPARENT = true;
  58. }
  59. /**
  60. * Returns wehter or not the grid requires alpha blending.
  61. */
  62. public needAlphaBlending(): boolean {
  63. return this.opacity < 1.0;
  64. }
  65. private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
  66. if (!mesh) {
  67. return true;
  68. }
  69. if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
  70. return true;
  71. }
  72. return false;
  73. }
  74. public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
  75. if (this.checkReadyOnlyOnce) {
  76. if (this._wasPreviouslyReady) {
  77. return true;
  78. }
  79. }
  80. var scene = this.getScene();
  81. if (!this.checkReadyOnEveryCall) {
  82. if (this._renderId === scene.getRenderId()) {
  83. if (this._checkCache(scene, mesh, useInstances)) {
  84. return true;
  85. }
  86. }
  87. }
  88. var engine = scene.getEngine();
  89. var needNormals = true;
  90. this._defines.reset();
  91. if (this.opacity < 1.0) {
  92. this._defines.TRANSPARENT = true;
  93. }
  94. // Get correct effect
  95. if (!this._defines.isEqual(this._cachedDefines)) {
  96. this._defines.cloneTo(this._cachedDefines);
  97. scene.resetCachedMaterial();
  98. // Attributes
  99. var attribs = [VertexBuffer.PositionKind, VertexBuffer.NormalKind];
  100. // Effect
  101. var shaderName = scene.getEngine().getCaps().standardDerivatives ? "grid" : "legacygrid";
  102. // Defines
  103. var join = this._defines.toString();
  104. this._effect = scene.getEngine().createEffect(shaderName,
  105. attribs,
  106. ["worldViewProjection", "mainColor", "lineColor", "gridControl"],
  107. [],
  108. join,
  109. null,
  110. this.onCompiled,
  111. this.onError);
  112. }
  113. if (!this._effect.isReady()) {
  114. return false;
  115. }
  116. this._renderId = scene.getRenderId();
  117. this._wasPreviouslyReady = true;
  118. return true;
  119. }
  120. public bindOnlyWorldMatrix(world: Matrix): void {
  121. var scene = this.getScene();
  122. this._effect.setMatrix("worldViewProjection", world.multiply(scene.getTransformMatrix()));
  123. }
  124. public bind(world: Matrix, mesh?: Mesh): void {
  125. var scene = this.getScene();
  126. // Matrices
  127. this.bindOnlyWorldMatrix(world);
  128. // Uniforms
  129. if (scene.getCachedMaterial() !== (<BABYLON.Material>this)) {
  130. this._effect.setColor3("mainColor", this.mainColor);
  131. this._effect.setColor3("lineColor", this.lineColor);
  132. this._gridControl.x = this.gridRatio;
  133. this._gridControl.y = Math.round(this.majorUnitFrequency);
  134. this._gridControl.z = this.minorUnitVisibility;
  135. this._gridControl.w = this.opacity;
  136. this._effect.setVector4("gridControl", this._gridControl);
  137. }
  138. super.bind(world, mesh);
  139. }
  140. public dispose(forceDisposeEffect?: boolean): void {
  141. super.dispose(forceDisposeEffect);
  142. }
  143. public clone(name: string): GridMaterial {
  144. return SerializationHelper.Clone(() => new GridMaterial(name, this.getScene()), this);
  145. }
  146. public serialize(): any {
  147. var serializationObject = SerializationHelper.Serialize(this);
  148. serializationObject.customType = "BABYLON.GridMaterial";
  149. return serializationObject;
  150. }
  151. public static Parse(source: any, scene: Scene, rootUrl: string): GridMaterial {
  152. return SerializationHelper.Parse(() => new GridMaterial(source.name, scene), source, scene, rootUrl);
  153. }
  154. }
  155. }