Преглед на файлове

Merge pull request #7403 from BabylonJS/master

4.1.0-beta.19
David Catuhe преди 5 години
родител
ревизия
d2b1e482f5
променени са 30 файла, в които са добавени 2444 реда и са изтрити 509 реда
  1. 219 66
      dist/preview release/babylon.d.ts
  2. 1 1
      dist/preview release/babylon.js
  3. 487 31
      dist/preview release/babylon.max.js
  4. 1 1
      dist/preview release/babylon.max.js.map
  5. 469 147
      dist/preview release/babylon.module.d.ts
  6. 219 66
      dist/preview release/documentation.d.ts
  7. 3 2
      dist/preview release/loaders/babylon.objFileLoader.js
  8. 1 1
      dist/preview release/loaders/babylon.objFileLoader.js.map
  9. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  10. 3 2
      dist/preview release/loaders/babylonjs.loaders.js
  11. 1 1
      dist/preview release/loaders/babylonjs.loaders.js.map
  12. 1 1
      dist/preview release/loaders/babylonjs.loaders.min.js
  13. 1 1
      dist/preview release/packagesSizeBaseLine.json
  14. 469 147
      dist/preview release/viewer/babylon.module.d.ts
  15. 29 17
      dist/preview release/viewer/babylon.viewer.js
  16. 2 2
      dist/preview release/viewer/babylon.viewer.max.js
  17. 3 0
      dist/preview release/what's new.md
  18. 3 2
      loaders/src/OBJ/objFileLoader.ts
  19. 9 10
      src/Cameras/XR/webXRCamera.ts
  20. 1 3
      src/Cameras/XR/webXRController.ts
  21. 3 3
      src/Engines/thinEngine.ts
  22. 85 0
      src/Lights/Shadows/cascadedShadowGenerator.ts
  23. 2 0
      src/Materials/Textures/MultiviewRenderTarget.ts
  24. 108 0
      src/Misc/depthReducer.ts
  25. 2 0
      src/Misc/index.ts
  26. 244 0
      src/Misc/minMaxReducer.ts
  27. 3 0
      src/Rendering/depthRenderer.ts
  28. 2 2
      src/Rendering/depthRendererSceneComponent.ts
  29. 70 0
      src/Shaders/minmaxRedux.fragment.fx
  30. 2 2
      src/sceneComponent.ts

+ 219 - 66
dist/preview release/babylon.d.ts

