babylon.shadowLight.ts 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. module BABYLON {
  2. export interface IShadowLight extends Light {
  3. id: string;
  4. position: Vector3;
  5. direction: Vector3;
  6. transformedPosition: Vector3;
  7. transformedDirection: Vector3;
  8. name: string;
  9. shadowMinZ: number;
  10. shadowMaxZ: number;
  11. computeTransformedInformation(): boolean;
  12. getScene(): Scene;
  13. customProjectionMatrixBuilder: (viewMatrix: Matrix, renderList: Array<AbstractMesh>, result: Matrix) => void;
  14. setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): IShadowLight;
  15. getDepthScale(): number;
  16. needCube(): boolean;
  17. needProjectionMatrixCompute(): boolean;
  18. forceProjectionMatrixCompute(): void;
  19. getShadowDirection(faceIndex?: number): Vector3;
  20. /**
  21. * Gets the minZ used for shadow according to both the scene and the light.
  22. * @param activeCamera
  23. */
  24. getDepthMinZ(activeCamera: Camera): number;
  25. /**
  26. * Gets the minZ used for shadow according to both the scene and the light.
  27. * @param activeCamera
  28. */
  29. getDepthMaxZ(activeCamera: Camera): number;
  30. }
  31. export abstract class ShadowLight extends Light implements IShadowLight {
  32. protected abstract _setDefaultShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): void;
  33. @serializeAsVector3()
  34. public position: Vector3;
  35. protected _direction: Vector3;
  36. @serializeAsVector3()
  37. public get direction(): Vector3 {
  38. return this._direction;
  39. }
  40. public set direction(value: Vector3) {
  41. this._direction = value;
  42. }
  43. private _shadowMinZ: number;
  44. @serialize()
  45. public get shadowMinZ(): number {
  46. return this._shadowMinZ
  47. }
  48. public set shadowMinZ(value: number) {
  49. this._shadowMinZ = value;
  50. this.forceProjectionMatrixCompute();
  51. }
  52. private _shadowMaxZ: number;
  53. @serialize()
  54. public get shadowMaxZ(): number {
  55. return this._shadowMaxZ
  56. }
  57. public set shadowMaxZ(value: number) {
  58. this._shadowMaxZ = value;
  59. this.forceProjectionMatrixCompute();
  60. }
  61. public customProjectionMatrixBuilder: (viewMatrix: Matrix, renderList: Array<AbstractMesh>, result: Matrix) => void;
  62. public transformedPosition: Vector3;
  63. public transformedDirection: Vector3;
  64. private _worldMatrix: Matrix;
  65. private _needProjectionMatrixCompute: boolean = true;
  66. /**
  67. * Computes the light transformed position/direction in case the light is parented. Returns true if parented, else false.
  68. */
  69. public computeTransformedInformation(): boolean {
  70. if (this.parent && this.parent.getWorldMatrix) {
  71. if (!this.transformedPosition) {
  72. this.transformedPosition = Vector3.Zero();
  73. }
  74. Vector3.TransformCoordinatesToRef(this.position, this.parent.getWorldMatrix(), this.transformedPosition);
  75. // In case the direction is present.
  76. if (this.direction) {
  77. if (!this.transformedDirection) {
  78. this.transformedDirection = Vector3.Zero();
  79. }
  80. Vector3.TransformNormalToRef(this.direction, this.parent.getWorldMatrix(), this.transformedDirection);
  81. }
  82. return true;
  83. }
  84. return false;
  85. }
  86. /**
  87. * Return the depth scale used for the shadow map.
  88. */
  89. public getDepthScale(): number {
  90. return 50.0;
  91. }
  92. /**
  93. * Returns the light direction (Vector3) for any passed face index.
  94. */
  95. public getShadowDirection(faceIndex?: number): Vector3 {
  96. return this.transformedDirection ? this.transformedDirection : this.direction;
  97. }
  98. /**
  99. * Returns the DirectionalLight absolute position in the World.
  100. */
  101. public getAbsolutePosition(): Vector3 {
  102. return this.transformedPosition ? this.transformedPosition : this.position;
  103. }
  104. /**
  105. * Sets the DirectionalLight direction toward the passed target (Vector3).
  106. * Returns the updated DirectionalLight direction (Vector3).
  107. */
  108. public setDirectionToTarget(target: Vector3): Vector3 {
  109. this.direction = Vector3.Normalize(target.subtract(this.position));
  110. return this.direction;
  111. }
  112. /**
  113. * Returns the light rotation (Vector3).
  114. */
  115. public getRotation(): Vector3 {
  116. this.direction.normalize();
  117. var xaxis = BABYLON.Vector3.Cross(this.direction, BABYLON.Axis.Y);
  118. var yaxis = BABYLON.Vector3.Cross(xaxis, this.direction);
  119. return Vector3.RotationFromAxis(xaxis, yaxis, this.direction);
  120. }
  121. /**
  122. * Boolean : false by default.
  123. */
  124. public needCube(): boolean {
  125. return false;
  126. }
  127. /**
  128. * Specifies wether or not the projection matrix should be recomputed this frame.
  129. */
  130. public needProjectionMatrixCompute(): boolean {
  131. return this._needProjectionMatrixCompute;
  132. }
  133. /**
  134. * Forces the shadow generator to recompute the projection matrix even if position and direction did not changed.
  135. */
  136. public forceProjectionMatrixCompute(): void {
  137. this._needProjectionMatrixCompute = true;
  138. }
  139. /**
  140. * Get the world matrix of the sahdow lights.
  141. */
  142. public _getWorldMatrix(): Matrix {
  143. if (!this._worldMatrix) {
  144. this._worldMatrix = Matrix.Identity();
  145. }
  146. Matrix.TranslationToRef(this.position.x, this.position.y, this.position.z, this._worldMatrix);
  147. return this._worldMatrix;
  148. }
  149. /**
  150. * Gets the minZ used for shadow according to both the scene and the light.
  151. * @param activeCamera
  152. */
  153. public getDepthMinZ(activeCamera: Camera): number {
  154. return this.shadowMinZ !== undefined ? this.shadowMinZ : activeCamera.minZ;
  155. }
  156. /**
  157. * Gets the maxZ used for shadow according to both the scene and the light.
  158. * @param activeCamera
  159. */
  160. public getDepthMaxZ(activeCamera: Camera): number {
  161. return this.shadowMaxZ !== undefined ? this.shadowMaxZ : activeCamera.maxZ;
  162. }
  163. /**
  164. * Sets the projection matrix according to the type of light and custom projection matrix definition.
  165. * Returns the light.
  166. */
  167. public setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): IShadowLight {
  168. if (this.customProjectionMatrixBuilder) {
  169. this.customProjectionMatrixBuilder(viewMatrix, renderList, matrix);
  170. }
  171. else {
  172. this._setDefaultShadowProjectionMatrix(matrix, viewMatrix, renderList);
  173. }
  174. return this;
  175. }
  176. }
  177. }