babylon.reflectionProbe.ts 5.9 KB

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