depthRendererSceneComponent.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import { Nullable } from "../types";
  2. import { Scene } from "../scene";
  3. import { SmartArrayNoDuplicate } from "../Misc/smartArray";
  4. import { DepthRenderer } from "./depthRenderer";
  5. import { Camera } from "../Cameras/camera";
  6. import { Constants } from "../Engines/constants";
  7. import { ISceneComponent, SceneComponentConstants } from "../sceneComponent";
  8. import { RenderTargetTexture } from "../Materials/Textures/renderTargetTexture";
  9. declare module "../scene" {
  10. export interface Scene {
  11. /** @hidden (Backing field) */
  12. _depthRenderer: { [id: string]: DepthRenderer };
  13. /**
  14. * Creates a depth renderer a given camera which contains a depth map which can be used for post processing.
  15. * @param camera The camera to create the depth renderer on (default: scene's active camera)
  16. * @param storeNonLinearDepth Defines whether the depth is stored linearly like in Babylon Shadows or directly like glFragCoord.z
  17. * @returns the created depth renderer
  18. */
  19. enableDepthRenderer(camera?: Nullable<Camera>, storeNonLinearDepth?: boolean): DepthRenderer;
  20. /**
  21. * Disables a depth renderer for a given camera
  22. * @param camera The camera to disable the depth renderer on (default: scene's active camera)
  23. */
  24. disableDepthRenderer(camera?: Nullable<Camera>): void;
  25. }
  26. }
  27. Scene.prototype.enableDepthRenderer = function(camera?: Nullable<Camera>, storeNonLinearDepth = false): DepthRenderer {
  28. camera = camera || this.activeCamera;
  29. if (!camera) {
  30. throw "No camera available to enable depth renderer";
  31. }
  32. if (!this._depthRenderer) {
  33. this._depthRenderer = {};
  34. }
  35. if (!this._depthRenderer[camera.id]) {
  36. var textureType = 0;
  37. if (this.getEngine().getCaps().textureHalfFloatRender) {
  38. textureType = Constants.TEXTURETYPE_HALF_FLOAT;
  39. }
  40. else if (this.getEngine().getCaps().textureFloatRender) {
  41. textureType = Constants.TEXTURETYPE_FLOAT;
  42. } else {
  43. textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;
  44. }
  45. this._depthRenderer[camera.id] = new DepthRenderer(this, textureType, camera, storeNonLinearDepth);
  46. }
  47. return this._depthRenderer[camera.id];
  48. };
  49. Scene.prototype.disableDepthRenderer = function(camera?: Nullable<Camera>): void {
  50. camera = camera || this.activeCamera;
  51. if (!camera || !this._depthRenderer || !this._depthRenderer[camera.id]) {
  52. return;
  53. }
  54. this._depthRenderer[camera.id].dispose();
  55. delete this._depthRenderer[camera.id];
  56. };
  57. /**
  58. * Defines the Depth Renderer scene component responsible to manage a depth buffer useful
  59. * in several rendering techniques.
  60. */
  61. export class DepthRendererSceneComponent implements ISceneComponent {
  62. /**
  63. * The component name helpfull to identify the component in the list of scene components.
  64. */
  65. public readonly name = SceneComponentConstants.NAME_DEPTHRENDERER;
  66. /**
  67. * The scene the component belongs to.
  68. */
  69. public scene: Scene;
  70. /**
  71. * Creates a new instance of the component for the given scene
  72. * @param scene Defines the scene to register the component in
  73. */
  74. constructor(scene: Scene) {
  75. this.scene = scene;
  76. }
  77. /**
  78. * Registers the component in a given scene
  79. */
  80. public register(): void {
  81. this.scene._gatherRenderTargetsStage.registerStep(SceneComponentConstants.STEP_GATHERRENDERTARGETS_DEPTHRENDERER, this, this._gatherRenderTargets);
  82. this.scene._gatherActiveCameraRenderTargetsStage.registerStep(SceneComponentConstants.STEP_GATHERACTIVECAMERARENDERTARGETS_DEPTHRENDERER, this, this._gatherActiveCameraRenderTargets);
  83. }
  84. /**
  85. * Rebuilds the elements related to this component in case of
  86. * context lost for instance.
  87. */
  88. public rebuild(): void {
  89. // Nothing to do for this component
  90. }
  91. /**
  92. * Disposes the component and the associated ressources
  93. */
  94. public dispose(): void {
  95. for (var key in this.scene._depthRenderer) {
  96. this.scene._depthRenderer[key].dispose();
  97. }
  98. }
  99. private _gatherRenderTargets(renderTargets: SmartArrayNoDuplicate<RenderTargetTexture>): void {
  100. if (this.scene._depthRenderer) {
  101. for (var key in this.scene._depthRenderer) {
  102. let depthRenderer = this.scene._depthRenderer[key];
  103. if (!depthRenderer.useOnlyInActiveCamera) {
  104. renderTargets.push(depthRenderer.getDepthMap());
  105. }
  106. }
  107. }
  108. }
  109. private _gatherActiveCameraRenderTargets(renderTargets: SmartArrayNoDuplicate<RenderTargetTexture>): void {
  110. if (this.scene._depthRenderer) {
  111. for (var key in this.scene._depthRenderer) {
  112. let depthRenderer = this.scene._depthRenderer[key];
  113. if (depthRenderer.useOnlyInActiveCamera && this.scene.activeCamera!.id === key) {
  114. renderTargets.push(depthRenderer.getDepthMap());
  115. }
  116. }
  117. }
  118. }
  119. }
  120. DepthRenderer._SceneComponentInitialization = (scene: Scene) => {
  121. // Register the G Buffer component to the scene.
  122. let component = scene._getComponent(SceneComponentConstants.NAME_DEPTHRENDERER) as DepthRendererSceneComponent;
  123. if (!component) {
  124. component = new DepthRendererSceneComponent(scene);
  125. scene._addComponent(component);
  126. }
  127. };