reflectionProbe.ts 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import { RenderTargetTexture } from "Materials/Textures/renderTargetTexture";
  2. import { Matrix, Vector3 } from "Math/math";
  3. import { AbstractMesh } from "Mesh/abstractMesh";
  4. import { Nullable } from "types";
  5. import { Scene } from "scene";
  6. import { Engine } from "Engine/engine";
  7. declare module "scene" {
  8. export interface Scene {
  9. /**
  10. * The list of reflection probes added to the scene
  11. * @see http://doc.babylonjs.com/how_to/how_to_use_reflection_probes
  12. */
  13. reflectionProbes: Array<ReflectionProbe>;
  14. }
  15. }
  16. /**
  17. * Class used to generate realtime reflection / refraction cube textures
  18. * @see http://doc.babylonjs.com/how_to/how_to_use_reflection_probes
  19. */
  20. export class ReflectionProbe{
  21. private _scene: Scene;
  22. private _renderTargetTexture: RenderTargetTexture;
  23. private _projectionMatrix: Matrix;
  24. private _viewMatrix = Matrix.Identity();
  25. private _target = Vector3.Zero();
  26. private _add = Vector3.Zero();
  27. private _attachedMesh: AbstractMesh;
  28. private _invertYAxis = false;
  29. /** Gets or sets probe position (center of the cube map) */
  30. public position = Vector3.Zero();
  31. /**
  32. * Creates a new reflection probe
  33. * @param name defines the name of the probe
  34. * @param size defines the texture resolution (for each face)
  35. * @param scene defines the hosting scene
  36. * @param generateMipMaps defines if mip maps should be generated automatically (true by default)
  37. * @param useFloat defines if HDR data (flaot data) should be used to store colors (false by default)
  38. */
  39. constructor(
  40. /** defines the name of the probe */
  41. public name: string,
  42. size: number, scene: Scene, generateMipMaps = true, useFloat = false) {
  43. this._scene = scene;
  44. // Create the scene field if not exist.
  45. if (!this._scene.reflectionProbes) {
  46. this._scene.reflectionProbes = new Array<ReflectionProbe>();
  47. }
  48. this._scene.reflectionProbes.push(this);
  49. this._renderTargetTexture = new RenderTargetTexture(name, size, scene, generateMipMaps, true, useFloat ? Engine.TEXTURETYPE_FLOAT : Engine.TEXTURETYPE_UNSIGNED_INT, true);
  50. this._renderTargetTexture.onBeforeRenderObservable.add((faceIndex: number) => {
  51. switch (faceIndex) {
  52. case 0:
  53. this._add.copyFromFloats(1, 0, 0);
  54. break;
  55. case 1:
  56. this._add.copyFromFloats(-1, 0, 0);
  57. break;
  58. case 2:
  59. this._add.copyFromFloats(0, this._invertYAxis ? 1 : -1, 0);
  60. break;
  61. case 3:
  62. this._add.copyFromFloats(0, this._invertYAxis ? -1 : 1, 0);
  63. break;
  64. case 4:
  65. this._add.copyFromFloats(0, 0, 1);
  66. break;
  67. case 5:
  68. this._add.copyFromFloats(0, 0, -1);
  69. break;
  70. }
  71. if (this._attachedMesh) {
  72. this.position.copyFrom(this._attachedMesh.getAbsolutePosition());
  73. }
  74. this.position.addToRef(this._add, this._target);
  75. Matrix.LookAtLHToRef(this.position, this._target, Vector3.Up(), this._viewMatrix);
  76. scene.setTransformMatrix(this._viewMatrix, this._projectionMatrix);
  77. scene._forcedViewPosition = this.position;
  78. });
  79. this._renderTargetTexture.onAfterUnbindObservable.add(() => {
  80. scene._forcedViewPosition = null;
  81. scene.updateTransformMatrix(true);
  82. });
  83. if (scene.activeCamera) {
  84. this._projectionMatrix = Matrix.PerspectiveFovLH(Math.PI / 2, 1, scene.activeCamera.minZ, scene.activeCamera.maxZ);
  85. }
  86. }
  87. /** Gets or sets the number of samples to use for multi-sampling (0 by default). Required WebGL2 */
  88. public get samples(): number {
  89. return this._renderTargetTexture.samples;
  90. }
  91. public set samples(value: number) {
  92. this._renderTargetTexture.samples = value;
  93. }
  94. /** Gets or sets the refresh rate to use (on every frame by default) */
  95. public get refreshRate(): number {
  96. return this._renderTargetTexture.refreshRate;
  97. }
  98. public set refreshRate(value: number) {
  99. this._renderTargetTexture.refreshRate = value;
  100. }
  101. /**
  102. * Gets the hosting scene
  103. * @returns a Scene
  104. */
  105. public getScene(): Scene {
  106. return this._scene;
  107. }
  108. /** Gets the internal CubeTexture used to render to */
  109. public get cubeTexture(): RenderTargetTexture {
  110. return this._renderTargetTexture;
  111. }
  112. /** Gets the list of meshes to render */
  113. public get renderList(): Nullable<AbstractMesh[]> {
  114. return this._renderTargetTexture.renderList;
  115. }
  116. /**
  117. * Attach the probe to a specific mesh (Rendering will be done from attached mesh's position)
  118. * @param mesh defines the mesh to attach to
  119. */
  120. public attachToMesh(mesh: AbstractMesh): void {
  121. this._attachedMesh = mesh;
  122. }
  123. /**
  124. * Specifies whether or not the stencil and depth buffer are cleared between two rendering groups
  125. * @param renderingGroupId The rendering group id corresponding to its index
  126. * @param autoClearDepthStencil Automatically clears depth and stencil between groups if true.
  127. */
  128. public setRenderingAutoClearDepthStencil(renderingGroupId: number, autoClearDepthStencil: boolean): void {
  129. this._renderTargetTexture.setRenderingAutoClearDepthStencil(renderingGroupId, autoClearDepthStencil);
  130. }
  131. /**
  132. * Clean all associated resources
  133. */
  134. public dispose() {
  135. var index = this._scene.reflectionProbes.indexOf(this);
  136. if (index !== -1) {
  137. // Remove from the scene if found
  138. this._scene.reflectionProbes.splice(index, 1);
  139. }
  140. if (this._renderTargetTexture) {
  141. this._renderTargetTexture.dispose();
  142. (<any>this._renderTargetTexture) = null;
  143. }
  144. }
  145. }