@@ -11362,9 +11362,9 @@ declare module BABYLON {
         static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW: number;
         static readonly STEP_AFTERCAMERADRAW_LAYER: number;
         static readonly STEP_AFTERRENDER_AUDIO: number;
-        static readonly STEP_GATHERRENDERTARGETS_SHADOWGENERATOR: number;
-        static readonly STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER: number;
         static readonly STEP_GATHERRENDERTARGETS_DEPTHRENDERER: number;
+        static readonly STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER: number;
+        static readonly STEP_GATHERRENDERTARGETS_SHADOWGENERATOR: number;
         static readonly STEP_GATHERRENDERTARGETS_POSTPROCESSRENDERPIPELINEMANAGER: number;
         static readonly STEP_GATHERACTIVECAMERARENDERTARGETS_DEPTHRENDERER: number;
         static readonly STEP_POINTERMOVE_SPRITE: number;
@@ -43758,7 +43758,6 @@ declare module BABYLON {
          * Pointer which can be used to select objects or attach a visible laser to
          */
         pointer: AbstractMesh;
-        private _gamepadMode;
         /**
          * If available, this is the gamepad object related to this controller.
          * Using this object it is possible to get click events and trackpad changes of the
@@ -53990,6 +53989,191 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
+    /** @hidden */
+    export var depthPixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /** @hidden */
+    export var depthVertexShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /**
+     * This represents a depth renderer in Babylon.
+     * A depth renderer will render to it's depth map every frame which can be displayed or used in post processing
+     */
+    export class DepthRenderer {
+        private _scene;
+        private _depthMap;
+        private _effect;
+        private readonly _storeNonLinearDepth;
+        private readonly _clearColor;
+        /** Get if the depth renderer is using packed depth or not */
+        readonly isPacked: boolean;
+        private _cachedDefines;
+        private _camera;
+        /** Enable or disable the depth renderer. When disabled, the depth texture is not updated */
+        enabled: boolean;
+        /**
+         * Specifiess that the depth renderer will only be used within
+         * the camera it is created for.
+         * This can help forcing its rendering during the camera processing.
+         */
+        useOnlyInActiveCamera: boolean;
+        /** @hidden */
+        static _SceneComponentInitialization: (scene: Scene) => void;
+        /**
+         * Instantiates a depth renderer
+         * @param scene The scene the renderer belongs to
+         * @param type The texture type of the depth map (default: Engine.TEXTURETYPE_FLOAT)
+         * @param camera The camera to be used to render the depth map (default: scene's active camera)
+         * @param storeNonLinearDepth Defines whether the depth is stored linearly like in Babylon Shadows or directly like glFragCoord.z
+         */
+        constructor(scene: Scene, type?: number, camera?: Nullable<Camera>, storeNonLinearDepth?: boolean);
+        /**
+         * Creates the depth rendering effect and checks if the effect is ready.
+         * @param subMesh The submesh to be used to render the depth map of
+         * @param useInstances If multiple world instances should be used
+         * @returns if the depth renderer is ready to render the depth map
+         */
+        isReady(subMesh: SubMesh, useInstances: boolean): boolean;
+        /**
+         * Gets the texture which the depth map will be written to.
+         * @returns The depth map texture
+         */
+        getDepthMap(): RenderTargetTexture;
+        /**
+         * Disposes of the depth renderer.
+         */
+        dispose(): void;
+    }
+}
+declare module BABYLON {
+    /** @hidden */
+    export var minmaxReduxPixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /**
+     * This class computes a min/max reduction from a texture: it means it computes the minimum
+     * and maximum values from all values of the texture.
+     * It is performed on the GPU for better performances, thanks to a succession of post processes.
+     * The source values are read from the red channel of the texture.
+     */
+    export class MinMaxReducer {
+        /**
+         * Observable triggered when the computation has been performed
+         */
+        onAfterReductionPerformed: Observable<{
+            min: number;
+            max: number;
+        }>;
+        protected _camera: Camera;
+        protected _sourceTexture: Nullable<RenderTargetTexture>;
+        protected _reductionSteps: Nullable<Array<PostProcess>>;
+        protected _postProcessManager: PostProcessManager;
+        protected _onAfterUnbindObserver: Nullable<Observer<RenderTargetTexture>>;
+        protected _forceFullscreenViewport: boolean;
+        /**
+         * Creates a min/max reducer
+         * @param camera The camera to use for the post processes
+         */
+        constructor(camera: Camera);
+        /**
+         * Gets the texture used to read the values from.
+         */
+        get sourceTexture(): Nullable<RenderTargetTexture>;
+        /**
+         * Sets the source texture to read the values from.
+         * One must indicate if the texture is a depth texture or not through the depthRedux parameter
+         * because in such textures '1' value must not be taken into account to compute the maximum
+         * as this value is used to clear the texture.
+         * Note that the computation is not activated by calling this function, you must call activate() for that!
+         * @param sourceTexture The texture to read the values from. The values should be in the red channel.
+         * @param depthRedux Indicates if the texture is a depth texture or not
+         * @param type The type of the textures created for the reduction (defaults to TEXTURETYPE_HALF_FLOAT)
+         * @param forceFullscreenViewport Forces the post processes used for the reduction to be applied without taking into account viewport (defaults to true)
+         */
+        setSourceTexture(sourceTexture: RenderTargetTexture, depthRedux: boolean, type?: number, forceFullscreenViewport?: boolean): void;
+        /**
+         * Defines the refresh rate of the computation.
+         * Use 0 to compute just once, 1 to compute on every frame, 2 to compute every two frames and so on...
+         */
+        get refreshRate(): number;
+        set refreshRate(value: number);
+        protected _activated: boolean;
+        /**
+         * Gets the activation status of the reducer
+         */
+        get activated(): boolean;
+        /**
+         * Activates the reduction computation.
+         * When activated, the observers registered in onAfterReductionPerformed are
+         * called after the compuation is performed
+         */
+        activate(): void;
+        /**
+         * Deactivates the reduction computation.
+         */
+        deactivate(): void;
+        /**
+         * Disposes the min/max reducer
+         * @param disposeAll true to dispose all the resources. You should always call this function with true as the parameter (or without any parameter as it is the default one). This flag is meant to be used internally.
+         */
+        dispose(disposeAll?: boolean): void;
+    }
+}
+declare module BABYLON {
+    /**
+     * This class is a small wrapper around the MinMaxReducer class to compute the min/max values of a depth texture
+     */
+    export class DepthReducer extends MinMaxReducer {
+        private _depthRenderer;
+        private _depthRendererId;
+        /**
+         * Gets the depth renderer used for the computation.
+         * Note that the result is null if you provide your own renderer when calling setDepthRenderer.
+         */
+        get depthRenderer(): Nullable<DepthRenderer>;
+        /**
+         * Creates a depth reducer
+         * @param camera The camera used to render the depth texture
+         */
+        constructor(camera: Camera);
+        /**
+         * Sets the depth renderer to use to generate the depth map
+         * @param depthRenderer The depth renderer to use. If not provided, a new one will be created automatically
+         * @param type The texture type of the depth map (default: TEXTURETYPE_HALF_FLOAT)
+         * @param forceFullscreenViewport Forces the post processes used for the reduction to be applied without taking into account viewport (defaults to true)
+         */
+        setDepthRenderer(depthRenderer?: Nullable<DepthRenderer>, type?: number, forceFullscreenViewport?: boolean): void;
+        /** @hidden */
+        setSourceTexture(sourceTexture: RenderTargetTexture, depthRedux: boolean, type?: number, forceFullscreenViewport?: boolean): void;
+        /**
+         * Activates the reduction computation.
+         * When activated, the observers registered in onAfterReductionPerformed are
+         * called after the compuation is performed
+         */
+        activate(): void;
+        /**
+         * Deactivates the reduction computation.
+         */
+        deactivate(): void;
+        /**
+         * Disposes the depth reducer
+         * @param disposeAll true to dispose all the resources. You should always call this function with true as the parameter (or without any parameter as it is the default one). This flag is meant to be used internally.
+         */
+        dispose(disposeAll?: boolean): void;
+    }
+}
+declare module BABYLON {
     /**
      * A CSM implementation allowing casting shadows on large scenes.
      * Documentation : https://doc.babylonjs.com/babylon101/cascadedShadows
@@ -54348,6 +54532,38 @@ declare module BABYLON {
          * @returns the cascade view matrix
          */
         getCascadeViewMatrix(cascadeNum: number): Nullable<Matrix>;
+        private _depthRenderer;
+        /**
+         * Sets the depth renderer to use when autoCalcDepthBounds is enabled.
+         *
+         * Note that if no depth renderer is set, a new one will be automatically created internally when necessary.
+         *
+         * You should call this function if you already have a depth renderer enabled in your scene, to avoid
+         * doing multiple depth rendering each frame. If you provide your own depth renderer, make sure it stores linear depth!
+         * @param depthRenderer The depth renderer to use when autoCalcDepthBounds is enabled. If you pass null or don't call this function at all, a depth renderer will be automatically created
+         */
+        setDepthRenderer(depthRenderer: Nullable<DepthRenderer>): void;
+        private _depthReducer;
+        private _autoCalcDepthBounds;
+        /**
+         * Gets or sets the autoCalcDepthBounds property.
+         *
+         * When enabled, a depth rendering pass is first performed (with an internally created depth renderer or with the one
+         * you provide by calling setDepthRenderer). Then, a min/max reducing is applied on the depth map to compute the
+         * minimal and maximal depth of the map and those values are used as inputs for the setMinMaxDistance() function.
+         * It can greatly enhance the shadow quality, at the expense of more GPU works.
+         * When using this option, you should increase the value of the lambda parameter, and even set it to 1 for best results.
+         */
+        get autoCalcDepthBounds(): boolean;
+        set autoCalcDepthBounds(value: boolean);
+        /**
+         * Defines the refresh rate of the min/max computation used when autoCalcDepthBounds is set to true
+         * Use 0 to compute just once, 1 to compute on every frame, 2 to compute every two frames and so on...
+         * Note that if you provided your own depth renderer through a call to setDepthRenderer, you are responsible
+         * for setting the refresh rate on the renderer yourself!
+         */
+        get autoCalcDepthBoundsRefreshRate(): number;
+        set autoCalcDepthBoundsRefreshRate(value: number);
         /**
          * Create the cascade breaks according to the lambda, shadowMaxZ and min/max distance properties, as well as the camera near and far planes.
          * This function is automatically called when updating lambda, shadowMaxZ and min/max distances, however you should call it yourself if
@@ -65964,13 +66180,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /** @hidden */
-    export var depthVertexShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module BABYLON {
-    /** @hidden */
     export var volumetricLightScatteringPixelShader: {
         name: string;
         shader: string;
@@ -66195,62 +66404,6 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
-    /** @hidden */
-    export var depthPixelShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module BABYLON {
-    /**
-     * This represents a depth renderer in Babylon.
-     * A depth renderer will render to it's depth map every frame which can be displayed or used in post processing
-     */
-    export class DepthRenderer {
-        private _scene;
-        private _depthMap;
-        private _effect;
-        private readonly _storeNonLinearDepth;
-        private readonly _clearColor;
-        /** Get if the depth renderer is using packed depth or not */
-        readonly isPacked: boolean;
-        private _cachedDefines;
-        private _camera;
-        /**
-         * Specifiess that the depth renderer will only be used within
-         * the camera it is created for.
-         * This can help forcing its rendering during the camera processing.
-         */
-        useOnlyInActiveCamera: boolean;
-        /** @hidden */
-        static _SceneComponentInitialization: (scene: Scene) => void;
-        /**
-         * Instantiates a depth renderer
-         * @param scene The scene the renderer belongs to
-         * @param type The texture type of the depth map (default: Engine.TEXTURETYPE_FLOAT)
-         * @param camera The camera to be used to render the depth map (default: scene's active camera)
-         * @param storeNonLinearDepth Defines whether the depth is stored linearly like in Babylon Shadows or directly like glFragCoord.z
-         */
-        constructor(scene: Scene, type?: number, camera?: Nullable<Camera>, storeNonLinearDepth?: boolean);
-        /**
-         * Creates the depth rendering effect and checks if the effect is ready.
-         * @param subMesh The submesh to be used to render the depth map of
-         * @param useInstances If multiple world instances should be used
-         * @returns if the depth renderer is ready to render the depth map
-         */
-        isReady(subMesh: SubMesh, useInstances: boolean): boolean;
-        /**
-         * Gets the texture which the depth map will be written to.
-         * @returns The depth map texture
-         */
-        getDepthMap(): RenderTargetTexture;
-        /**
-         * Disposes of the depth renderer.
-         */
-        dispose(): void;
-    }
-}
-declare module BABYLON {
         interface Scene {
             /** @hidden (Backing field) */
             _depthRenderer: {

Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/babylon.js


Файловите разлики са ограничени, защото са твърде много
+ 487 - 31
dist/preview release/babylon.max.js


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/babylon.max.js.map


+ 469 - 147
dist/preview release/babylon.module.d.ts

@@ -11563,9 +11563,9 @@ declare module "babylonjs/sceneComponent" {
         static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW: number;
         static readonly STEP_AFTERCAMERADRAW_LAYER: number;
         static readonly STEP_AFTERRENDER_AUDIO: number;
-        static readonly STEP_GATHERRENDERTARGETS_SHADOWGENERATOR: number;
-        static readonly STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER: number;
         static readonly STEP_GATHERRENDERTARGETS_DEPTHRENDERER: number;
+        static readonly STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER: number;
+        static readonly STEP_GATHERRENDERTARGETS_SHADOWGENERATOR: number;
         static readonly STEP_GATHERRENDERTARGETS_POSTPROCESSRENDERPIPELINEMANAGER: number;
         static readonly STEP_GATHERACTIVECAMERARENDERTARGETS_DEPTHRENDERER: number;
         static readonly STEP_POINTERMOVE_SPRITE: number;
@@ -45280,7 +45280,6 @@ declare module "babylonjs/Cameras/XR/webXRController" {
          * Pointer which can be used to select objects or attach a visible laser to
          */
         pointer: AbstractMesh;
-        private _gamepadMode;
         /**
          * If available, this is the gamepad object related to this controller.
          * Using this object it is possible to get click events and trackpad changes of the
@@ -56396,6 +56395,219 @@ declare module "babylonjs/LensFlares/index" {
     export * from "babylonjs/LensFlares/lensFlareSystem";
     export * from "babylonjs/LensFlares/lensFlareSystemSceneComponent";
 }
+declare module "babylonjs/Shaders/depth.fragment" {
+    import "babylonjs/Shaders/ShadersInclude/packingFunctions";
+    /** @hidden */
+    export var depthPixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module "babylonjs/Shaders/depth.vertex" {
+    import "babylonjs/Shaders/ShadersInclude/bonesDeclaration";
+    import "babylonjs/Shaders/ShadersInclude/morphTargetsVertexGlobalDeclaration";
+    import "babylonjs/Shaders/ShadersInclude/morphTargetsVertexDeclaration";
+    import "babylonjs/Shaders/ShadersInclude/instancesDeclaration";
+    import "babylonjs/Shaders/ShadersInclude/morphTargetsVertex";
+    import "babylonjs/Shaders/ShadersInclude/instancesVertex";
+    import "babylonjs/Shaders/ShadersInclude/bonesVertex";
+    /** @hidden */
+    export var depthVertexShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module "babylonjs/Rendering/depthRenderer" {
+    import { Nullable } from "babylonjs/types";
+    import { SubMesh } from "babylonjs/Meshes/subMesh";
+    import { Scene } from "babylonjs/scene";
+    import { RenderTargetTexture } from "babylonjs/Materials/Textures/renderTargetTexture";
+    import { Camera } from "babylonjs/Cameras/camera";
+    import "babylonjs/Shaders/depth.fragment";
+    import "babylonjs/Shaders/depth.vertex";
+    /**
+     * This represents a depth renderer in Babylon.
+     * A depth renderer will render to it's depth map every frame which can be displayed or used in post processing
+     */
+    export class DepthRenderer {
+        private _scene;
+        private _depthMap;
+        private _effect;
+        private readonly _storeNonLinearDepth;
+        private readonly _clearColor;
+        /** Get if the depth renderer is using packed depth or not */
+        readonly isPacked: boolean;
+        private _cachedDefines;
+        private _camera;
+        /** Enable or disable the depth renderer. When disabled, the depth texture is not updated */
+        enabled: boolean;
+        /**
+         * Specifiess that the depth renderer will only be used within
+         * the camera it is created for.
+         * This can help forcing its rendering during the camera processing.
+         */
+        useOnlyInActiveCamera: boolean;
+        /** @hidden */
+        static _SceneComponentInitialization: (scene: Scene) => void;
+        /**
+         * Instantiates a depth renderer
+         * @param scene The scene the renderer belongs to
+         * @param type The texture type of the depth map (default: Engine.TEXTURETYPE_FLOAT)
+         * @param camera The camera to be used to render the depth map (default: scene's active camera)
+         * @param storeNonLinearDepth Defines whether the depth is stored linearly like in Babylon Shadows or directly like glFragCoord.z
+         */
+        constructor(scene: Scene, type?: number, camera?: Nullable<Camera>, storeNonLinearDepth?: boolean);
+        /**
+         * Creates the depth rendering effect and checks if the effect is ready.
+         * @param subMesh The submesh to be used to render the depth map of
+         * @param useInstances If multiple world instances should be used
+         * @returns if the depth renderer is ready to render the depth map
+         */
+        isReady(subMesh: SubMesh, useInstances: boolean): boolean;
+        /**
+         * Gets the texture which the depth map will be written to.
+         * @returns The depth map texture
+         */
+        getDepthMap(): RenderTargetTexture;
+        /**
+         * Disposes of the depth renderer.
+         */
+        dispose(): void;
+    }
+}
+declare module "babylonjs/Shaders/minmaxRedux.fragment" {
+    /** @hidden */
+    export var minmaxReduxPixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module "babylonjs/Misc/minMaxReducer" {
+    import { Nullable } from "babylonjs/types";
+    import { RenderTargetTexture } from "babylonjs/Materials/Textures/renderTargetTexture";
+    import { Camera } from "babylonjs/Cameras/camera";
+    import { Observer } from "babylonjs/Misc/observable";
+    import { PostProcess } from "babylonjs/PostProcesses/postProcess";
+    import { PostProcessManager } from "babylonjs/PostProcesses/postProcessManager";
+    import { Observable } from "babylonjs/Misc/observable";
+    import "babylonjs/Shaders/minmaxRedux.fragment";
+    /**
+     * This class computes a min/max reduction from a texture: it means it computes the minimum
+     * and maximum values from all values of the texture.
+     * It is performed on the GPU for better performances, thanks to a succession of post processes.
+     * The source values are read from the red channel of the texture.
+     */
+    export class MinMaxReducer {
+        /**
+         * Observable triggered when the computation has been performed
+         */
+        onAfterReductionPerformed: Observable<{
+            min: number;
+            max: number;
+        }>;
+        protected _camera: Camera;
+        protected _sourceTexture: Nullable<RenderTargetTexture>;
+        protected _reductionSteps: Nullable<Array<PostProcess>>;
+        protected _postProcessManager: PostProcessManager;
+        protected _onAfterUnbindObserver: Nullable<Observer<RenderTargetTexture>>;
+        protected _forceFullscreenViewport: boolean;
+        /**
+         * Creates a min/max reducer
+         * @param camera The camera to use for the post processes
+         */
+        constructor(camera: Camera);
+        /**
+         * Gets the texture used to read the values from.
+         */
+        get sourceTexture(): Nullable<RenderTargetTexture>;
+        /**
+         * Sets the source texture to read the values from.
+         * One must indicate if the texture is a depth texture or not through the depthRedux parameter
+         * because in such textures '1' value must not be taken into account to compute the maximum
+         * as this value is used to clear the texture.
+         * Note that the computation is not activated by calling this function, you must call activate() for that!
+         * @param sourceTexture The texture to read the values from. The values should be in the red channel.
+         * @param depthRedux Indicates if the texture is a depth texture or not
+         * @param type The type of the textures created for the reduction (defaults to TEXTURETYPE_HALF_FLOAT)
+         * @param forceFullscreenViewport Forces the post processes used for the reduction to be applied without taking into account viewport (defaults to true)
+         */
+        setSourceTexture(sourceTexture: RenderTargetTexture, depthRedux: boolean, type?: number, forceFullscreenViewport?: boolean): void;
+        /**
+         * Defines the refresh rate of the computation.
+         * Use 0 to compute just once, 1 to compute on every frame, 2 to compute every two frames and so on...
+         */
+        get refreshRate(): number;
+        set refreshRate(value: number);
+        protected _activated: boolean;
+        /**
+         * Gets the activation status of the reducer
+         */
+        get activated(): boolean;
+        /**
+         * Activates the reduction computation.
+         * When activated, the observers registered in onAfterReductionPerformed are
+         * called after the compuation is performed
+         */
+        activate(): void;
+        /**
+         * Deactivates the reduction computation.
+         */
+        deactivate(): void;
+        /**
+         * Disposes the min/max reducer
+         * @param disposeAll true to dispose all the resources. You should always call this function with true as the parameter (or without any parameter as it is the default one). This flag is meant to be used internally.
+         */
+        dispose(disposeAll?: boolean): void;
+    }
+}
+declare module "babylonjs/Misc/depthReducer" {
+    import { Nullable } from "babylonjs/types";
+    import { RenderTargetTexture } from "babylonjs/Materials/Textures/renderTargetTexture";
+    import { Camera } from "babylonjs/Cameras/camera";
+    import { DepthRenderer } from "babylonjs/Rendering/depthRenderer";
+    import { MinMaxReducer } from "babylonjs/Misc/minMaxReducer";
+    /**
+     * This class is a small wrapper around the MinMaxReducer class to compute the min/max values of a depth texture
+     */
+    export class DepthReducer extends MinMaxReducer {
+        private _depthRenderer;
+        private _depthRendererId;
+        /**
+         * Gets the depth renderer used for the computation.
+         * Note that the result is null if you provide your own renderer when calling setDepthRenderer.
+         */
+        get depthRenderer(): Nullable<DepthRenderer>;
+        /**
+         * Creates a depth reducer
+         * @param camera The camera used to render the depth texture
+         */
+        constructor(camera: Camera);
+        /**
+         * Sets the depth renderer to use to generate the depth map
+         * @param depthRenderer The depth renderer to use. If not provided, a new one will be created automatically
+         * @param type The texture type of the depth map (default: TEXTURETYPE_HALF_FLOAT)
+         * @param forceFullscreenViewport Forces the post processes used for the reduction to be applied without taking into account viewport (defaults to true)
+         */
+        setDepthRenderer(depthRenderer?: Nullable<DepthRenderer>, type?: number, forceFullscreenViewport?: boolean): void;
+        /** @hidden */
+        setSourceTexture(sourceTexture: RenderTargetTexture, depthRedux: boolean, type?: number, forceFullscreenViewport?: boolean): void;
+        /**
+         * Activates the reduction computation.
+         * When activated, the observers registered in onAfterReductionPerformed are
+         * called after the compuation is performed
+         */
+        activate(): void;
+        /**
+         * Deactivates the reduction computation.
+         */
+        deactivate(): void;
+        /**
+         * Disposes the depth reducer
+         * @param disposeAll true to dispose all the resources. You should always call this function with true as the parameter (or without any parameter as it is the default one). This flag is meant to be used internally.
+         */
+        dispose(disposeAll?: boolean): void;
+    }
+}
 declare module "babylonjs/Lights/Shadows/cascadedShadowGenerator" {
     import { Nullable } from "babylonjs/types";
     import { Scene } from "babylonjs/scene";
@@ -56412,6 +56624,7 @@ declare module "babylonjs/Lights/Shadows/cascadedShadowGenerator" {
     import { IShadowGenerator } from "babylonjs/Lights/Shadows/shadowGenerator";
     import { DirectionalLight } from "babylonjs/Lights/directionalLight";
     import { BoundingInfo } from "babylonjs/Culling/boundingInfo";
+    import { DepthRenderer } from "babylonjs/Rendering/depthRenderer";
     /**
      * A CSM implementation allowing casting shadows on large scenes.
      * Documentation : https://doc.babylonjs.com/babylon101/cascadedShadows
@@ -56770,6 +56983,38 @@ declare module "babylonjs/Lights/Shadows/cascadedShadowGenerator" {
          * @returns the cascade view matrix
          */
         getCascadeViewMatrix(cascadeNum: number): Nullable<Matrix>;
+        private _depthRenderer;
+        /**
+         * Sets the depth renderer to use when autoCalcDepthBounds is enabled.
+         *
+         * Note that if no depth renderer is set, a new one will be automatically created internally when necessary.
+         *
+         * You should call this function if you already have a depth renderer enabled in your scene, to avoid
+         * doing multiple depth rendering each frame. If you provide your own depth renderer, make sure it stores linear depth!
+         * @param depthRenderer The depth renderer to use when autoCalcDepthBounds is enabled. If you pass null or don't call this function at all, a depth renderer will be automatically created
+         */
+        setDepthRenderer(depthRenderer: Nullable<DepthRenderer>): void;
+        private _depthReducer;
+        private _autoCalcDepthBounds;
+        /**
+         * Gets or sets the autoCalcDepthBounds property.
+         *
+         * When enabled, a depth rendering pass is first performed (with an internally created depth renderer or with the one
+         * you provide by calling setDepthRenderer). Then, a min/max reducing is applied on the depth map to compute the
+         * minimal and maximal depth of the map and those values are used as inputs for the setMinMaxDistance() function.
+         * It can greatly enhance the shadow quality, at the expense of more GPU works.
+         * When using this option, you should increase the value of the lambda parameter, and even set it to 1 for best results.
+         */
+        get autoCalcDepthBounds(): boolean;
+        set autoCalcDepthBounds(value: boolean);
+        /**
+         * Defines the refresh rate of the min/max computation used when autoCalcDepthBounds is set to true
+         * Use 0 to compute just once, 1 to compute on every frame, 2 to compute every two frames and so on...
+         * Note that if you provided your own depth renderer through a call to setDepthRenderer, you are responsible
+         * for setting the refresh rate on the renderer yourself!
+         */
+        get autoCalcDepthBoundsRefreshRate(): number;
+        set autoCalcDepthBoundsRefreshRate(value: number);
         /**
          * Create the cascade breaks according to the lambda, shadowMaxZ and min/max distance properties, as well as the camera near and far planes.
          * This function is automatically called when updating lambda, shadowMaxZ and min/max distances, however you should call it yourself if
@@ -69461,20 +69706,6 @@ declare module "babylonjs/PostProcesses/tonemapPostProcess" {
         exposureAdjustment: number, camera: Camera, samplingMode?: number, engine?: Engine, textureFormat?: number);
     }
 }
-declare module "babylonjs/Shaders/depth.vertex" {
-    import "babylonjs/Shaders/ShadersInclude/bonesDeclaration";
-    import "babylonjs/Shaders/ShadersInclude/morphTargetsVertexGlobalDeclaration";
-    import "babylonjs/Shaders/ShadersInclude/morphTargetsVertexDeclaration";
-    import "babylonjs/Shaders/ShadersInclude/instancesDeclaration";
-    import "babylonjs/Shaders/ShadersInclude/morphTargetsVertex";
-    import "babylonjs/Shaders/ShadersInclude/instancesVertex";
-    import "babylonjs/Shaders/ShadersInclude/bonesVertex";
-    /** @hidden */
-    export var depthVertexShader: {
-        name: string;
-        shader: string;
-    };
-}
 declare module "babylonjs/Shaders/volumetricLightScattering.fragment" {
     /** @hidden */
     export var volumetricLightScatteringPixelShader: {
@@ -69769,70 +70000,6 @@ declare module "babylonjs/Rendering/boundingBoxRenderer" {
         dispose(): void;
     }
 }
-declare module "babylonjs/Shaders/depth.fragment" {
-    import "babylonjs/Shaders/ShadersInclude/packingFunctions";
-    /** @hidden */
-    export var depthPixelShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module "babylonjs/Rendering/depthRenderer" {
-    import { Nullable } from "babylonjs/types";
-    import { SubMesh } from "babylonjs/Meshes/subMesh";
-    import { Scene } from "babylonjs/scene";
-    import { RenderTargetTexture } from "babylonjs/Materials/Textures/renderTargetTexture";
-    import { Camera } from "babylonjs/Cameras/camera";
-    import "babylonjs/Shaders/depth.fragment";
-    import "babylonjs/Shaders/depth.vertex";
-    /**
-     * This represents a depth renderer in Babylon.
-     * A depth renderer will render to it's depth map every frame which can be displayed or used in post processing
-     */
-    export class DepthRenderer {
-        private _scene;
-        private _depthMap;
-        private _effect;
-        private readonly _storeNonLinearDepth;
-        private readonly _clearColor;
-        /** Get if the depth renderer is using packed depth or not */
-        readonly isPacked: boolean;
-        private _cachedDefines;
-        private _camera;
-        /**
-         * Specifiess that the depth renderer will only be used within
-         * the camera it is created for.
-         * This can help forcing its rendering during the camera processing.
-         */
-        useOnlyInActiveCamera: boolean;
-        /** @hidden */
-        static _SceneComponentInitialization: (scene: Scene) => void;
-        /**
-         * Instantiates a depth renderer
-         * @param scene The scene the renderer belongs to
-         * @param type The texture type of the depth map (default: Engine.TEXTURETYPE_FLOAT)
-         * @param camera The camera to be used to render the depth map (default: scene's active camera)
-         * @param storeNonLinearDepth Defines whether the depth is stored linearly like in Babylon Shadows or directly like glFragCoord.z
-         */
-        constructor(scene: Scene, type?: number, camera?: Nullable<Camera>, storeNonLinearDepth?: boolean);
-        /**
-         * Creates the depth rendering effect and checks if the effect is ready.
-         * @param subMesh The submesh to be used to render the depth map of
-         * @param useInstances If multiple world instances should be used
-         * @returns if the depth renderer is ready to render the depth map
-         */
-        isReady(subMesh: SubMesh, useInstances: boolean): boolean;
-        /**
-         * Gets the texture which the depth map will be written to.
-         * @returns The depth map texture
-         */
-        getDepthMap(): RenderTargetTexture;
-        /**
-         * Disposes of the depth renderer.
-         */
-        dispose(): void;
-    }
-}
 declare module "babylonjs/Rendering/depthRendererSceneComponent" {
     import { Nullable } from "babylonjs/types";
     import { Scene } from "babylonjs/scene";
@@ -72077,6 +72244,8 @@ declare module "babylonjs/Misc/index" {
     export * from "babylonjs/Misc/fileTools";
     export * from "babylonjs/Misc/stringTools";
     export * from "babylonjs/Misc/dataReader";
+    export * from "babylonjs/Misc/minMaxReducer";
+    export * from "babylonjs/Misc/depthReducer";
 }
 declare module "babylonjs/index" {
     export * from "babylonjs/abstractScene";
@@ -83593,9 +83762,9 @@ declare module BABYLON {
         static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW: number;
         static readonly STEP_AFTERCAMERADRAW_LAYER: number;
         static readonly STEP_AFTERRENDER_AUDIO: number;
-        static readonly STEP_GATHERRENDERTARGETS_SHADOWGENERATOR: number;
-        static readonly STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER: number;
         static readonly STEP_GATHERRENDERTARGETS_DEPTHRENDERER: number;
+        static readonly STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER: number;
+        static readonly STEP_GATHERRENDERTARGETS_SHADOWGENERATOR: number;
         static readonly STEP_GATHERRENDERTARGETS_POSTPROCESSRENDERPIPELINEMANAGER: number;
         static readonly STEP_GATHERACTIVECAMERARENDERTARGETS_DEPTHRENDERER: number;
         static readonly STEP_POINTERMOVE_SPRITE: number;
@@ -115989,7 +116158,6 @@ declare module BABYLON {
          * Pointer which can be used to select objects or attach a visible laser to
          */
         pointer: AbstractMesh;
-        private _gamepadMode;
         /**
          * If available, this is the gamepad object related to this controller.
          * Using this object it is possible to get click events and trackpad changes of the
@@ -126221,6 +126389,191 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
+    /** @hidden */
+    export var depthPixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /** @hidden */
+    export var depthVertexShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /**
+     * This represents a depth renderer in Babylon.
+     * A depth renderer will render to it's depth map every frame which can be displayed or used in post processing
+     */
+    export class DepthRenderer {
+        private _scene;
+        private _depthMap;
+        private _effect;
+        private readonly _storeNonLinearDepth;
+        private readonly _clearColor;
+        /** Get if the depth renderer is using packed depth or not */
+        readonly isPacked: boolean;
+        private _cachedDefines;
+        private _camera;
+        /** Enable or disable the depth renderer. When disabled, the depth texture is not updated */
+        enabled: boolean;
+        /**
+         * Specifiess that the depth renderer will only be used within
+         * the camera it is created for.
+         * This can help forcing its rendering during the camera processing.
+         */
+        useOnlyInActiveCamera: boolean;
+        /** @hidden */
+        static _SceneComponentInitialization: (scene: Scene) => void;
+        /**
+         * Instantiates a depth renderer
+         * @param scene The scene the renderer belongs to
+         * @param type The texture type of the depth map (default: Engine.TEXTURETYPE_FLOAT)
+         * @param camera The camera to be used to render the depth map (default: scene's active camera)
+         * @param storeNonLinearDepth Defines whether the depth is stored linearly like in Babylon Shadows or directly like glFragCoord.z
+         */
+        constructor(scene: Scene, type?: number, camera?: Nullable<Camera>, storeNonLinearDepth?: boolean);
+        /**
+         * Creates the depth rendering effect and checks if the effect is ready.
+         * @param subMesh The submesh to be used to render the depth map of
+         * @param useInstances If multiple world instances should be used
+         * @returns if the depth renderer is ready to render the depth map
+         */
+        isReady(subMesh: SubMesh, useInstances: boolean): boolean;
+        /**
+         * Gets the texture which the depth map will be written to.
+         * @returns The depth map texture
+         */
+        getDepthMap(): RenderTargetTexture;
+        /**
+         * Disposes of the depth renderer.
+         */
+        dispose(): void;
+    }
+}
+declare module BABYLON {
+    /** @hidden */
+    export var minmaxReduxPixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /**
+     * This class computes a min/max reduction from a texture: it means it computes the minimum
+     * and maximum values from all values of the texture.
+     * It is performed on the GPU for better performances, thanks to a succession of post processes.
+     * The source values are read from the red channel of the texture.
+     */
+    export class MinMaxReducer {
+        /**
+         * Observable triggered when the computation has been performed
+         */
+        onAfterReductionPerformed: Observable<{
+            min: number;
+            max: number;
+        }>;
+        protected _camera: Camera;
+        protected _sourceTexture: Nullable<RenderTargetTexture>;
+        protected _reductionSteps: Nullable<Array<PostProcess>>;
+        protected _postProcessManager: PostProcessManager;
+        protected _onAfterUnbindObserver: Nullable<Observer<RenderTargetTexture>>;
+        protected _forceFullscreenViewport: boolean;
+        /**
+         * Creates a min/max reducer
+         * @param camera The camera to use for the post processes
+         */
+        constructor(camera: Camera);
+        /**
+         * Gets the texture used to read the values from.
+         */
+        get sourceTexture(): Nullable<RenderTargetTexture>;
+        /**
+         * Sets the source texture to read the values from.
+         * One must indicate if the texture is a depth texture or not through the depthRedux parameter
+         * because in such textures '1' value must not be taken into account to compute the maximum
+         * as this value is used to clear the texture.
+         * Note that the computation is not activated by calling this function, you must call activate() for that!
+         * @param sourceTexture The texture to read the values from. The values should be in the red channel.
+         * @param depthRedux Indicates if the texture is a depth texture or not
+         * @param type The type of the textures created for the reduction (defaults to TEXTURETYPE_HALF_FLOAT)
+         * @param forceFullscreenViewport Forces the post processes used for the reduction to be applied without taking into account viewport (defaults to true)
+         */
+        setSourceTexture(sourceTexture: RenderTargetTexture, depthRedux: boolean, type?: number, forceFullscreenViewport?: boolean): void;
+        /**
+         * Defines the refresh rate of the computation.
+         * Use 0 to compute just once, 1 to compute on every frame, 2 to compute every two frames and so on...
+         */
+        get refreshRate(): number;
+        set refreshRate(value: number);
+        protected _activated: boolean;
+        /**
+         * Gets the activation status of the reducer
+         */
+        get activated(): boolean;
+        /**
+         * Activates the reduction computation.
+         * When activated, the observers registered in onAfterReductionPerformed are
+         * called after the compuation is performed
+         */
+        activate(): void;
+        /**
+         * Deactivates the reduction computation.
+         */
+        deactivate(): void;
+        /**
+         * Disposes the min/max reducer
+         * @param disposeAll true to dispose all the resources. You should always call this function with true as the parameter (or without any parameter as it is the default one). This flag is meant to be used internally.
+         */
+        dispose(disposeAll?: boolean): void;
+    }
+}
+declare module BABYLON {
+    /**
+     * This class is a small wrapper around the MinMaxReducer class to compute the min/max values of a depth texture
+     */
+    export class DepthReducer extends MinMaxReducer {
+        private _depthRenderer;
+        private _depthRendererId;
+        /**
+         * Gets the depth renderer used for the computation.
+         * Note that the result is null if you provide your own renderer when calling setDepthRenderer.
+         */
+        get depthRenderer(): Nullable<DepthRenderer>;
+        /**
+         * Creates a depth reducer
+         * @param camera The camera used to render the depth texture
+         */
+        constructor(camera: Camera);
+        /**
+         * Sets the depth renderer to use to generate the depth map
+         * @param depthRenderer The depth renderer to use. If not provided, a new one will be created automatically
+         * @param type The texture type of the depth map (default: TEXTURETYPE_HALF_FLOAT)
+         * @param forceFullscreenViewport Forces the post processes used for the reduction to be applied without taking into account viewport (defaults to true)
+         */
+        setDepthRenderer(depthRenderer?: Nullable<DepthRenderer>, type?: number, forceFullscreenViewport?: boolean): void;
+        /** @hidden */
+        setSourceTexture(sourceTexture: RenderTargetTexture, depthRedux: boolean, type?: number, forceFullscreenViewport?: boolean): void;
+        /**
+         * Activates the reduction computation.
+         * When activated, the observers registered in onAfterReductionPerformed are
+         * called after the compuation is performed
+         */
+        activate(): void;
+        /**
+         * Deactivates the reduction computation.
+         */
+        deactivate(): void;
+        /**
+         * Disposes the depth reducer
+         * @param disposeAll true to dispose all the resources. You should always call this function with true as the parameter (or without any parameter as it is the default one). This flag is meant to be used internally.
+         */
+        dispose(disposeAll?: boolean): void;
+    }
+}
+declare module BABYLON {
     /**
      * A CSM implementation allowing casting shadows on large scenes.
      * Documentation : https://doc.babylonjs.com/babylon101/cascadedShadows
@@ -126579,6 +126932,38 @@ declare module BABYLON {
          * @returns the cascade view matrix
          */
         getCascadeViewMatrix(cascadeNum: number): Nullable<Matrix>;
+        private _depthRenderer;
+        /**
+         * Sets the depth renderer to use when autoCalcDepthBounds is enabled.
+         *
+         * Note that if no depth renderer is set, a new one will be automatically created internally when necessary.
+         *
+         * You should call this function if you already have a depth renderer enabled in your scene, to avoid
+         * doing multiple depth rendering each frame. If you provide your own depth renderer, make sure it stores linear depth!
+         * @param depthRenderer The depth renderer to use when autoCalcDepthBounds is enabled. If you pass null or don't call this function at all, a depth renderer will be automatically created
+         */
+        setDepthRenderer(depthRenderer: Nullable<DepthRenderer>): void;
+        private _depthReducer;
+        private _autoCalcDepthBounds;
+        /**
+         * Gets or sets the autoCalcDepthBounds property.
+         *
+         * When enabled, a depth rendering pass is first performed (with an internally created depth renderer or with the one
+         * you provide by calling setDepthRenderer). Then, a min/max reducing is applied on the depth map to compute the
+         * minimal and maximal depth of the map and those values are used as inputs for the setMinMaxDistance() function.
+         * It can greatly enhance the shadow quality, at the expense of more GPU works.
+         * When using this option, you should increase the value of the lambda parameter, and even set it to 1 for best results.
+         */
+        get autoCalcDepthBounds(): boolean;
+        set autoCalcDepthBounds(value: boolean);
+        /**
+         * Defines the refresh rate of the min/max computation used when autoCalcDepthBounds is set to true
+         * Use 0 to compute just once, 1 to compute on every frame, 2 to compute every two frames and so on...
+         * Note that if you provided your own depth renderer through a call to setDepthRenderer, you are responsible
+         * for setting the refresh rate on the renderer yourself!
+         */
+        get autoCalcDepthBoundsRefreshRate(): number;
+        set autoCalcDepthBoundsRefreshRate(value: number);
         /**
          * Create the cascade breaks according to the lambda, shadowMaxZ and min/max distance properties, as well as the camera near and far planes.
          * This function is automatically called when updating lambda, shadowMaxZ and min/max distances, however you should call it yourself if
@@ -138195,13 +138580,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /** @hidden */
-    export var depthVertexShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module BABYLON {
-    /** @hidden */
     export var volumetricLightScatteringPixelShader: {
         name: string;
         shader: string;
@@ -138426,62 +138804,6 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
-    /** @hidden */
-    export var depthPixelShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module BABYLON {
-    /**
-     * This represents a depth renderer in Babylon.
-     * A depth renderer will render to it's depth map every frame which can be displayed or used in post processing
-     */
-    export class DepthRenderer {
-        private _scene;
-        private _depthMap;
-        private _effect;
-        private readonly _storeNonLinearDepth;
-        private readonly _clearColor;
-        /** Get if the depth renderer is using packed depth or not */
-        readonly isPacked: boolean;
-        private _cachedDefines;
-        private _camera;
-        /**
-         * Specifiess that the depth renderer will only be used within
-         * the camera it is created for.
-         * This can help forcing its rendering during the camera processing.
-         */
-        useOnlyInActiveCamera: boolean;
-        /** @hidden */
-        static _SceneComponentInitialization: (scene: Scene) => void;
-        /**
-         * Instantiates a depth renderer
-         * @param scene The scene the renderer belongs to
-         * @param type The texture type of the depth map (default: Engine.TEXTURETYPE_FLOAT)
-         * @param camera The camera to be used to render the depth map (default: scene's active camera)
-         * @param storeNonLinearDepth Defines whether the depth is stored linearly like in Babylon Shadows or directly like glFragCoord.z
-         */
-        constructor(scene: Scene, type?: number, camera?: Nullable<Camera>, storeNonLinearDepth?: boolean);
-        /**
-         * Creates the depth rendering effect and checks if the effect is ready.
-         * @param subMesh The submesh to be used to render the depth map of
-         * @param useInstances If multiple world instances should be used
-         * @returns if the depth renderer is ready to render the depth map
-         */
-        isReady(subMesh: SubMesh, useInstances: boolean): boolean;
-        /**
-         * Gets the texture which the depth map will be written to.
-         * @returns The depth map texture
-         */
-        getDepthMap(): RenderTargetTexture;
-        /**
-         * Disposes of the depth renderer.
-         */
-        dispose(): void;
-    }
-}
-declare module BABYLON {
         interface Scene {
             /** @hidden (Backing field) */
             _depthRenderer: {

+ 219 - 66
dist/preview release/documentation.d.ts

@@ -11362,9 +11362,9 @@ declare module BABYLON {
         static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW: number;
         static readonly STEP_AFTERCAMERADRAW_LAYER: number;
         static readonly STEP_AFTERRENDER_AUDIO: number;
-        static readonly STEP_GATHERRENDERTARGETS_SHADOWGENERATOR: number;
-        static readonly STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER: number;
         static readonly STEP_GATHERRENDERTARGETS_DEPTHRENDERER: number;
+        static readonly STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER: number;
+        static readonly STEP_GATHERRENDERTARGETS_SHADOWGENERATOR: number;
         static readonly STEP_GATHERRENDERTARGETS_POSTPROCESSRENDERPIPELINEMANAGER: number;
         static readonly STEP_GATHERACTIVECAMERARENDERTARGETS_DEPTHRENDERER: number;
         static readonly STEP_POINTERMOVE_SPRITE: number;
@@ -43758,7 +43758,6 @@ declare module BABYLON {
          * Pointer which can be used to select objects or attach a visible laser to
          */
         pointer: AbstractMesh;
-        private _gamepadMode;
         /**
          * If available, this is the gamepad object related to this controller.
          * Using this object it is possible to get click events and trackpad changes of the
@@ -53990,6 +53989,191 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
+    /** @hidden */
+    export var depthPixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /** @hidden */
+    export var depthVertexShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /**
+     * This represents a depth renderer in Babylon.
+     * A depth renderer will render to it's depth map every frame which can be displayed or used in post processing
+     */
+    export class DepthRenderer {
+        private _scene;
+        private _depthMap;
+        private _effect;
+        private readonly _storeNonLinearDepth;
+        private readonly _clearColor;
+        /** Get if the depth renderer is using packed depth or not */
+        readonly isPacked: boolean;
+        private _cachedDefines;
+        private _camera;
+        /** Enable or disable the depth renderer. When disabled, the depth texture is not updated */
+        enabled: boolean;
+        /**
+         * Specifiess that the depth renderer will only be used within
+         * the camera it is created for.
+         * This can help forcing its rendering during the camera processing.
+         */
+        useOnlyInActiveCamera: boolean;
+        /** @hidden */
+        static _SceneComponentInitialization: (scene: Scene) => void;
+        /**
+         * Instantiates a depth renderer
+         * @param scene The scene the renderer belongs to
+         * @param type The texture type of the depth map (default: Engine.TEXTURETYPE_FLOAT)
+         * @param camera The camera to be used to render the depth map (default: scene's active camera)
+         * @param storeNonLinearDepth Defines whether the depth is stored linearly like in Babylon Shadows or directly like glFragCoord.z
+         */
+        constructor(scene: Scene, type?: number, camera?: Nullable<Camera>, storeNonLinearDepth?: boolean);
+        /**
+         * Creates the depth rendering effect and checks if the effect is ready.
+         * @param subMesh The submesh to be used to render the depth map of
+         * @param useInstances If multiple world instances should be used
+         * @returns if the depth renderer is ready to render the depth map
+         */
+        isReady(subMesh: SubMesh, useInstances: boolean): boolean;
+        /**
+         * Gets the texture which the depth map will be written to.
+         * @returns The depth map texture
+         */
+        getDepthMap(): RenderTargetTexture;
+        /**
+         * Disposes of the depth renderer.
+         */
+        dispose(): void;
+    }
+}
+declare module BABYLON {
+    /** @hidden */
+    export var minmaxReduxPixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /**
+     * This class computes a min/max reduction from a texture: it means it computes the minimum
+     * and maximum values from all values of the texture.
+     * It is performed on the GPU for better performances, thanks to a succession of post processes.
+     * The source values are read from the red channel of the texture.
+     */
+    export class MinMaxReducer {
+        /**
+         * Observable triggered when the computation has been performed
+         */
+        onAfterReductionPerformed: Observable<{
+            min: number;
+            max: number;
+        }>;
+        protected _camera: Camera;
+        protected _sourceTexture: Nullable<RenderTargetTexture>;
+        protected _reductionSteps: Nullable<Array<PostProcess>>;
+        protected _postProcessManager: PostProcessManager;
+        protected _onAfterUnbindObserver: Nullable<Observer<RenderTargetTexture>>;
+        protected _forceFullscreenViewport: boolean;
+        /**
+         * Creates a min/max reducer
+         * @param camera The camera to use for the post processes
+         */
+        constructor(camera: Camera);
+        /**
+         * Gets the texture used to read the values from.
+         */
+        get sourceTexture(): Nullable<RenderTargetTexture>;
+        /**
+         * Sets the source texture to read the values from.
+         * One must indicate if the texture is a depth texture or not through the depthRedux parameter
+         * because in such textures '1' value must not be taken into account to compute the maximum
+         * as this value is used to clear the texture.
+         * Note that the computation is not activated by calling this function, you must call activate() for that!
+         * @param sourceTexture The texture to read the values from. The values should be in the red channel.
+         * @param depthRedux Indicates if the texture is a depth texture or not
+         * @param type The type of the textures created for the reduction (defaults to TEXTURETYPE_HALF_FLOAT)
+         * @param forceFullscreenViewport Forces the post processes used for the reduction to be applied without taking into account viewport (defaults to true)
+         */
+        setSourceTexture(sourceTexture: RenderTargetTexture, depthRedux: boolean, type?: number, forceFullscreenViewport?: boolean): void;
+        /**
+         * Defines the refresh rate of the computation.
+         * Use 0 to compute just once, 1 to compute on every frame, 2 to compute every two frames and so on...
+         */
+        get refreshRate(): number;
+        set refreshRate(value: number);
+        protected _activated: boolean;
+        /**
+         * Gets the activation status of the reducer
+         */
+        get activated(): boolean;
+        /**
+         * Activates the reduction computation.
+         * When activated, the observers registered in onAfterReductionPerformed are
+         * called after the compuation is performed
+         */
+        activate(): void;
+        /**
+         * Deactivates the reduction computation.
+         */
+        deactivate(): void;
+        /**
+         * Disposes the min/max reducer
+         * @param disposeAll true to dispose all the resources. You should always call this function with true as the parameter (or without any parameter as it is the default one). This flag is meant to be used internally.
+         */
+        dispose(disposeAll?: boolean): void;
+    }
+}
+declare module BABYLON {
+    /**
+     * This class is a small wrapper around the MinMaxReducer class to compute the min/max values of a depth texture
+     */
+    export class DepthReducer extends MinMaxReducer {
+        private _depthRenderer;
+        private _depthRendererId;
+        /**
+         * Gets the depth renderer used for the computation.
+         * Note that the result is null if you provide your own renderer when calling setDepthRenderer.
+         */
+        get depthRenderer(): Nullable<DepthRenderer>;
+        /**
+         * Creates a depth reducer
+         * @param camera The camera used to render the depth texture
+         */
+        constructor(camera: Camera);
+        /**
+         * Sets the depth renderer to use to generate the depth map
+         * @param depthRenderer The depth renderer to use. If not provided, a new one will be created automatically
+         * @param type The texture type of the depth map (default: TEXTURETYPE_HALF_FLOAT)
+         * @param forceFullscreenViewport Forces the post processes used for the reduction to be applied without taking into account viewport (defaults to true)
+         */
+        setDepthRenderer(depthRenderer?: Nullable<DepthRenderer>, type?: number, forceFullscreenViewport?: boolean): void;
+        /** @hidden */
+        setSourceTexture(sourceTexture: RenderTargetTexture, depthRedux: boolean, type?: number, forceFullscreenViewport?: boolean): void;
+        /**
+         * Activates the reduction computation.
+         * When activated, the observers registered in onAfterReductionPerformed are
+         * called after the compuation is performed
+         */
+        activate(): void;
+        /**
+         * Deactivates the reduction computation.
+         */
+        deactivate(): void;
+        /**
+         * Disposes the depth reducer
+         * @param disposeAll true to dispose all the resources. You should always call this function with true as the parameter (or without any parameter as it is the default one). This flag is meant to be used internally.
+         */
+        dispose(disposeAll?: boolean): void;
+    }
+}
+declare module BABYLON {
     /**
      * A CSM implementation allowing casting shadows on large scenes.
      * Documentation : https://doc.babylonjs.com/babylon101/cascadedShadows
@@ -54348,6 +54532,38 @@ declare module BABYLON {
          * @returns the cascade view matrix
          */
         getCascadeViewMatrix(cascadeNum: number): Nullable<Matrix>;
+        private _depthRenderer;
+        /**
+         * Sets the depth renderer to use when autoCalcDepthBounds is enabled.
+         *
+         * Note that if no depth renderer is set, a new one will be automatically created internally when necessary.
+         *
+         * You should call this function if you already have a depth renderer enabled in your scene, to avoid
+         * doing multiple depth rendering each frame. If you provide your own depth renderer, make sure it stores linear depth!
+         * @param depthRenderer The depth renderer to use when autoCalcDepthBounds is enabled. If you pass null or don't call this function at all, a depth renderer will be automatically created
+         */
+        setDepthRenderer(depthRenderer: Nullable<DepthRenderer>): void;
+        private _depthReducer;
+        private _autoCalcDepthBounds;
+        /**
+         * Gets or sets the autoCalcDepthBounds property.
+         *
+         * When enabled, a depth rendering pass is first performed (with an internally created depth renderer or with the one
+         * you provide by calling setDepthRenderer). Then, a min/max reducing is applied on the depth map to compute the
+         * minimal and maximal depth of the map and those values are used as inputs for the setMinMaxDistance() function.
+         * It can greatly enhance the shadow quality, at the expense of more GPU works.
+         * When using this option, you should increase the value of the lambda parameter, and even set it to 1 for best results.
+         */
+        get autoCalcDepthBounds(): boolean;
+        set autoCalcDepthBounds(value: boolean);
+        /**
+         * Defines the refresh rate of the min/max computation used when autoCalcDepthBounds is set to true
+         * Use 0 to compute just once, 1 to compute on every frame, 2 to compute every two frames and so on...
+         * Note that if you provided your own depth renderer through a call to setDepthRenderer, you are responsible
+         * for setting the refresh rate on the renderer yourself!
+         */
+        get autoCalcDepthBoundsRefreshRate(): number;
+        set autoCalcDepthBoundsRefreshRate(value: number);
         /**
          * Create the cascade breaks according to the lambda, shadowMaxZ and min/max distance properties, as well as the camera near and far planes.
          * This function is automatically called when updating lambda, shadowMaxZ and min/max distances, however you should call it yourself if
@@ -65964,13 +66180,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /** @hidden */
-    export var depthVertexShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module BABYLON {
-    /** @hidden */
     export var volumetricLightScatteringPixelShader: {
         name: string;
         shader: string;
@@ -66195,62 +66404,6 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
-    /** @hidden */
-    export var depthPixelShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module BABYLON {
-    /**
-     * This represents a depth renderer in Babylon.
-     * A depth renderer will render to it's depth map every frame which can be displayed or used in post processing
-     */
-    export class DepthRenderer {
-        private _scene;
-        private _depthMap;
-        private _effect;
-        private readonly _storeNonLinearDepth;
-        private readonly _clearColor;
-        /** Get if the depth renderer is using packed depth or not */
-        readonly isPacked: boolean;
-        private _cachedDefines;
-        private _camera;
-        /**
-         * Specifiess that the depth renderer will only be used within
-         * the camera it is created for.
-         * This can help forcing its rendering during the camera processing.
-         */
-        useOnlyInActiveCamera: boolean;
-        /** @hidden */
-        static _SceneComponentInitialization: (scene: Scene) => void;
-        /**
-         * Instantiates a depth renderer
-         * @param scene The scene the renderer belongs to
-         * @param type The texture type of the depth map (default: Engine.TEXTURETYPE_FLOAT)
-         * @param camera The camera to be used to render the depth map (default: scene's active camera)
-         * @param storeNonLinearDepth Defines whether the depth is stored linearly like in Babylon Shadows or directly like glFragCoord.z
-         */
-        constructor(scene: Scene, type?: number, camera?: Nullable<Camera>, storeNonLinearDepth?: boolean);
-        /**
-         * Creates the depth rendering effect and checks if the effect is ready.
-         * @param subMesh The submesh to be used to render the depth map of
-         * @param useInstances If multiple world instances should be used
-         * @returns if the depth renderer is ready to render the depth map
-         */
-        isReady(subMesh: SubMesh, useInstances: boolean): boolean;
-        /**
-         * Gets the texture which the depth map will be written to.
-         * @returns The depth map texture
-         */
-        getDepthMap(): RenderTargetTexture;
-        /**
-         * Disposes of the depth renderer.
-         */
-        dispose(): void;
-    }
-}
-declare module BABYLON {
         interface Scene {
             /** @hidden (Backing field) */
             _depthRenderer: {

+ 3 - 2
dist/preview release/loaders/babylon.objFileLoader.js

@@ -1020,14 +1020,14 @@ var OBJFileLoader = /** @class */ (function () {
                 //Get the name of the material
                 materialNameFromObj = line.substring(7).trim();
                 //If this new material is in the same mesh
-                if (!isFirstMaterial) {
+                if (!isFirstMaterial || !hasMeshes) {
                     //Set the data for the previous mesh
                     addPreviousObjMesh();
                     //Create a new mesh
                     var objMesh = 
                     //Set the name of the current obj mesh
                     {
-                        name: objMeshName + "_mm" + increment.toString(),
+                        name: (objMeshName || "mesh") + "_mm" + increment.toString(),
                         indices: undefined,
                         positions: undefined,
                         normals: undefined,
@@ -1038,6 +1038,7 @@ var OBJFileLoader = /** @class */ (function () {
                     increment++;
                     //If meshes are already defined
                     meshesFromObj.push(objMesh);
+                    hasMeshes = true;
                 }
                 //Set the material name if the previous line define a mesh
                 if (hasMeshes && isFirstMaterial) {

Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.js.map


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


+ 3 - 2
dist/preview release/loaders/babylonjs.loaders.js

@@ -1249,14 +1249,14 @@ var OBJFileLoader = /** @class */ (function () {
                 //Get the name of the material
                 materialNameFromObj = line.substring(7).trim();
                 //If this new material is in the same mesh
-                if (!isFirstMaterial) {
+                if (!isFirstMaterial || !hasMeshes) {
                     //Set the data for the previous mesh
                     addPreviousObjMesh();
                     //Create a new mesh
                     var objMesh = 
                     //Set the name of the current obj mesh
                     {
-                        name: objMeshName + "_mm" + increment.toString(),
+                        name: (objMeshName || "mesh") + "_mm" + increment.toString(),
                         indices: undefined,
                         positions: undefined,
                         normals: undefined,
@@ -1267,6 +1267,7 @@ var OBJFileLoader = /** @class */ (function () {
                     increment++;
                     //If meshes are already defined
                     meshesFromObj.push(objMesh);
+                    hasMeshes = true;
                 }
                 //Set the material name if the previous line define a mesh
                 if (hasMeshes && isFirstMaterial) {

Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.js.map


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.min.js


+ 1 - 1
dist/preview release/packagesSizeBaseLine.json

@@ -1 +1 @@
-{"thinEngineOnly":112287,"engineOnly":148378,"sceneOnly":502161,"minGridMaterial":632857,"minStandardMaterial":772848}
+{"thinEngineOnly":112302,"engineOnly":148393,"sceneOnly":502176,"minGridMaterial":632872,"minStandardMaterial":772863}

+ 469 - 147
dist/preview release/viewer/babylon.module.d.ts

@@ -11563,9 +11563,9 @@ declare module "babylonjs/sceneComponent" {
         static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW: number;
         static readonly STEP_AFTERCAMERADRAW_LAYER: number;
         static readonly STEP_AFTERRENDER_AUDIO: number;
-        static readonly STEP_GATHERRENDERTARGETS_SHADOWGENERATOR: number;
-        static readonly STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER: number;
         static readonly STEP_GATHERRENDERTARGETS_DEPTHRENDERER: number;
+        static readonly STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER: number;
+        static readonly STEP_GATHERRENDERTARGETS_SHADOWGENERATOR: number;
         static readonly STEP_GATHERRENDERTARGETS_POSTPROCESSRENDERPIPELINEMANAGER: number;
         static readonly STEP_GATHERACTIVECAMERARENDERTARGETS_DEPTHRENDERER: number;
         static readonly STEP_POINTERMOVE_SPRITE: number;
@@ -45280,7 +45280,6 @@ declare module "babylonjs/Cameras/XR/webXRController" {
          * Pointer which can be used to select objects or attach a visible laser to
          */
         pointer: AbstractMesh;
-        private _gamepadMode;
         /**
          * If available, this is the gamepad object related to this controller.
          * Using this object it is possible to get click events and trackpad changes of the
@@ -56396,6 +56395,219 @@ declare module "babylonjs/LensFlares/index" {
     export * from "babylonjs/LensFlares/lensFlareSystem";
     export * from "babylonjs/LensFlares/lensFlareSystemSceneComponent";
 }
+declare module "babylonjs/Shaders/depth.fragment" {
+    import "babylonjs/Shaders/ShadersInclude/packingFunctions";
+    /** @hidden */
+    export var depthPixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module "babylonjs/Shaders/depth.vertex" {
+    import "babylonjs/Shaders/ShadersInclude/bonesDeclaration";
+    import "babylonjs/Shaders/ShadersInclude/morphTargetsVertexGlobalDeclaration";
+    import "babylonjs/Shaders/ShadersInclude/morphTargetsVertexDeclaration";
+    import "babylonjs/Shaders/ShadersInclude/instancesDeclaration";
+    import "babylonjs/Shaders/ShadersInclude/morphTargetsVertex";
+    import "babylonjs/Shaders/ShadersInclude/instancesVertex";
+    import "babylonjs/Shaders/ShadersInclude/bonesVertex";
+    /** @hidden */
+    export var depthVertexShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module "babylonjs/Rendering/depthRenderer" {
+    import { Nullable } from "babylonjs/types";
+    import { SubMesh } from "babylonjs/Meshes/subMesh";
+    import { Scene } from "babylonjs/scene";
+    import { RenderTargetTexture } from "babylonjs/Materials/Textures/renderTargetTexture";
+    import { Camera } from "babylonjs/Cameras/camera";
+    import "babylonjs/Shaders/depth.fragment";
+    import "babylonjs/Shaders/depth.vertex";
+    /**
+     * This represents a depth renderer in Babylon.
+     * A depth renderer will render to it's depth map every frame which can be displayed or used in post processing
+     */
+    export class DepthRenderer {
+        private _scene;
+        private _depthMap;
+        private _effect;
+        private readonly _storeNonLinearDepth;
+        private readonly _clearColor;
+        /** Get if the depth renderer is using packed depth or not */
+        readonly isPacked: boolean;
+        private _cachedDefines;
+        private _camera;
+        /** Enable or disable the depth renderer. When disabled, the depth texture is not updated */
+        enabled: boolean;
+        /**
+         * Specifiess that the depth renderer will only be used within
+         * the camera it is created for.
+         * This can help forcing its rendering during the camera processing.
+         */
+        useOnlyInActiveCamera: boolean;
+        /** @hidden */
+        static _SceneComponentInitialization: (scene: Scene) => void;
+        /**
+         * Instantiates a depth renderer
+         * @param scene The scene the renderer belongs to
+         * @param type The texture type of the depth map (default: Engine.TEXTURETYPE_FLOAT)
+         * @param camera The camera to be used to render the depth map (default: scene's active camera)
+         * @param storeNonLinearDepth Defines whether the depth is stored linearly like in Babylon Shadows or directly like glFragCoord.z
+         */
+        constructor(scene: Scene, type?: number, camera?: Nullable<Camera>, storeNonLinearDepth?: boolean);
+        /**
+         * Creates the depth rendering effect and checks if the effect is ready.
+         * @param subMesh The submesh to be used to render the depth map of
+         * @param useInstances If multiple world instances should be used
+         * @returns if the depth renderer is ready to render the depth map
+         */
+        isReady(subMesh: SubMesh, useInstances: boolean): boolean;
+        /**
+         * Gets the texture which the depth map will be written to.
+         * @returns The depth map texture
+         */
+        getDepthMap(): RenderTargetTexture;
+        /**
+         * Disposes of the depth renderer.
+         */
+        dispose(): void;
+    }
+}
+declare module "babylonjs/Shaders/minmaxRedux.fragment" {
+    /** @hidden */
+    export var minmaxReduxPixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module "babylonjs/Misc/minMaxReducer" {
+    import { Nullable } from "babylonjs/types";
+    import { RenderTargetTexture } from "babylonjs/Materials/Textures/renderTargetTexture";
+    import { Camera } from "babylonjs/Cameras/camera";
+    import { Observer } from "babylonjs/Misc/observable";
+    import { PostProcess } from "babylonjs/PostProcesses/postProcess";
+    import { PostProcessManager } from "babylonjs/PostProcesses/postProcessManager";
+    import { Observable } from "babylonjs/Misc/observable";
+    import "babylonjs/Shaders/minmaxRedux.fragment";
+    /**
+     * This class computes a min/max reduction from a texture: it means it computes the minimum
+     * and maximum values from all values of the texture.
+     * It is performed on the GPU for better performances, thanks to a succession of post processes.
+     * The source values are read from the red channel of the texture.
+     */
+    export class MinMaxReducer {
+        /**
+         * Observable triggered when the computation has been performed
+         */
+        onAfterReductionPerformed: Observable<{
+            min: number;
+            max: number;
+        }>;
+        protected _camera: Camera;
+        protected _sourceTexture: Nullable<RenderTargetTexture>;
+        protected _reductionSteps: Nullable<Array<PostProcess>>;
+        protected _postProcessManager: PostProcessManager;
+        protected _onAfterUnbindObserver: Nullable<Observer<RenderTargetTexture>>;
+        protected _forceFullscreenViewport: boolean;
+        /**
+         * Creates a min/max reducer
+         * @param camera The camera to use for the post processes
+         */
+        constructor(camera: Camera);
+        /**
+         * Gets the texture used to read the values from.
+         */
+        get sourceTexture(): Nullable<RenderTargetTexture>;
+        /**
+         * Sets the source texture to read the values from.
+         * One must indicate if the texture is a depth texture or not through the depthRedux parameter
+         * because in such textures '1' value must not be taken into account to compute the maximum
+         * as this value is used to clear the texture.
+         * Note that the computation is not activated by calling this function, you must call activate() for that!
+         * @param sourceTexture The texture to read the values from. The values should be in the red channel.
+         * @param depthRedux Indicates if the texture is a depth texture or not
+         * @param type The type of the textures created for the reduction (defaults to TEXTURETYPE_HALF_FLOAT)
+         * @param forceFullscreenViewport Forces the post processes used for the reduction to be applied without taking into account viewport (defaults to true)
+         */
+        setSourceTexture(sourceTexture: RenderTargetTexture, depthRedux: boolean, type?: number, forceFullscreenViewport?: boolean): void;
+        /**
+         * Defines the refresh rate of the computation.
+         * Use 0 to compute just once, 1 to compute on every frame, 2 to compute every two frames and so on...
+         */
+        get refreshRate(): number;
+        set refreshRate(value: number);
+        protected _activated: boolean;
+        /**
+         * Gets the activation status of the reducer
+         */
+        get activated(): boolean;
+        /**
+         * Activates the reduction computation.
+         * When activated, the observers registered in onAfterReductionPerformed are
+         * called after the compuation is performed
+         */
+        activate(): void;
+        /**
+         * Deactivates the reduction computation.
+         */
+        deactivate(): void;
+        /**
+         * Disposes the min/max reducer
+         * @param disposeAll true to dispose all the resources. You should always call this function with true as the parameter (or without any parameter as it is the default one). This flag is meant to be used internally.
+         */
+        dispose(disposeAll?: boolean): void;
+    }
+}
+declare module "babylonjs/Misc/depthReducer" {
+    import { Nullable } from "babylonjs/types";
+    import { RenderTargetTexture } from "babylonjs/Materials/Textures/renderTargetTexture";
+    import { Camera } from "babylonjs/Cameras/camera";
+    import { DepthRenderer } from "babylonjs/Rendering/depthRenderer";
+    import { MinMaxReducer } from "babylonjs/Misc/minMaxReducer";
+    /**
+     * This class is a small wrapper around the MinMaxReducer class to compute the min/max values of a depth texture
+     */
+    export class DepthReducer extends MinMaxReducer {
+        private _depthRenderer;
+        private _depthRendererId;
+        /**
+         * Gets the depth renderer used for the computation.
+         * Note that the result is null if you provide your own renderer when calling setDepthRenderer.
+         */
+        get depthRenderer(): Nullable<DepthRenderer>;
+        /**
+         * Creates a depth reducer
+         * @param camera The camera used to render the depth texture
+         */
+        constructor(camera: Camera);
+        /**
+         * Sets the depth renderer to use to generate the depth map
+         * @param depthRenderer The depth renderer to use. If not provided, a new one will be created automatically
+         * @param type The texture type of the depth map (default: TEXTURETYPE_HALF_FLOAT)
+         * @param forceFullscreenViewport Forces the post processes used for the reduction to be applied without taking into account viewport (defaults to true)
+         */
+        setDepthRenderer(depthRenderer?: Nullable<DepthRenderer>, type?: number, forceFullscreenViewport?: boolean): void;
+        /** @hidden */
+        setSourceTexture(sourceTexture: RenderTargetTexture, depthRedux: boolean, type?: number, forceFullscreenViewport?: boolean): void;
+        /**
+         * Activates the reduction computation.
+         * When activated, the observers registered in onAfterReductionPerformed are
+         * called after the compuation is performed
+         */
+        activate(): void;
+        /**
+         * Deactivates the reduction computation.
+         */
+        deactivate(): void;
+        /**
+         * Disposes the depth reducer
+         * @param disposeAll true to dispose all the resources. You should always call this function with true as the parameter (or without any parameter as it is the default one). This flag is meant to be used internally.
+         */
+        dispose(disposeAll?: boolean): void;
+    }
+}
 declare module "babylonjs/Lights/Shadows/cascadedShadowGenerator" {
     import { Nullable } from "babylonjs/types";
     import { Scene } from "babylonjs/scene";
@@ -56412,6 +56624,7 @@ declare module "babylonjs/Lights/Shadows/cascadedShadowGenerator" {
     import { IShadowGenerator } from "babylonjs/Lights/Shadows/shadowGenerator";
     import { DirectionalLight } from "babylonjs/Lights/directionalLight";
     import { BoundingInfo } from "babylonjs/Culling/boundingInfo";
+    import { DepthRenderer } from "babylonjs/Rendering/depthRenderer";
     /**
      * A CSM implementation allowing casting shadows on large scenes.
      * Documentation : https://doc.babylonjs.com/babylon101/cascadedShadows
@@ -56770,6 +56983,38 @@ declare module "babylonjs/Lights/Shadows/cascadedShadowGenerator" {
          * @returns the cascade view matrix
          */
         getCascadeViewMatrix(cascadeNum: number): Nullable<Matrix>;
+        private _depthRenderer;
+        /**
+         * Sets the depth renderer to use when autoCalcDepthBounds is enabled.
+         *
+         * Note that if no depth renderer is set, a new one will be automatically created internally when necessary.
+         *
+         * You should call this function if you already have a depth renderer enabled in your scene, to avoid
+         * doing multiple depth rendering each frame. If you provide your own depth renderer, make sure it stores linear depth!
+         * @param depthRenderer The depth renderer to use when autoCalcDepthBounds is enabled. If you pass null or don't call this function at all, a depth renderer will be automatically created
+         */
+        setDepthRenderer(depthRenderer: Nullable<DepthRenderer>): void;
+        private _depthReducer;
+        private _autoCalcDepthBounds;
+        /**
+         * Gets or sets the autoCalcDepthBounds property.
+         *
+         * When enabled, a depth rendering pass is first performed (with an internally created depth renderer or with the one
+         * you provide by calling setDepthRenderer). Then, a min/max reducing is applied on the depth map to compute the
+         * minimal and maximal depth of the map and those values are used as inputs for the setMinMaxDistance() function.
+         * It can greatly enhance the shadow quality, at the expense of more GPU works.
+         * When using this option, you should increase the value of the lambda parameter, and even set it to 1 for best results.
+         */
+        get autoCalcDepthBounds(): boolean;
+        set autoCalcDepthBounds(value: boolean);
+        /**
+         * Defines the refresh rate of the min/max computation used when autoCalcDepthBounds is set to true
+         * Use 0 to compute just once, 1 to compute on every frame, 2 to compute every two frames and so on...
+         * Note that if you provided your own depth renderer through a call to setDepthRenderer, you are responsible
+         * for setting the refresh rate on the renderer yourself!
+         */
+        get autoCalcDepthBoundsRefreshRate(): number;
+        set autoCalcDepthBoundsRefreshRate(value: number);
         /**
          * Create the cascade breaks according to the lambda, shadowMaxZ and min/max distance properties, as well as the camera near and far planes.
          * This function is automatically called when updating lambda, shadowMaxZ and min/max distances, however you should call it yourself if
@@ -69461,20 +69706,6 @@ declare module "babylonjs/PostProcesses/tonemapPostProcess" {
         exposureAdjustment: number, camera: Camera, samplingMode?: number, engine?: Engine, textureFormat?: number);
     }
 }
-declare module "babylonjs/Shaders/depth.vertex" {
-    import "babylonjs/Shaders/ShadersInclude/bonesDeclaration";
-    import "babylonjs/Shaders/ShadersInclude/morphTargetsVertexGlobalDeclaration";
-    import "babylonjs/Shaders/ShadersInclude/morphTargetsVertexDeclaration";
-    import "babylonjs/Shaders/ShadersInclude/instancesDeclaration";
-    import "babylonjs/Shaders/ShadersInclude/morphTargetsVertex";
-    import "babylonjs/Shaders/ShadersInclude/instancesVertex";
-    import "babylonjs/Shaders/ShadersInclude/bonesVertex";
-    /** @hidden */
-    export var depthVertexShader: {
-        name: string;
-        shader: string;
-    };
-}
 declare module "babylonjs/Shaders/volumetricLightScattering.fragment" {
     /** @hidden */
     export var volumetricLightScatteringPixelShader: {
@@ -69769,70 +70000,6 @@ declare module "babylonjs/Rendering/boundingBoxRenderer" {
         dispose(): void;
     }
 }
-declare module "babylonjs/Shaders/depth.fragment" {
-    import "babylonjs/Shaders/ShadersInclude/packingFunctions";
-    /** @hidden */
-    export var depthPixelShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module "babylonjs/Rendering/depthRenderer" {
-    import { Nullable } from "babylonjs/types";
-    import { SubMesh } from "babylonjs/Meshes/subMesh";
-    import { Scene } from "babylonjs/scene";
-    import { RenderTargetTexture } from "babylonjs/Materials/Textures/renderTargetTexture";
-    import { Camera } from "babylonjs/Cameras/camera";
-    import "babylonjs/Shaders/depth.fragment";
-    import "babylonjs/Shaders/depth.vertex";
-    /**
-     * This represents a depth renderer in Babylon.
-     * A depth renderer will render to it's depth map every frame which can be displayed or used in post processing
-     */
-    export class DepthRenderer {
-        private _scene;
-        private _depthMap;
-        private _effect;
-        private readonly _storeNonLinearDepth;
-        private readonly _clearColor;
-        /** Get if the depth renderer is using packed depth or not */
-        readonly isPacked: boolean;
-        private _cachedDefines;
-        private _camera;
-        /**
-         * Specifiess that the depth renderer will only be used within
-         * the camera it is created for.
-         * This can help forcing its rendering during the camera processing.
-         */
-        useOnlyInActiveCamera: boolean;
-        /** @hidden */
-        static _SceneComponentInitialization: (scene: Scene) => void;
-        /**
-         * Instantiates a depth renderer
-         * @param scene The scene the renderer belongs to
-         * @param type The texture type of the depth map (default: Engine.TEXTURETYPE_FLOAT)
-         * @param camera The camera to be used to render the depth map (default: scene's active camera)
-         * @param storeNonLinearDepth Defines whether the depth is stored linearly like in Babylon Shadows or directly like glFragCoord.z
-         */
-        constructor(scene: Scene, type?: number, camera?: Nullable<Camera>, storeNonLinearDepth?: boolean);
-        /**
-         * Creates the depth rendering effect and checks if the effect is ready.
-         * @param subMesh The submesh to be used to render the depth map of
-         * @param useInstances If multiple world instances should be used
-         * @returns if the depth renderer is ready to render the depth map
-         */
-        isReady(subMesh: SubMesh, useInstances: boolean): boolean;
-        /**
-         * Gets the texture which the depth map will be written to.
-         * @returns The depth map texture
-         */
-        getDepthMap(): RenderTargetTexture;
-        /**
-         * Disposes of the depth renderer.
-         */
-        dispose(): void;
-    }
-}
 declare module "babylonjs/Rendering/depthRendererSceneComponent" {
     import { Nullable } from "babylonjs/types";
     import { Scene } from "babylonjs/scene";
@@ -72077,6 +72244,8 @@ declare module "babylonjs/Misc/index" {
     export * from "babylonjs/Misc/fileTools";
     export * from "babylonjs/Misc/stringTools";
     export * from "babylonjs/Misc/dataReader";
+    export * from "babylonjs/Misc/minMaxReducer";
+    export * from "babylonjs/Misc/depthReducer";
 }
 declare module "babylonjs/index" {
     export * from "babylonjs/abstractScene";
@@ -83593,9 +83762,9 @@ declare module BABYLON {
         static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW: number;
         static readonly STEP_AFTERCAMERADRAW_LAYER: number;
         static readonly STEP_AFTERRENDER_AUDIO: number;
-        static readonly STEP_GATHERRENDERTARGETS_SHADOWGENERATOR: number;
-        static readonly STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER: number;
         static readonly STEP_GATHERRENDERTARGETS_DEPTHRENDERER: number;
+        static readonly STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER: number;
+        static readonly STEP_GATHERRENDERTARGETS_SHADOWGENERATOR: number;
         static readonly STEP_GATHERRENDERTARGETS_POSTPROCESSRENDERPIPELINEMANAGER: number;
         static readonly STEP_GATHERACTIVECAMERARENDERTARGETS_DEPTHRENDERER: number;
         static readonly STEP_POINTERMOVE_SPRITE: number;
@@ -115989,7 +116158,6 @@ declare module BABYLON {
          * Pointer which can be used to select objects or attach a visible laser to
          */
         pointer: AbstractMesh;
-        private _gamepadMode;
         /**
          * If available, this is the gamepad object related to this controller.
          * Using this object it is possible to get click events and trackpad changes of the
@@ -126221,6 +126389,191 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
+    /** @hidden */
+    export var depthPixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /** @hidden */
+    export var depthVertexShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /**
+     * This represents a depth renderer in Babylon.
+     * A depth renderer will render to it's depth map every frame which can be displayed or used in post processing
+     */
+    export class DepthRenderer {
+        private _scene;
+        private _depthMap;
+        private _effect;
+        private readonly _storeNonLinearDepth;
+        private readonly _clearColor;
+        /** Get if the depth renderer is using packed depth or not */
+        readonly isPacked: boolean;
+        private _cachedDefines;
+        private _camera;
+        /** Enable or disable the depth renderer. When disabled, the depth texture is not updated */
+        enabled: boolean;
+        /**
+         * Specifiess that the depth renderer will only be used within
+         * the camera it is created for.
+         * This can help forcing its rendering during the camera processing.
+         */
+        useOnlyInActiveCamera: boolean;
+        /** @hidden */
+        static _SceneComponentInitialization: (scene: Scene) => void;
+        /**
+         * Instantiates a depth renderer
+         * @param scene The scene the renderer belongs to
+         * @param type The texture type of the depth map (default: Engine.TEXTURETYPE_FLOAT)
+         * @param camera The camera to be used to render the depth map (default: scene's active camera)
+         * @param storeNonLinearDepth Defines whether the depth is stored linearly like in Babylon Shadows or directly like glFragCoord.z
+         */
+        constructor(scene: Scene, type?: number, camera?: Nullable<Camera>, storeNonLinearDepth?: boolean);
+        /**
+         * Creates the depth rendering effect and checks if the effect is ready.
+         * @param subMesh The submesh to be used to render the depth map of
+         * @param useInstances If multiple world instances should be used
+         * @returns if the depth renderer is ready to render the depth map
+         */
+        isReady(subMesh: SubMesh, useInstances: boolean): boolean;
+        /**
+         * Gets the texture which the depth map will be written to.
+         * @returns The depth map texture
+         */
+        getDepthMap(): RenderTargetTexture;
+        /**
+         * Disposes of the depth renderer.
+         */
+        dispose(): void;
+    }
+}
+declare module BABYLON {
+    /** @hidden */
+    export var minmaxReduxPixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /**
+     * This class computes a min/max reduction from a texture: it means it computes the minimum
+     * and maximum values from all values of the texture.
+     * It is performed on the GPU for better performances, thanks to a succession of post processes.
+     * The source values are read from the red channel of the texture.
+     */
+    export class MinMaxReducer {
+        /**
+         * Observable triggered when the computation has been performed
+         */
+        onAfterReductionPerformed: Observable<{
+            min: number;
+            max: number;
+        }>;
+        protected _camera: Camera;
+        protected _sourceTexture: Nullable<RenderTargetTexture>;
+        protected _reductionSteps: Nullable<Array<PostProcess>>;
+        protected _postProcessManager: PostProcessManager;
+        protected _onAfterUnbindObserver: Nullable<Observer<RenderTargetTexture>>;
+        protected _forceFullscreenViewport: boolean;
+        /**
+         * Creates a min/max reducer
+         * @param camera The camera to use for the post processes
+         */
+        constructor(camera: Camera);
+        /**
+         * Gets the texture used to read the values from.
+         */
+        get sourceTexture(): Nullable<RenderTargetTexture>;
+        /**
+         * Sets the source texture to read the values from.
+         * One must indicate if the texture is a depth texture or not through the depthRedux parameter
+         * because in such textures '1' value must not be taken into account to compute the maximum
+         * as this value is used to clear the texture.
+         * Note that the computation is not activated by calling this function, you must call activate() for that!
+         * @param sourceTexture The texture to read the values from. The values should be in the red channel.
+         * @param depthRedux Indicates if the texture is a depth texture or not
+         * @param type The type of the textures created for the reduction (defaults to TEXTURETYPE_HALF_FLOAT)
+         * @param forceFullscreenViewport Forces the post processes used for the reduction to be applied without taking into account viewport (defaults to true)
+         */
+        setSourceTexture(sourceTexture: RenderTargetTexture, depthRedux: boolean, type?: number, forceFullscreenViewport?: boolean): void;
+        /**
+         * Defines the refresh rate of the computation.
+         * Use 0 to compute just once, 1 to compute on every frame, 2 to compute every two frames and so on...
+         */
+        get refreshRate(): number;
+        set refreshRate(value: number);
+        protected _activated: boolean;
+        /**
+         * Gets the activation status of the reducer
+         */
+        get activated(): boolean;
+        /**
+         * Activates the reduction computation.
+         * When activated, the observers registered in onAfterReductionPerformed are
+         * called after the compuation is performed
+         */
+        activate(): void;
+        /**
+         * Deactivates the reduction computation.
+         */
+        deactivate(): void;
+        /**
+         * Disposes the min/max reducer
+         * @param disposeAll true to dispose all the resources. You should always call this function with true as the parameter (or without any parameter as it is the default one). This flag is meant to be used internally.
+         */
+        dispose(disposeAll?: boolean): void;
+    }
+}
+declare module BABYLON {
+    /**
+     * This class is a small wrapper around the MinMaxReducer class to compute the min/max values of a depth texture
+     */
+    export class DepthReducer extends MinMaxReducer {
+        private _depthRenderer;
+        private _depthRendererId;
+        /**
+         * Gets the depth renderer used for the computation.
+         * Note that the result is null if you provide your own renderer when calling setDepthRenderer.
+         */
+        get depthRenderer(): Nullable<DepthRenderer>;
+        /**
+         * Creates a depth reducer
+         * @param camera The camera used to render the depth texture
+         */
+        constructor(camera: Camera);
+        /**
+         * Sets the depth renderer to use to generate the depth map
+         * @param depthRenderer The depth renderer to use. If not provided, a new one will be created automatically
+         * @param type The texture type of the depth map (default: TEXTURETYPE_HALF_FLOAT)
+         * @param forceFullscreenViewport Forces the post processes used for the reduction to be applied without taking into account viewport (defaults to true)
+         */
+        setDepthRenderer(depthRenderer?: Nullable<DepthRenderer>, type?: number, forceFullscreenViewport?: boolean): void;
+        /** @hidden */
+        setSourceTexture(sourceTexture: RenderTargetTexture, depthRedux: boolean, type?: number, forceFullscreenViewport?: boolean): void;
+        /**
+         * Activates the reduction computation.
+         * When activated, the observers registered in onAfterReductionPerformed are
+         * called after the compuation is performed
+         */
+        activate(): void;
+        /**
+         * Deactivates the reduction computation.
+         */
+        deactivate(): void;
+        /**
+         * Disposes the depth reducer
+         * @param disposeAll true to dispose all the resources. You should always call this function with true as the parameter (or without any parameter as it is the default one). This flag is meant to be used internally.
+         */
+        dispose(disposeAll?: boolean): void;
+    }
+}
+declare module BABYLON {
     /**
      * A CSM implementation allowing casting shadows on large scenes.
      * Documentation : https://doc.babylonjs.com/babylon101/cascadedShadows
@@ -126579,6 +126932,38 @@ declare module BABYLON {
          * @returns the cascade view matrix
          */
         getCascadeViewMatrix(cascadeNum: number): Nullable<Matrix>;
+        private _depthRenderer;
+        /**
+         * Sets the depth renderer to use when autoCalcDepthBounds is enabled.
+         *
+         * Note that if no depth renderer is set, a new one will be automatically created internally when necessary.
+         *
+         * You should call this function if you already have a depth renderer enabled in your scene, to avoid
+         * doing multiple depth rendering each frame. If you provide your own depth renderer, make sure it stores linear depth!
+         * @param depthRenderer The depth renderer to use when autoCalcDepthBounds is enabled. If you pass null or don't call this function at all, a depth renderer will be automatically created
+         */
+        setDepthRenderer(depthRenderer: Nullable<DepthRenderer>): void;
+        private _depthReducer;
+        private _autoCalcDepthBounds;
+        /**
+         * Gets or sets the autoCalcDepthBounds property.
+         *
+         * When enabled, a depth rendering pass is first performed (with an internally created depth renderer or with the one
+         * you provide by calling setDepthRenderer). Then, a min/max reducing is applied on the depth map to compute the
+         * minimal and maximal depth of the map and those values are used as inputs for the setMinMaxDistance() function.
+         * It can greatly enhance the shadow quality, at the expense of more GPU works.
+         * When using this option, you should increase the value of the lambda parameter, and even set it to 1 for best results.
+         */
+        get autoCalcDepthBounds(): boolean;
+        set autoCalcDepthBounds(value: boolean);
+        /**
+         * Defines the refresh rate of the min/max computation used when autoCalcDepthBounds is set to true
+         * Use 0 to compute just once, 1 to compute on every frame, 2 to compute every two frames and so on...
+         * Note that if you provided your own depth renderer through a call to setDepthRenderer, you are responsible
+         * for setting the refresh rate on the renderer yourself!
+         */
+        get autoCalcDepthBoundsRefreshRate(): number;
+        set autoCalcDepthBoundsRefreshRate(value: number);
         /**
          * Create the cascade breaks according to the lambda, shadowMaxZ and min/max distance properties, as well as the camera near and far planes.
          * This function is automatically called when updating lambda, shadowMaxZ and min/max distances, however you should call it yourself if
@@ -138195,13 +138580,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /** @hidden */
-    export var depthVertexShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module BABYLON {
-    /** @hidden */
     export var volumetricLightScatteringPixelShader: {
         name: string;
         shader: string;
@@ -138426,62 +138804,6 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
-    /** @hidden */
-    export var depthPixelShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module BABYLON {
-    /**
-     * This represents a depth renderer in Babylon.
-     * A depth renderer will render to it's depth map every frame which can be displayed or used in post processing
-     */
-    export class DepthRenderer {
-        private _scene;
-        private _depthMap;
-        private _effect;
-        private readonly _storeNonLinearDepth;
-        private readonly _clearColor;
-        /** Get if the depth renderer is using packed depth or not */
-        readonly isPacked: boolean;
-        private _cachedDefines;
-        private _camera;
-        /**
-         * Specifiess that the depth renderer will only be used within
-         * the camera it is created for.
-         * This can help forcing its rendering during the camera processing.
-         */
-        useOnlyInActiveCamera: boolean;
-        /** @hidden */
-        static _SceneComponentInitialization: (scene: Scene) => void;
-        /**
-         * Instantiates a depth renderer
-         * @param scene The scene the renderer belongs to
-         * @param type The texture type of the depth map (default: Engine.TEXTURETYPE_FLOAT)
-         * @param camera The camera to be used to render the depth map (default: scene's active camera)
-         * @param storeNonLinearDepth Defines whether the depth is stored linearly like in Babylon Shadows or directly like glFragCoord.z
-         */
-        constructor(scene: Scene, type?: number, camera?: Nullable<Camera>, storeNonLinearDepth?: boolean);
-        /**
-         * Creates the depth rendering effect and checks if the effect is ready.
-         * @param subMesh The submesh to be used to render the depth map of
-         * @param useInstances If multiple world instances should be used
-         * @returns if the depth renderer is ready to render the depth map
-         */
-        isReady(subMesh: SubMesh, useInstances: boolean): boolean;
-        /**
-         * Gets the texture which the depth map will be written to.
-         * @returns The depth map texture
-         */
-        getDepthMap(): RenderTargetTexture;
-        /**
-         * Disposes of the depth renderer.
-         */
-        dispose(): void;
-    }
-}
-declare module BABYLON {
         interface Scene {
             /** @hidden (Backing field) */
             _depthRenderer: {

Файловите разлики са ограничени, защото са твърде много
+ 29 - 17
dist/preview release/viewer/babylon.viewer.js


Файловите разлики са ограничени, защото са твърде много
+ 2 - 2
dist/preview release/viewer/babylon.viewer.max.js


+ 3 - 0
dist/preview release/what's new.md

@@ -53,6 +53,7 @@
 - PNG support for browsers not supporting SVG ([RaananW](https://github.com/RaananW/))
 - Device orientation event permissions for iOS 13+ ([RaananW](https://github.com/RaananW/))
 - Added `DirectionalLight.autoCalcShadowZBounds` to automatically compute the `shadowMinZ` and `shadowMaxZ` values ([Popov72](https://github.com/Popov72))
+- Added `CascadedShadowGenerator.autoCalcDepthBounds` to improve the shadow quality rendering ([Popov72](https://github.com/Popov72))
 - Improved cascade blending in CSM shadow technic ([Popov72](https://github.com/Popov72))
 
 ### Engine
@@ -188,6 +189,7 @@
 - Teleportation and controller selection are now WebXR features. ([#7290](https://github.com/BabylonJS/Babylon.js/issues/7290)) ([RaananW](https://github.com/RaananW/))
 - Teleportation allows selecting direction before teleporting when using thumbstick/touchpad. ([#7290](https://github.com/BabylonJS/Babylon.js/issues/7290)) ([RaananW](https://github.com/RaananW/))
 - It is now possible to force a certain profile type for the controllers ([#7348](https://github.com/BabylonJS/Babylon.js/issues/7375)) ([RaananW](https://github.com/RaananW/))
+- WebXR camera is initialized on the first frame ([#7389](https://github.com/BabylonJS/Babylon.js/issues/7389)) ([RaananW](https://github.com/RaananW/))
 
 ### Ray
 
@@ -281,6 +283,7 @@
 - Fixed issue where textures exported using Safari web browser are Y mirrored. ([#7352](https://github.com/BabylonJS/Babylon.js/issues/7352)) ([Drigax](https://github.com/drigax))
 - Fix a bug when resizing a MRT ([Popov72](https://github.com/Popov72))
 - Fixed an infinite clone recursion bug in `InstancedMesh` due to `DeepCopier.DeepCopy` cloning `parent` ([Poolminer](https://github.com/Poolminer/))
+- Fixed an issue with multiview textures ([RaananW](https://github.com/RaananW/))
 
 ## Breaking changes
 

+ 3 - 2
loaders/src/OBJ/objFileLoader.ts

@@ -813,14 +813,14 @@ export class OBJFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPlugi
 
                 //If this new material is in the same mesh
 
-                if (!isFirstMaterial) {
+                if (!isFirstMaterial || !hasMeshes) {
                     //Set the data for the previous mesh
                     addPreviousObjMesh();
                     //Create a new mesh
                     var objMesh: MeshObject =
                     //Set the name of the current obj mesh
                     {
-                        name: objMeshName + "_mm" + increment.toString(), //Set the name of the current obj mesh
+                        name: (objMeshName || "mesh") + "_mm" + increment.toString(), //Set the name of the current obj mesh
                         indices: undefined,
                         positions: undefined,
                         normals: undefined,
@@ -831,6 +831,7 @@ export class OBJFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPlugi
                     increment++;
                     //If meshes are already defined
                     meshesFromObj.push(objMesh);
+                    hasMeshes = true;
                 }
                 //Set the material name if the previous line define a mesh
 

+ 9 - 10
src/Cameras/XR/webXRCamera.ts

@@ -43,14 +43,16 @@ export class WebXRCamera extends FreeCamera {
             this._referenceQuaternion.copyFromFloats(0, 0, 0, 1);
             // first frame - camera's y position should be 0 for the correct offset
             this._firstFrame = true;
+
         });
 
         // Check transformation changes on each frame. Callback is added to be first so that the transformation will be
         // applied to the rest of the elements using the referenceSpace object
         this._xrSessionManager.onXRFrameObservable.add((frame) => {
-            if (!this._firstFrame) {
-                this._updateReferenceSpace();
+            if (this._firstFrame) {
+                this._updateFromXRSession();
             }
+            this._updateReferenceSpace();
             this._updateFromXRSession();
         }, undefined, true);
     }
@@ -83,16 +85,14 @@ export class WebXRCamera extends FreeCamera {
         this.rigCameras[1].outputRenderTarget = null;
     }
 
-    private _updateReferenceSpace(): boolean {
+    private _updateReferenceSpace() {
         // were position & rotation updated OUTSIDE of the xr update loop
         if (!this.position.equals(this._referencedPosition) || !this.rotationQuaternion.equals(this._referenceQuaternion)) {
             this.position.subtractToRef(this._referencedPosition, this._referencedPosition);
             this._referenceQuaternion.conjugateInPlace();
             this._referenceQuaternion.multiplyToRef(this.rotationQuaternion, this._referenceQuaternion);
             this._updateReferenceSpaceOffset(this._referencedPosition, this._referenceQuaternion.normalize());
-            return true;
         }
-        return false;
     }
 
     private _updateReferenceSpaceOffset(positionOffset: Vector3, rotationOffset?: Quaternion, ignoreHeight: boolean = false) {
@@ -180,12 +180,11 @@ export class WebXRCamera extends FreeCamera {
                 this._referenceQuaternion.copyFromFloats(0, 0, 0, 1);
                 // update the reference space so that the position will be correct
 
-                return this.update();
-
             }
-
-            this.rotationQuaternion.copyFrom(this._referenceQuaternion);
-            this.position.copyFrom(this._referencedPosition);
+            else {
+                this.rotationQuaternion.copyFrom(this._referenceQuaternion);
+                this.position.copyFrom(this._referencedPosition);
+            }
         }
 
         // Update camera rigs

+ 1 - 3
src/Cameras/XR/webXRController.ts

@@ -20,8 +20,6 @@ export class WebXRController {
      * Pointer which can be used to select objects or attach a visible laser to
      */
     public pointer: AbstractMesh;
-
-    private _gamepadMode = false;
     /**
      * If available, this is the gamepad object related to this controller.
      * Using this object it is possible to get click events and trackpad changes of the
@@ -145,7 +143,7 @@ export class WebXRController {
         if (this.grip) {
             this.grip.dispose();
         }
-        if (this.gamepadController && this._gamepadMode) {
+        if (this.gamepadController) {
             this.gamepadController.dispose();
         }
         this.pointer.dispose();

+ 3 - 3
src/Engines/thinEngine.ts

@@ -132,14 +132,14 @@ export class ThinEngine {
      */
     // Not mixed with Version for tooling purpose.
     public static get NpmPackage(): string {
-        return "babylonjs@4.1.0-beta.18";
+        return "babylonjs@4.1.0-beta.19";
     }
 
     /**
      * Returns the current version of the framework
      */
     public static get Version(): string {
-        return "4.1.0-beta.18";
+        return "4.1.0-beta.19";
     }
 
     /**
@@ -3094,7 +3094,7 @@ export class ThinEngine {
             return this._gl.TEXTURE_CUBE_MAP;
         } else if (texture.is3D) {
             return this._gl.TEXTURE_3D;
-        } else if (texture.is2DArray) {
+        } else if (texture.is2DArray || texture.isMultiview) {
             return this._gl.TEXTURE_2D_ARRAY;
         }
         return this._gl.TEXTURE_2D;

+ 85 - 0
src/Lights/Shadows/cascadedShadowGenerator.ts

@@ -27,6 +27,8 @@ import { IShadowGenerator } from './shadowGenerator';
 import { DirectionalLight } from '../directionalLight';
 
 import { BoundingInfo } from '../../Culling/boundingInfo';
+import { DepthRenderer } from '../../Rendering/depthRenderer';
+import { DepthReducer } from '../../Misc/depthReducer';
 
 interface ICascade {
     prevBreakDistance: number;
@@ -698,6 +700,89 @@ export class CascadedShadowGenerator implements IShadowGenerator {
         return cascadeNum >= 0 && cascadeNum < this._numCascades ? this._viewMatrices[cascadeNum] : null;
     }
 
+    private _depthRenderer: Nullable<DepthRenderer>;
+    /**
+     * Sets the depth renderer to use when autoCalcDepthBounds is enabled.
+     *
+     * Note that if no depth renderer is set, a new one will be automatically created internally when necessary.
+     *
+     * You should call this function if you already have a depth renderer enabled in your scene, to avoid
+     * doing multiple depth rendering each frame. If you provide your own depth renderer, make sure it stores linear depth!
+     * @param depthRenderer The depth renderer to use when autoCalcDepthBounds is enabled. If you pass null or don't call this function at all, a depth renderer will be automatically created
+     */
+    public setDepthRenderer(depthRenderer: Nullable<DepthRenderer>): void {
+        this._depthRenderer = depthRenderer;
+
+        if (this._depthReducer) {
+            this._depthReducer.setDepthRenderer(this._depthRenderer);
+        }
+    }
+
+    private _depthReducer: Nullable<DepthReducer>;
+    private _autoCalcDepthBounds = false;
+
+    /**
+     * Gets or sets the autoCalcDepthBounds property.
+     *
+     * When enabled, a depth rendering pass is first performed (with an internally created depth renderer or with the one
+     * you provide by calling setDepthRenderer). Then, a min/max reducing is applied on the depth map to compute the
+     * minimal and maximal depth of the map and those values are used as inputs for the setMinMaxDistance() function.
+     * It can greatly enhance the shadow quality, at the expense of more GPU works.
+     * When using this option, you should increase the value of the lambda parameter, and even set it to 1 for best results.
+     */
+    public get autoCalcDepthBounds(): boolean {
+        return this._autoCalcDepthBounds;
+    }
+
+    public set autoCalcDepthBounds(value: boolean) {
+        const camera = this._scene.activeCamera;
+
+        if (!camera) {
+            return;
+        }
+
+        if (!value) {
+            if (this._depthReducer) {
+                this._depthReducer.deactivate();
+            }
+            this.setMinMaxDistance(0, 1);
+            return;
+        }
+
+        if (!this._depthReducer) {
+            this._depthReducer = new DepthReducer(camera);
+            this._depthReducer.onAfterReductionPerformed.add((minmax: { min: number, max: number}) => {
+                let min = minmax.min, max = minmax.max;
+                if (min >= max) {
+                    min = 0;
+                    max = 1;
+                }
+                if (min != this._minDistance || max != this._maxDistance) {
+                    this.setMinMaxDistance(min, max);
+                }
+            });
+            this._depthReducer.setDepthRenderer(this._depthRenderer);
+        }
+
+        this._depthReducer.activate();
+    }
+
+    /**
+     * Defines the refresh rate of the min/max computation used when autoCalcDepthBounds is set to true
+     * Use 0 to compute just once, 1 to compute on every frame, 2 to compute every two frames and so on...
+     * Note that if you provided your own depth renderer through a call to setDepthRenderer, you are responsible
+     * for setting the refresh rate on the renderer yourself!
+     */
+    public get autoCalcDepthBoundsRefreshRate(): number {
+        return this._depthReducer?.depthRenderer?.getDepthMap().refreshRate ?? -1;
+    }
+
+    public set autoCalcDepthBoundsRefreshRate(value: number) {
+        if (this._depthReducer?.depthRenderer) {
+            this._depthReducer.depthRenderer.getDepthMap().refreshRate = value;
+        }
+    }
+
     /**
      * Create the cascade breaks according to the lambda, shadowMaxZ and min/max distance properties, as well as the camera near and far planes.
      * This function is automatically called when updating lambda, shadowMaxZ and min/max distances, however you should call it yourself if

+ 2 - 0
src/Materials/Textures/MultiviewRenderTarget.ts

@@ -1,6 +1,7 @@
 import { RenderTargetTexture } from '../Textures/renderTargetTexture';
 import { Scene } from '../../scene';
 import { InternalTextureSource } from '../Textures/internalTexture';
+import { Constants } from '../../Engines/constants';
 
 /**
  * Renders to multiple views with a single draw call
@@ -16,6 +17,7 @@ export class MultiviewRenderTarget extends RenderTargetTexture {
         super("multiview rtt", size, scene, false, true, InternalTextureSource.Unknown, false, undefined, false, false, true, undefined, true);
         var internalTexture = scene.getEngine().createMultiviewRenderTargetTexture(this.getRenderWidth(), this.getRenderHeight());
         internalTexture.isMultiview = true;
+        internalTexture.format = Constants.TEXTUREFORMAT_RGBA;
         this._texture = internalTexture;
         this.samples = this._engine.getCaps().maxSamples || this.samples;
     }

+ 108 - 0
src/Misc/depthReducer.ts

@@ -0,0 +1,108 @@
+import { Nullable } from "../types";
+import { RenderTargetTexture } from "../Materials/Textures/renderTargetTexture";
+import { Camera } from "../Cameras/camera";
+import { Constants } from "../Engines/constants";
+import { DepthRenderer } from "../Rendering/depthRenderer";
+
+import { MinMaxReducer } from "./minMaxReducer";
+
+/**
+ * This class is a small wrapper around the MinMaxReducer class to compute the min/max values of a depth texture
+ */
+export class DepthReducer extends MinMaxReducer {
+
+    private _depthRenderer: Nullable<DepthRenderer>;
+    private _depthRendererId: string;
+
+    /**
+     * Gets the depth renderer used for the computation.
+     * Note that the result is null if you provide your own renderer when calling setDepthRenderer.
+     */
+    public get depthRenderer(): Nullable<DepthRenderer> {
+        return this._depthRenderer;
+    }
+
+    /**
+     * Creates a depth reducer
+     * @param camera The camera used to render the depth texture
+     */
+    constructor(camera: Camera) {
+        super(camera);
+    }
+
+    /**
+     * Sets the depth renderer to use to generate the depth map
+     * @param depthRenderer The depth renderer to use. If not provided, a new one will be created automatically
+     * @param type The texture type of the depth map (default: TEXTURETYPE_HALF_FLOAT)
+     * @param forceFullscreenViewport Forces the post processes used for the reduction to be applied without taking into account viewport (defaults to true)
+     */
+    public setDepthRenderer(depthRenderer: Nullable<DepthRenderer> = null, type: number = Constants.TEXTURETYPE_HALF_FLOAT, forceFullscreenViewport = true): void {
+        const scene = this._camera.getScene();
+
+        if (this._depthRenderer) {
+            delete scene._depthRenderer[this._depthRendererId];
+
+            this._depthRenderer.dispose();
+            this._depthRenderer = null;
+        }
+
+        if (depthRenderer === null) {
+            if (!scene._depthRenderer) {
+                scene._depthRenderer = {};
+            }
+
+            depthRenderer = this._depthRenderer = new DepthRenderer(scene, type, this._camera, false);
+            depthRenderer.enabled = false;
+
+            this._depthRendererId = "minmax" + this._camera.id;
+            scene._depthRenderer[this._depthRendererId] = depthRenderer;
+        }
+
+        super.setSourceTexture(depthRenderer.getDepthMap(), true, type, forceFullscreenViewport);
+    }
+
+    /** @hidden */
+    public setSourceTexture(sourceTexture: RenderTargetTexture, depthRedux: boolean, type: number = Constants.TEXTURETYPE_HALF_FLOAT, forceFullscreenViewport = true): void {
+        super.setSourceTexture(sourceTexture, depthRedux, type, forceFullscreenViewport);
+    }
+
+    /**
+     * Activates the reduction computation.
+     * When activated, the observers registered in onAfterReductionPerformed are
+     * called after the compuation is performed
+     */
+    public activate(): void {
+        if (this._depthRenderer) {
+            this._depthRenderer.enabled = true;
+        }
+
+        super.activate();
+    }
+
+    /**
+     * Deactivates the reduction computation.
+     */
+    public deactivate(): void {
+        super.deactivate();
+
+        if (this._depthRenderer) {
+            this._depthRenderer.enabled = false;
+        }
+    }
+
+    /**
+     * Disposes the depth reducer
+     * @param disposeAll true to dispose all the resources. You should always call this function with true as the parameter (or without any parameter as it is the default one). This flag is meant to be used internally.
+     */
+    public dispose(disposeAll = true): void {
+        super.dispose(disposeAll);
+
+        if (this._depthRenderer && disposeAll) {
+            delete this._depthRenderer.getDepthMap().getScene()?._depthRenderer[this._depthRendererId];
+
+            this._depthRenderer.dispose();
+            this._depthRenderer = null;
+        }
+    }
+
+}

+ 2 - 0
src/Misc/index.ts

@@ -45,3 +45,5 @@ export * from "./canvasGenerator";
 export * from "./fileTools";
 export * from "./stringTools";
 export * from "./dataReader";
+export * from "./minMaxReducer";
+export * from "./depthReducer";

+ 244 - 0
src/Misc/minMaxReducer.ts

@@ -0,0 +1,244 @@
+import { Nullable } from "../types";
+import { RenderTargetTexture } from "../Materials/Textures/renderTargetTexture";
+import { Camera } from "../Cameras/camera";
+import { Constants } from "../Engines/constants";
+import { Observer } from "./observable";
+import { Effect } from "../Materials/effect";
+import { PostProcess } from "../PostProcesses/postProcess";
+import { PostProcessManager } from "../PostProcesses/postProcessManager";
+import { Observable } from "./observable";
+
+import "../Shaders/minmaxRedux.fragment";
+
+/**
+ * This class computes a min/max reduction from a texture: it means it computes the minimum
+ * and maximum values from all values of the texture.
+ * It is performed on the GPU for better performances, thanks to a succession of post processes.
+ * The source values are read from the red channel of the texture.
+ */
+export class MinMaxReducer {
+
+    /**
+     * Observable triggered when the computation has been performed
+     */
+    public onAfterReductionPerformed = new Observable<{ min: number, max: number }>();
+
+    protected _camera: Camera;
+    protected _sourceTexture: Nullable<RenderTargetTexture>;
+    protected _reductionSteps: Nullable<Array<PostProcess>>;
+    protected _postProcessManager: PostProcessManager;
+    protected _onAfterUnbindObserver: Nullable<Observer<RenderTargetTexture>>;
+    protected _forceFullscreenViewport = true;
+
+    /**
+     * Creates a min/max reducer
+     * @param camera The camera to use for the post processes
+     */
+    constructor(camera: Camera) {
+        this._camera = camera;
+        this._postProcessManager = new PostProcessManager(camera.getScene());
+    }
+
+    /**
+     * Gets the texture used to read the values from.
+     */
+    public get sourceTexture(): Nullable<RenderTargetTexture> {
+        return this._sourceTexture;
+    }
+
+    /**
+     * Sets the source texture to read the values from.
+     * One must indicate if the texture is a depth texture or not through the depthRedux parameter
+     * because in such textures '1' value must not be taken into account to compute the maximum
+     * as this value is used to clear the texture.
+     * Note that the computation is not activated by calling this function, you must call activate() for that!
+     * @param sourceTexture The texture to read the values from. The values should be in the red channel.
+     * @param depthRedux Indicates if the texture is a depth texture or not
+     * @param type The type of the textures created for the reduction (defaults to TEXTURETYPE_HALF_FLOAT)
+     * @param forceFullscreenViewport Forces the post processes used for the reduction to be applied without taking into account viewport (defaults to true)
+     */
+    public setSourceTexture(sourceTexture: RenderTargetTexture, depthRedux: boolean, type: number = Constants.TEXTURETYPE_HALF_FLOAT, forceFullscreenViewport = true): void {
+        if (sourceTexture === this._sourceTexture) {
+            return;
+        }
+
+        this.dispose(false);
+
+        this._sourceTexture = sourceTexture;
+        this._reductionSteps = [];
+        this._forceFullscreenViewport = forceFullscreenViewport;
+
+        const scene = this._camera.getScene();
+
+        // create the first step
+        let reductionInitial = new PostProcess(
+            'Initial reduction phase',
+            'minmaxRedux', // shader
+            ['texSize'],
+            ['sourceTexture'], // textures
+            1.0, // options
+            null, // camera
+            Constants.TEXTURE_NEAREST_NEAREST, // sampling
+            scene.getEngine(), // engine
+            false, // reusable
+            "#define INITIAL" + (depthRedux ? "\n#define DEPTH_REDUX" : ""), // defines
+            type,
+            undefined,
+            undefined,
+            undefined,
+            Constants.TEXTUREFORMAT_RG,
+        );
+
+        reductionInitial.autoClear = false;
+        reductionInitial.forceFullscreenViewport = forceFullscreenViewport;
+
+        let w = this._sourceTexture.getRenderWidth(), h = this._sourceTexture.getRenderHeight();
+
+        reductionInitial.onApply = ((w: number, h: number) => {
+            return (effect: Effect) => {
+                effect.setTexture('sourceTexture', this._sourceTexture);
+                effect.setFloatArray2('texSize', new Float32Array([w, h]));
+            };
+        })(w, h);
+
+        this._reductionSteps.push(reductionInitial);
+
+        let index = 1;
+
+        // create the additional steps
+        while (w > 1 || h > 1) {
+            w = Math.max(Math.round(w / 2), 1);
+            h = Math.max(Math.round(h / 2), 1);
+
+            let reduction = new PostProcess(
+                'Reduction phase ' + index,
+                'minmaxRedux', // shader
+                ['texSize'],
+                null,
+                { width: w, height: h }, // options
+                null, // camera
+                Constants.TEXTURE_NEAREST_NEAREST, // sampling
+                scene.getEngine(), // engine
+                false, // reusable
+                "#define " + ((w == 1 && h == 1) ? 'LAST' : (w == 1 || h == 1) ? 'ONEBEFORELAST' : 'MAIN'), // defines
+                type,
+                undefined,
+                undefined,
+                undefined,
+                Constants.TEXTUREFORMAT_RG,
+            );
+
+            reduction.autoClear = false;
+            reduction.forceFullscreenViewport = forceFullscreenViewport;
+
+            reduction.onApply = ((w: number, h: number) => {
+                return (effect: Effect) => {
+                    if (w == 1 || h == 1) {
+                        effect.setIntArray2('texSize', new Int32Array([w, h]));
+                    } else {
+                        effect.setFloatArray2('texSize', new Float32Array([w, h]));
+                    }
+                };
+            })(w, h);
+
+            this._reductionSteps.push(reduction);
+
+            index++;
+
+            if (w == 1 && h == 1) {
+                let func = (w: number, h: number, reduction: PostProcess) => {
+                    let buffer = new Float32Array(4 * w * h),
+                        minmax = { min: 0, max: 0};
+                    return () => {
+                        scene.getEngine()._readTexturePixels(reduction.inputTexture, w, h, -1, 0, buffer);
+                        minmax.min = buffer[0];
+                        minmax.max = buffer[1];
+                        this.onAfterReductionPerformed.notifyObservers(minmax);
+                    };
+                };
+                reduction.onAfterRenderObservable.add(func(w, h, reduction));
+            }
+        }
+    }
+
+    /**
+     * Defines the refresh rate of the computation.
+     * Use 0 to compute just once, 1 to compute on every frame, 2 to compute every two frames and so on...
+     */
+    public get refreshRate(): number {
+        return this._sourceTexture ? this._sourceTexture.refreshRate : -1;
+    }
+
+    public set refreshRate(value: number) {
+        if (this._sourceTexture) {
+            this._sourceTexture.refreshRate = value;
+        }
+    }
+
+    protected _activated = false;
+
+    /**
+     * Gets the activation status of the reducer
+     */
+    public get activated(): boolean {
+        return this._activated;
+    }
+
+    /**
+     * Activates the reduction computation.
+     * When activated, the observers registered in onAfterReductionPerformed are
+     * called after the compuation is performed
+     */
+    public activate(): void {
+        if (this._onAfterUnbindObserver || !this._sourceTexture) {
+            return;
+        }
+
+        this._onAfterUnbindObserver = this._sourceTexture.onAfterUnbindObservable.add(() => {
+            this._reductionSteps![0].activate(this._camera);
+            this._postProcessManager.directRender(this._reductionSteps!, this._reductionSteps![0].inputTexture, this._forceFullscreenViewport);
+            this._camera.getScene().getEngine().unBindFramebuffer(this._reductionSteps![0].inputTexture, false);
+        });
+
+        this._activated = true;
+    }
+
+    /**
+     * Deactivates the reduction computation.
+     */
+    public deactivate(): void {
+        if (!this._onAfterUnbindObserver || !this._sourceTexture) {
+            return;
+        }
+
+        this._sourceTexture.onAfterUnbindObservable.remove(this._onAfterUnbindObserver);
+        this._onAfterUnbindObserver = null;
+        this._activated = false;
+    }
+
+    /**
+     * Disposes the min/max reducer
+     * @param disposeAll true to dispose all the resources. You should always call this function with true as the parameter (or without any parameter as it is the default one). This flag is meant to be used internally.
+     */
+    public dispose(disposeAll = true): void {
+        if (disposeAll) {
+            this.onAfterReductionPerformed.clear();
+        }
+
+        this.deactivate();
+
+        if (this._reductionSteps) {
+            for (let i = 0; i < this._reductionSteps.length; ++i) {
+                this._reductionSteps[i].dispose();
+            }
+            this._reductionSteps = null;
+        }
+
+        if (this._postProcessManager && disposeAll) {
+            this._postProcessManager.dispose();
+        }
+
+        this._sourceTexture = null;
+    }
+
+}

+ 3 - 0
src/Rendering/depthRenderer.ts

@@ -34,6 +34,9 @@ export class DepthRenderer {
     private _cachedDefines: string;
     private _camera: Nullable<Camera>;
 
+    /** Enable or disable the depth renderer. When disabled, the depth texture is not updated */
+    public enabled = true;
+
     /**
      * Specifiess that the depth renderer will only be used within
      * the camera it is created for.

+ 2 - 2
src/Rendering/depthRendererSceneComponent.ts

@@ -114,7 +114,7 @@ export class DepthRendererSceneComponent implements ISceneComponent {
         if (this.scene._depthRenderer) {
             for (var key in this.scene._depthRenderer) {
                 let depthRenderer = this.scene._depthRenderer[key];
-                if (!depthRenderer.useOnlyInActiveCamera) {
+                if (depthRenderer.enabled && !depthRenderer.useOnlyInActiveCamera) {
                     renderTargets.push(depthRenderer.getDepthMap());
                 }
             }
@@ -125,7 +125,7 @@ export class DepthRendererSceneComponent implements ISceneComponent {
         if (this.scene._depthRenderer) {
             for (var key in this.scene._depthRenderer) {
                 let depthRenderer = this.scene._depthRenderer[key];
-                if (depthRenderer.useOnlyInActiveCamera && this.scene.activeCamera!.id === key) {
+                if (depthRenderer.enabled && depthRenderer.useOnlyInActiveCamera && this.scene.activeCamera!.id === key) {
                     renderTargets.push(depthRenderer.getDepthMap());
                 }
             }

+ 70 - 0
src/Shaders/minmaxRedux.fragment.fx

@@ -0,0 +1,70 @@
+attribute vec2 vUV;
+
+uniform sampler2D textureSampler;
+
+#if defined(INITIAL)
+uniform sampler2D sourceTexture;
+uniform vec2 texSize;
+
+void main(void)
+{
+    ivec2 coord = ivec2(vUV * (texSize - 1.0));
+
+    float f1 = texelFetch(sourceTexture, coord, 0).r;
+    float f2 = texelFetch(sourceTexture, coord + ivec2(1, 0), 0).r;
+    float f3 = texelFetch(sourceTexture, coord + ivec2(1, 1), 0).r;
+    float f4 = texelFetch(sourceTexture, coord + ivec2(0, 1), 0).r;
+
+    float minz = min(min(min(f1, f2), f3), f4);
+    #ifdef DEPTH_REDUX
+        float maxz = max(max(max(sign(1.0 - f1) * f1, sign(1.0 - f2) * f2), sign(1.0 - f3) * f3), sign(1.0 - f4) * f4);
+    #else
+        float maxz = max(max(max(f1, f2), f3), f4);
+    #endif
+
+    glFragColor = vec4(minz, maxz, 0., 0.);
+}
+
+#elif defined(MAIN)
+uniform vec2 texSize;
+
+void main(void)
+{
+    ivec2 coord = ivec2(vUV * (texSize - 1.0));
+
+    vec2 f1 = texelFetch(textureSampler, coord, 0).rg;
+    vec2 f2 = texelFetch(textureSampler, coord + ivec2(1, 0), 0).rg;
+    vec2 f3 = texelFetch(textureSampler, coord + ivec2(1, 1), 0).rg;
+    vec2 f4 = texelFetch(textureSampler, coord + ivec2(0, 1), 0).rg;
+
+    float minz = min(min(min(f1.x, f2.x), f3.x), f4.x);
+    float maxz = max(max(max(f1.y, f2.y), f3.y), f4.y);
+
+    glFragColor = vec4(minz, maxz, 0., 0.);
+}
+
+#elif defined(ONEBEFORELAST)
+uniform ivec2 texSize;
+
+void main(void)
+{
+    ivec2 coord = ivec2(vUV * vec2(texSize - 1));
+
+    vec2 f1 = texelFetch(textureSampler, coord % texSize, 0).rg;
+    vec2 f2 = texelFetch(textureSampler, (coord + ivec2(1, 0)) % texSize, 0).rg;
+    vec2 f3 = texelFetch(textureSampler, (coord + ivec2(1, 1)) % texSize, 0).rg;
+    vec2 f4 = texelFetch(textureSampler, (coord + ivec2(0, 1)) % texSize, 0).rg;
+
+    float minz = min(f1.x, f2.x);
+    float maxz = max(f1.y, f2.y);
+
+    glFragColor = vec4(minz, maxz, 0., 0.);
+}
+
+#elif defined(LAST)
+void main(void)
+{
+    discard;
+    glFragColor = vec4(0.);
+}
+#endif

+ 2 - 2
src/sceneComponent.ts

@@ -70,9 +70,9 @@ export class SceneComponentConstants {
 
     public static readonly STEP_AFTERRENDER_AUDIO = 0;
 
-    public static readonly STEP_GATHERRENDERTARGETS_SHADOWGENERATOR = 0;
+    public static readonly STEP_GATHERRENDERTARGETS_DEPTHRENDERER = 0;
     public static readonly STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER = 1;
-    public static readonly STEP_GATHERRENDERTARGETS_DEPTHRENDERER = 2;
+    public static readonly STEP_GATHERRENDERTARGETS_SHADOWGENERATOR = 2;
     public static readonly STEP_GATHERRENDERTARGETS_POSTPROCESSRENDERPIPELINEMANAGER = 3;
 
     public static readonly STEP_GATHERACTIVECAMERARENDERTARGETS_DEPTHRENDERER = 0;