babylon.gridmaterial.ts 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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 = 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. }
  57. /**
  58. * Returns wehter or not the grid requires alpha blending.
  59. */
  60. public needAlphaBlending(): boolean {
  61. return this.opacity < 1.0;
  62. }
  63. private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
  64. if (!mesh) {
  65. return true;
  66. }
  67. if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
  68. return true;
  69. }
  70. return false;
  71. }
  72. public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
  73. if (this.checkReadyOnlyOnce) {
  74. if (this._wasPreviouslyReady) {
  75. return true;
  76. }
  77. }
  78. var scene = this.getScene();
  79. if (!this.checkReadyOnEveryCall) {
  80. if (this._renderId === scene.getRenderId()) {
  81. if (this._checkCache(scene, mesh, useInstances)) {
  82. return true;
  83. }
  84. }
  85. }
  86. var engine = scene.getEngine();
  87. var needNormals = true;
  88. this._defines.reset();
  89. if (this.opacity < 1.0) {
  90. this._defines.TRANSPARENT = true;
  91. }
  92. // Get correct effect
  93. if (!this._effect || !this._defines.isEqual(this._cachedDefines)) {
  94. this._defines.cloneTo(this._cachedDefines);
  95. scene.resetCachedMaterial();
  96. // Attributes
  97. var attribs = [VertexBuffer.PositionKind, VertexBuffer.NormalKind];
  98. // Effect
  99. var shaderName = scene.getEngine().getCaps().standardDerivatives ? "grid" : "legacygrid";
  100. // Defines
  101. var join = this._defines.toString();
  102. this._effect = scene.getEngine().createEffect(shaderName,
  103. attribs,
  104. ["worldViewProjection", "mainColor", "lineColor", "gridControl"],
  105. [],
  106. join,
  107. null,
  108. this.onCompiled,
  109. this.onError);
  110. }
  111. if (!this._effect.isReady()) {
  112. return false;
  113. }
  114. this._renderId = scene.getRenderId();
  115. this._wasPreviouslyReady = true;
  116. return true;
  117. }
  118. public bindOnlyWorldMatrix(world: Matrix): void {
  119. var scene = this.getScene();
  120. this._effect.setMatrix("worldViewProjection", world.multiply(scene.getTransformMatrix()));
  121. }
  122. public bind(world: Matrix, mesh?: Mesh): void {
  123. var scene = this.getScene();
  124. // Matrices
  125. this.bindOnlyWorldMatrix(world);
  126. // Uniforms
  127. if (scene.getCachedMaterial() !== (<BABYLON.Material>this)) {
  128. this._effect.setColor3("mainColor", this.mainColor);
  129. this._effect.setColor3("lineColor", this.lineColor);
  130. this._gridControl.x = this.gridRatio;
  131. this._gridControl.y = Math.round(this.majorUnitFrequency);
  132. this._gridControl.z = this.minorUnitVisibility;
  133. this._gridControl.w = this.opacity;
  134. this._effect.setVector4("gridControl", this._gridControl);
  135. }
  136. super.bind(world, mesh);
  137. }
  138. public dispose(forceDisposeEffect?: boolean): void {
  139. super.dispose(forceDisposeEffect);
  140. }
  141. public clone(name: string): GridMaterial {
  142. return SerializationHelper.Clone(() => new GridMaterial(name, this.getScene()), this);
  143. }
  144. public serialize(): any {
  145. var serializationObject = SerializationHelper.Serialize(this);
  146. serializationObject.customType = "BABYLON.GridMaterial";
  147. return serializationObject;
  148. }
  149. public static Parse(source: any, scene: Scene, rootUrl: string): GridMaterial {
  150. return SerializationHelper.Parse(() => new GridMaterial(source.name, scene), source, scene, rootUrl);
  151. }
  152. }
  153. }