Pārlūkot izejas kodu

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js into WebGPU

sebavan 5 gadi atpakaļ
vecāks
revīzija
89a1027bdc
86 mainītis faili ar 11992 papildinājumiem un 2826 dzēšanām
  1. 516 28
      dist/preview release/babylon.d.ts
  2. 2 2
      dist/preview release/babylon.js
  3. 2094 503
      dist/preview release/babylon.max.js
  4. 1 1
      dist/preview release/babylon.max.js.map
  5. 1045 56
      dist/preview release/babylon.module.d.ts
  6. 516 28
      dist/preview release/documentation.d.ts
  7. 3 3
      dist/preview release/gui/babylon.gui.js
  8. 1 1
      dist/preview release/gui/babylon.gui.min.js
  9. 8 8
      dist/preview release/inspector/babylon.inspector.bundle.js
  10. 1641 444
      dist/preview release/inspector/babylon.inspector.bundle.max.js
  11. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js.map
  12. 3 3
      dist/preview release/loaders/babylon.glTF1FileLoader.js
  13. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.js
  14. 3 3
      dist/preview release/loaders/babylonjs.loaders.js
  15. 3 3
      dist/preview release/materialsLibrary/babylon.cellMaterial.js
  16. 3 3
      dist/preview release/materialsLibrary/babylon.customMaterial.js
  17. 1 1
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  18. 3 3
      dist/preview release/materialsLibrary/babylon.fireMaterial.js
  19. 3 3
      dist/preview release/materialsLibrary/babylon.furMaterial.js
  20. 3 3
      dist/preview release/materialsLibrary/babylon.gradientMaterial.js
  21. 3 3
      dist/preview release/materialsLibrary/babylon.gridMaterial.js
  22. 3 3
      dist/preview release/materialsLibrary/babylon.lavaMaterial.js
  23. 3 3
      dist/preview release/materialsLibrary/babylon.mixMaterial.js
  24. 3 3
      dist/preview release/materialsLibrary/babylon.normalMaterial.js
  25. 3 3
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js
  26. 3 3
      dist/preview release/materialsLibrary/babylon.simpleMaterial.js
  27. 3 3
      dist/preview release/materialsLibrary/babylon.skyMaterial.js
  28. 3 3
      dist/preview release/materialsLibrary/babylon.terrainMaterial.js
  29. 3 3
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js
  30. 3 3
      dist/preview release/materialsLibrary/babylon.waterMaterial.js
  31. 3 3
      dist/preview release/materialsLibrary/babylonjs.materials.js
  32. 1 1
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  33. 6 6
      dist/preview release/nodeEditor/babylon.nodeEditor.js
  34. 2465 1269
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js
  35. 1 1
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map
  36. 1 1
      dist/preview release/packagesSizeBaseLine.json
  37. 3 3
      dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.js
  38. 3 3
      dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.js
  39. 3 3
      dist/preview release/postProcessesLibrary/babylon.oceanPostProcess.js
  40. 3 3
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.js
  41. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.brickProceduralTexture.js
  42. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.cloudProceduralTexture.js
  43. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.fireProceduralTexture.js
  44. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.grassProceduralTexture.js
  45. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.marbleProceduralTexture.js
  46. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.normalMapProceduralTexture.js
  47. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.perlinNoiseProceduralTexture.js
  48. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.roadProceduralTexture.js
  49. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.starfieldProceduralTexture.js
  50. 3 3
      dist/preview release/proceduralTexturesLibrary/babylon.woodProceduralTexture.js
  51. 3 3
      dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.js
  52. 3 3
      dist/preview release/serializers/babylon.glTF2Serializer.js
  53. 3 3
      dist/preview release/serializers/babylonjs.serializers.js
  54. 1045 56
      dist/preview release/viewer/babylon.module.d.ts
  55. 128 124
      dist/preview release/viewer/babylon.viewer.js
  56. 3 3
      dist/preview release/viewer/babylon.viewer.max.js
  57. 3 1
      dist/preview release/what's new.md
  58. 3 10
      src/Cameras/XR/motionController/webXRMicrosoftMixedRealityController.ts
  59. 13 3
      src/Cameras/XR/motionController/webXRMotionControllerManager.ts
  60. 4 3
      src/Cameras/XR/webXRController.ts
  61. 8 1
      src/Cameras/XR/webXRInput.ts
  62. 0 1
      src/Engines/Extensions/engine.multiRender.ts
  63. 61 53
      src/Engines/Extensions/engine.renderTarget.ts
  64. 0 1
      src/Engines/Extensions/engine.renderTargetCube.ts
  65. 0 35
      src/Engines/engine.ts
  66. 0 1
      src/Engines/nullEngine.ts
  67. 62 23
      src/Engines/thinEngine.ts
  68. 21 17
      src/Inputs/scene.inputManager.ts
  69. 3 0
      src/LibDeclarations/webgl2.d.ts
  70. 1707 0
      src/Lights/Shadows/cascadedShadowGenerator.ts
  71. 1 0
      src/Lights/Shadows/index.ts
  72. 4 8
      src/Lights/Shadows/shadowGenerator.ts
  73. 9 0
      src/Lights/Shadows/shadowGeneratorSceneComponent.ts
  74. 12 2
      src/Materials/Textures/internalTexture.ts
  75. 41 13
      src/Materials/Textures/renderTargetTexture.ts
  76. 19 0
      src/Materials/Textures/videoTexture.ts
  77. 17 0
      src/Materials/materialHelper.ts
  78. 7 2
      src/PostProcesses/postProcess.ts
  79. 1 1
      src/PostProcesses/postProcessManager.ts
  80. 76 2
      src/Shaders/ShadersInclude/lightFragment.fx
  81. 45 1
      src/Shaders/ShadersInclude/lightFragmentDeclaration.fx
  82. 45 1
      src/Shaders/ShadersInclude/lightUboDeclaration.fx
  83. 218 1
      src/Shaders/ShadersInclude/shadowsFragmentFunctions.fx
  84. 7 1
      src/Shaders/ShadersInclude/shadowsVertex.fx
  85. 9 0
      src/Shaders/shadowMap.fragment.fx
  86. 9 0
      src/Shaders/shadowMap.vertex.fx

+ 516 - 28
dist/preview release/babylon.d.ts

@@ -8442,6 +8442,7 @@ declare module BABYLON {
             createRenderTargetTexture(size: number | {
                 width: number;
                 height: number;
+                layers?: number;
             }, options: boolean | RenderTargetCreationOptions): InternalTexture;
             /**
              * Creates a depth stencil texture.
@@ -8453,11 +8454,13 @@ declare module BABYLON {
             createDepthStencilTexture(size: number | {
                 width: number;
                 height: number;
+                layers?: number;
             }, options: DepthTextureCreationOptions): InternalTexture;
             /** @hidden */
             _createDepthStencilTexture(size: number | {
                 width: number;
                 height: number;
+                layers?: number;
             }, options: DepthTextureCreationOptions): InternalTexture;
         }
 }
@@ -9403,11 +9406,6 @@ declare module BABYLON {
          */
         getShadowMap(): Nullable<RenderTargetTexture>;
         /**
-         * Gets the RTT used during rendering (can be a blurred version of the shadow map or the shadow map itself).
-         * @returns The render target texture if the shadow map is present otherwise, null
-         */
-        getShadowMapForRendering(): Nullable<RenderTargetTexture>;
-        /**
          * Determine wheter the shadow generator is ready or not (mainly all effects and related post processes needs to be ready).
          * @param subMesh The submesh we want to render in the shadow map
          * @param useInstances Defines wether will draw in the map using instances
@@ -9444,7 +9442,7 @@ declare module BABYLON {
          * @param onCompiled Callback triggered at the and of the effects compilation
          * @param options Sets of optional options forcing the compilation with different modes
          */
-        forceCompilation(onCompiled?: (generator: ShadowGenerator) => void, options?: Partial<{
+        forceCompilation(onCompiled?: (generator: IShadowGenerator) => void, options?: Partial<{
             useInstances: boolean;
         }>): void;
         /**
@@ -9853,7 +9851,7 @@ declare module BABYLON {
          * @param onCompiled Callback triggered at the and of the effects compilation
          * @param options Sets of optional options forcing the compilation with different modes
          */
-        forceCompilation(onCompiled?: (generator: ShadowGenerator) => void, options?: Partial<{
+        forceCompilation(onCompiled?: (generator: IShadowGenerator) => void, options?: Partial<{
             useInstances: boolean;
         }>): void;
         /**
@@ -15558,6 +15556,7 @@ declare module BABYLON {
         private _options;
         private _reusable;
         private _textureType;
+        private _textureFormat;
         /**
         * Smart array of input and output textures for the post process.
         * @hidden
@@ -15660,10 +15659,11 @@ declare module BABYLON {
          * @param vertexUrl The url of the vertex shader to be used. (default: "postprocess")
          * @param indexParameters The index parameters to be used for babylons include syntax "#include<kernelBlurVaryingDeclaration>[0..varyingCount]". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx
          * @param blockCompilation If the shader should not be compiled imediatly. (default: false)
+         * @param textureFormat Format of textures used when performing the post process. (default: TEXTUREFORMAT_RGBA)
          */
         constructor(
         /** Name of the PostProcess. */
-        name: string, fragmentUrl: string, parameters: Nullable<string[]>, samplers: Nullable<string[]>, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, defines?: Nullable<string>, textureType?: number, vertexUrl?: string, indexParameters?: any, blockCompilation?: boolean);
+        name: string, fragmentUrl: string, parameters: Nullable<string[]>, samplers: Nullable<string[]>, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, defines?: Nullable<string>, textureType?: number, vertexUrl?: string, indexParameters?: any, blockCompilation?: boolean, textureFormat?: number);
         /**
          * Gets a string idenfifying the name of the class
          * @returns "PostProcess" string
@@ -20319,6 +20319,7 @@ declare module BABYLON {
         protected _size: number | {
             width: number;
             height: number;
+            layers?: number;
         };
         protected _initialSizeParameter: number | {
             width: number;
@@ -20363,7 +20364,7 @@ declare module BABYLON {
          * depth texture.
          * Otherwise, return null.
          */
-        depthStencilTexture: Nullable<InternalTexture>;
+        get depthStencilTexture(): Nullable<InternalTexture>;
         /**
          * Instantiate a render target texture. This is mainly used to render of screen the scene to for instance apply post processse
          * or used a shadow, depth texture...
@@ -20384,6 +20385,7 @@ declare module BABYLON {
         constructor(name: string, size: number | {
             width: number;
             height: number;
+            layers?: number;
         } | {
             ratio: number;
         }, scene: Nullable<Scene>, generateMipMaps?: boolean, doNotChangeAspectRatio?: boolean, type?: number, isCube?: boolean, samplingMode?: number, generateDepthBuffer?: boolean, generateStencilBuffer?: boolean, isMulti?: boolean, format?: number, delayAllocation?: boolean);
@@ -20446,6 +20448,11 @@ declare module BABYLON {
          */
         getRenderHeight(): number;
         /**
+         * Gets the actual number of layers of the texture.
+         * @returns the number of layers
+         */
+        getRenderLayers(): number;
+        /**
          * Get if the texture can be rescaled or not.
          */
         get canRescale(): boolean;
@@ -20483,8 +20490,9 @@ declare module BABYLON {
         /**
          * @hidden
          * @param faceIndex face index to bind to if this is a cubetexture
+         * @param layer defines the index of the texture to bind in the array
          */
-        _bindFrameBuffer(faceIndex?: number): void;
+        _bindFrameBuffer(faceIndex?: number, layer?: number): void;
         protected unbindFrameBuffer(engine: Engine, faceIndex: number): void;
         private renderToTarget;
         /**
@@ -30555,6 +30563,7 @@ declare module BABYLON {
         private _settings;
         private _createInternalTextureOnEvent;
         private _frameId;
+        private _currentSrc;
         /**
          * Creates a video texture.
          * If you want to display a video in your scene, this is the special texture for that.
@@ -30593,6 +30602,11 @@ declare module BABYLON {
          */
         updateURL(url: string): void;
         /**
+         * Clones the texture.
+         * @returns the cloned texture
+         */
+        clone(): VideoTexture;
+        /**
          * Dispose the texture and release its associated resources.
          */
         dispose(): void;
@@ -31089,10 +31103,10 @@ declare module BABYLON {
          * @param requiredWidth The width of the target to render to
          * @param requiredHeight The height of the target to render to
          * @param forceFullscreenViewport Forces the viewport to be the entire texture/screen if true
-         * @param depthStencilTexture The depth stencil texture to use to render
-         * @param lodLevel defines le lod level to bind to the frame buffer
+         * @param lodLevel defines the lod level to bind to the frame buffer
+         * @param layer defines the 2d array index to bind to frame buffer to
          */
-        bindFramebuffer(texture: InternalTexture, faceIndex?: number, requiredWidth?: number, requiredHeight?: number, forceFullscreenViewport?: boolean, depthStencilTexture?: InternalTexture, lodLevel?: number): void;
+        bindFramebuffer(texture: InternalTexture, faceIndex?: number, requiredWidth?: number, requiredHeight?: number, forceFullscreenViewport?: boolean, lodLevel?: number, layer?: number): void;
         /** @hidden */
         _bindUnboundFramebuffer(framebuffer: Nullable<WebGLFramebuffer>): void;
         /**
@@ -31614,11 +31628,24 @@ declare module BABYLON {
         _setupDepthStencilTexture(internalTexture: InternalTexture, size: number | {
             width: number;
             height: number;
+            layers?: number;
         }, generateStencil: boolean, bilinearFiltering: boolean, comparisonFunction: number): void;
         /** @hidden */
         _uploadCompressedDataToTextureDirectly(texture: InternalTexture, internalFormat: number, width: number, height: number, data: ArrayBufferView, faceIndex?: number, lod?: number): void;
         /** @hidden */
         _uploadDataToTextureDirectly(texture: InternalTexture, imageData: ArrayBufferView, faceIndex?: number, lod?: number, babylonInternalFormat?: number, useTextureWidthAndHeight?: boolean): void;
+        /**
+         * Update a portion of an internal texture
+         * @param texture defines the texture to update
+         * @param imageData defines the data to store into the texture
+         * @param xOffset defines the x coordinates of the update rectangle
+         * @param yOffset defines the y coordinates of the update rectangle
+         * @param width defines the width of the update rectangle
+         * @param height defines the height of the update rectangle
+         * @param faceIndex defines the face index if texture is a cube (0 by default)
+         * @param lod defines the lod level to update (0 by default)
+         */
+        updateTextureData(texture: InternalTexture, imageData: ArrayBufferView, xOffset: number, yOffset: number, width: number, height: number, faceIndex?: number, lod?: number): void;
         /** @hidden */
         _uploadArrayBufferViewToTexture(texture: InternalTexture, imageData: ArrayBufferView, faceIndex?: number, lod?: number): void;
         protected _prepareWebGLTextureContinuation(texture: InternalTexture, scene: Nullable<ISceneLike>, noMipmap: boolean, isCompressed: boolean, samplingMode: number): void;
@@ -32155,6 +32182,8 @@ declare module BABYLON {
         /** @hidden */
         _lodGenerationOffset: number;
         /** @hidden */
+        _depthStencilTexture: Nullable<InternalTexture>;
+        /** @hidden */
         _colorTextureArray: Nullable<WebGLTexture>;
         /** @hidden */
         _depthStencilTextureArray: Nullable<WebGLTexture>;
@@ -33556,11 +33585,6 @@ declare module BABYLON {
         /** @hidden */
         _uploadImageToTexture(texture: InternalTexture, image: HTMLImageElement | ImageBitmap, faceIndex?: number, lod?: number): void;
         /**
-         * Sets the frame buffer Depth / Stencil attachement of the render target to the defined depth stencil texture.
-         * @param renderTarget The render target to set the frame buffer for
-         */
-        setFrameBufferDepthStencilTexture(renderTarget: RenderTargetTexture): void;
-        /**
          * Update a dynamic index buffer
          * @param indexBuffer defines the target index buffer
          * @param indices defines the data to update
@@ -34544,8 +34568,9 @@ declare module BABYLON {
         * @param attachUp defines if you want to attach events to pointerup
         * @param attachDown defines if you want to attach events to pointerdown
         * @param attachMove defines if you want to attach events to pointermove
+        * @param elementToAttachTo defines the target DOM element to attach to (will use the canvas by default)
         */
-        attachControl(attachUp?: boolean, attachDown?: boolean, attachMove?: boolean): void;
+        attachControl(attachUp?: boolean, attachDown?: boolean, attachMove?: boolean, elementToAttachTo?: Nullable<HTMLElement>): void;
         /**
          * Detaches all event handlers
          */
@@ -43600,9 +43625,10 @@ declare module BABYLON {
          *
          * @param xrInput the xrInput to which a new controller is initialized
          * @param scene the scene to which the model will be added
+         * @param forceProfile force a certain profile for this controller
          * @return the motion controller class for this profile id or the generic standard class if none was found
          */
-        static GetMotionControllerWithXRInput(xrInput: XRInputSource, scene: Scene): WebXRAbstractMotionController;
+        static GetMotionControllerWithXRInput(xrInput: XRInputSource, scene: Scene, forceProfile?: string): WebXRAbstractMotionController;
         /**
          * Find a fallback profile if the profile was not found. There are a few predefined generic profiles.
          * @param profileId the profile to which a fallback needs to be found
@@ -43656,11 +43682,11 @@ declare module BABYLON {
          * @see https://doc.babylonjs.com/how_to/webxr
          * @param scene the scene which the controller should be associated to
          * @param inputSource the underlying input source for the controller
-         * @param parentContainer parent that the controller meshes should be children of
+         * @param controllerProfile An optional controller profile for this input. This will override the xrInput profile.
          */
         constructor(scene: Scene, 
         /** The underlying input source for the controller  */
-        inputSource: XRInputSource);
+        inputSource: XRInputSource, controllerProfile?: string);
         /**
          * Updates the controller pose based on the given XRFrame
          * @param xrFrame xr frame to update the pose with
@@ -43692,6 +43718,12 @@ declare module BABYLON {
          * If set to true no model will be automatically loaded
          */
         doNotLoadControllerMeshes?: boolean;
+        /**
+         * If set, this profile will be used for all controllers loaded (for example "microsoft-mixed-reality")
+         * If not found, the xr input profile data will be used.
+         * Profiles are defined here - https://github.com/immersive-web/webxr-input-profiles/
+         */
+        forceInputProfile?: string;
     }
     /**
      * XR input used to track XR inputs such as controllers/rays
@@ -44831,11 +44863,6 @@ declare module BABYLON {
                     "componentProperty": string;
                     "states": string[];
                 };
-                "menu": {
-                    "rootNodeName": string;
-                    "componentProperty": string;
-                    "states": string[];
-                };
             };
             axes: {
                 "xr-standard-touchpad": {
@@ -46465,7 +46492,6 @@ declare module BABYLON {
          * @param requiredWidth The width of the target to render to
          * @param requiredHeight The height of the target to render to
          * @param forceFullscreenViewport Forces the viewport to be the entire texture/screen if true
-         * @param depthStencilTexture The depth stencil texture to use to render
          * @param lodLevel defines le lod level to bind to the frame buffer
          */
         bindFramebuffer(texture: InternalTexture, faceIndex?: number, requiredWidth?: number, requiredHeight?: number, forceFullscreenViewport?: boolean): void;
@@ -53649,6 +53675,465 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * A CSM implementation allowing casting shadows on large scenes.
+     * Documentation : https://doc.babylonjs.com/babylon101/cascadedShadows
+     * Based on: https://github.com/TheRealMJP/Shadows and https://johanmedestrom.wordpress.com/2016/03/18/opengl-cascaded-shadow-maps/
+     */
+    export class CascadedShadowGenerator implements IShadowGenerator {
+        private static readonly frustumCornersNDCSpace;
+        /**
+         * Defines the default number of cascades used by the CSM.
+         */
+        static readonly DEFAULT_CASCADES_COUNT: number;
+        /**
+         * Defines the minimum number of cascades used by the CSM.
+         */
+        static readonly MIN_CASCADES_COUNT: number;
+        /**
+         * Defines the maximum number of cascades used by the CSM.
+         */
+        static readonly MAX_CASCADES_COUNT: number;
+        /**
+         * Shadow generator mode None: no filtering applied.
+         */
+        static readonly FILTER_NONE: number;
+        /**
+         * Shadow generator mode PCF: Percentage Closer Filtering
+         * benefits from Webgl 2 shadow samplers. Fallback to Poisson Sampling in Webgl 1
+         * (https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch11.html)
+         */
+        static readonly FILTER_PCF: number;
+        /**
+         * Shadow generator mode PCSS: Percentage Closering Soft Shadow.
+         * benefits from Webgl 2 shadow samplers. Fallback to Poisson Sampling in Webgl 1
+         * Contact Hardening
+         */
+        static readonly FILTER_PCSS: number;
+        /**
+         * Reserved for PCF and PCSS
+         * Highest Quality.
+         *
+         * Execute PCF on a 5*5 kernel improving a lot the shadow aliasing artifacts.
+         *
+         * Execute PCSS with 32 taps blocker search and 64 taps PCF.
+         */
+        static readonly QUALITY_HIGH: number;
+        /**
+         * Reserved for PCF and PCSS
+         * Good tradeoff for quality/perf cross devices
+         *
+         * Execute PCF on a 3*3 kernel.
+         *
+         * Execute PCSS with 16 taps blocker search and 32 taps PCF.
+         */
+        static readonly QUALITY_MEDIUM: number;
+        /**
+         * Reserved for PCF and PCSS
+         * The lowest quality but the fastest.
+         *
+         * Execute PCF on a 1*1 kernel.
+         *
+         * Execute PCSS with 16 taps blocker search and 16 taps PCF.
+         */
+        static readonly QUALITY_LOW: number;
+        private static readonly _CLEARONE;
+        /**
+         * Observable triggered before the shadow is rendered. Can be used to update internal effect state
+         */
+        onBeforeShadowMapRenderObservable: Observable<Effect>;
+        /**
+         * Observable triggered after the shadow is rendered. Can be used to restore internal effect state
+         */
+        onAfterShadowMapRenderObservable: Observable<Effect>;
+        /**
+         * Observable triggered before a mesh is rendered in the shadow map.
+         * Can be used to update internal effect state (that you can get from the onBeforeShadowMapRenderObservable)
+         */
+        onBeforeShadowMapRenderMeshObservable: Observable<Mesh>;
+        /**
+         * Observable triggered after a mesh is rendered in the shadow map.
+         * Can be used to update internal effect state (that you can get from the onAfterShadowMapRenderObservable)
+         */
+        onAfterShadowMapRenderMeshObservable: Observable<Mesh>;
+        private _bias;
+        /**
+         * Gets the bias: offset applied on the depth preventing acnea (in light direction).
+         */
+        get bias(): number;
+        /**
+         * Sets the bias: offset applied on the depth preventing acnea (in light direction).
+         */
+        set bias(bias: number);
+        private _normalBias;
+        /**
+         * Gets the normalBias: offset applied on the depth preventing acnea (along side the normal direction and proportinal to the light/normal angle).
+         */
+        get normalBias(): number;
+        /**
+         * Sets the normalBias: offset applied on the depth preventing acnea (along side the normal direction and proportinal to the light/normal angle).
+         */
+        set normalBias(normalBias: number);
+        private _filter;
+        /**
+         * Gets the current mode of the shadow generator (normal, PCF, PCSS...).
+         * The returned value is a number equal to one of the available mode defined in ShadowMap.FILTER_x like _FILTER_NONE
+         */
+        get filter(): number;
+        /**
+         * Sets the current mode of the shadow generator (normal, PCF, PCSS...).
+         * The returned value is a number equal to one of the available mode defined in ShadowMap.FILTER_x like _FILTER_NONE
+         */
+        set filter(value: number);
+        /**
+         * Gets if the current filter is set to "PCF" (percentage closer filtering).
+         */
+        get usePercentageCloserFiltering(): boolean;
+        /**
+         * Sets the current filter to "PCF" (percentage closer filtering).
+         */
+        set usePercentageCloserFiltering(value: boolean);
+        private _filteringQuality;
+        /**
+         * Gets the PCF or PCSS Quality.
+         * Only valid if usePercentageCloserFiltering or usePercentageCloserFiltering is true.
+         */
+        get filteringQuality(): number;
+        /**
+         * Sets the PCF or PCSS Quality.
+         * Only valid if usePercentageCloserFiltering or usePercentageCloserFiltering is true.
+         */
+        set filteringQuality(filteringQuality: number);
+        /**
+         * Gets if the current filter is set to "PCSS" (contact hardening).
+         */
+        get useContactHardeningShadow(): boolean;
+        /**
+         * Sets the current filter to "PCSS" (contact hardening).
+         */
+        set useContactHardeningShadow(value: boolean);
+        private _contactHardeningLightSizeUVRatio;
+        /**
+         * Gets the Light Size (in shadow map uv unit) used in PCSS to determine the blocker search area and the penumbra size.
+         * Using a ratio helps keeping shape stability independently of the map size.
+         *
+         * It does not account for the light projection as it was having too much
+         * instability during the light setup or during light position changes.
+         *
+         * Only valid if useContactHardeningShadow is true.
+         */
+        get contactHardeningLightSizeUVRatio(): number;
+        /**
+         * Sets the Light Size (in shadow map uv unit) used in PCSS to determine the blocker search area and the penumbra size.
+         * Using a ratio helps keeping shape stability independently of the map size.
+         *
+         * It does not account for the light projection as it was having too much
+         * instability during the light setup or during light position changes.
+         *
+         * Only valid if useContactHardeningShadow is true.
+         */
+        set contactHardeningLightSizeUVRatio(contactHardeningLightSizeUVRatio: number);
+        private _darkness;
+        /** Gets or sets the actual darkness of a shadow */
+        get darkness(): number;
+        set darkness(value: number);
+        /**
+         * Returns the darkness value (float). This can only decrease the actual darkness of a shadow.
+         * 0 means strongest and 1 would means no shadow.
+         * @returns the darkness.
+         */
+        getDarkness(): number;
+        /**
+         * Sets the darkness value (float). This can only decrease the actual darkness of a shadow.
+         * @param darkness The darkness value 0 means strongest and 1 would means no shadow.
+         * @returns the shadow generator allowing fluent coding.
+         */
+        setDarkness(darkness: number): CascadedShadowGenerator;
+        /**
+         * Gets or sets the actual darkness of the soft shadows while using PCSS filtering (value between 0. and 1.)
+         */
+        penumbraDarkness: number;
+        private _transparencyShadow;
+        /** Gets or sets the ability to have transparent shadow  */
+        get transparencyShadow(): boolean;
+        set transparencyShadow(value: boolean);
+        /**
+         * Sets the ability to have transparent shadow (boolean).
+         * @param transparent True if transparent else False
+         * @returns the shadow generator allowing fluent coding
+         */
+        setTransparencyShadow(transparent: boolean): CascadedShadowGenerator;
+        private _numCascades;
+        /**
+         * Gets or set the number of cascades used by the CSM.
+         */
+        get numCascades(): number;
+        set numCascades(value: number);
+        /**
+         * Sets this to true if you want that the edges of the shadows don't "swimm" / "shimmer" when rotating the camera.
+         * The trade off is that you loose some precision in the shadow rendering when enabling this setting.
+         */
+        stabilizeCascades: boolean;
+        private _shadowMap;
+        /**
+         * Gets the main RTT containing the shadow map (usually storing depth from the light point of view).
+         * @returns The render target texture if present otherwise, null
+         */
+        getShadowMap(): Nullable<RenderTargetTexture>;
+        protected _freezeShadowCastersBoundingInfo: boolean;
+        private _freezeShadowCastersBoundingInfoObservable;
+        /**
+         * Enables or disables the shadow casters bounding info computation.
+         * If your shadow casters don't move, you can disable this feature.
+         * If it is enabled, the bounding box computation is done every frame.
+         */
+        get freezeShadowCastersBoundingInfo(): boolean;
+        set freezeShadowCastersBoundingInfo(freeze: boolean);
+        private _scbiMin;
+        private _scbiMax;
+        protected _computeShadowCastersBoundingInfo(): void;
+        protected _shadowCastersBoundingInfo: BoundingInfo;
+        /**
+         * Gets or sets the shadow casters bounding info.
+         * If you provide your own shadow casters bounding info, first enable freezeShadowCastersBoundingInfo
+         * so that the system won't overwrite the bounds you provide
+         */
+        get shadowCastersBoundingInfo(): BoundingInfo;
+        set shadowCastersBoundingInfo(boundingInfo: BoundingInfo);
+        protected _breaksAreDirty: boolean;
+        protected _minDistance: number;
+        protected _maxDistance: number;
+        /**
+         * Sets the minimal and maximal distances to use when computing the cascade breaks.
+         *
+         * The values of min / max are typically the depth zmin and zmax values of your scene, for a given frame.
+         * If you don't know these values, simply leave them to their defaults and don't call this function.
+         * @param min minimal distance for the breaks (default to 0.)
+         * @param max maximal distance for the breaks (default to 1.)
+         */
+        setMinMaxDistance(min: number, max: number): void;
+        /**
+         * Gets the class name of that object
+         * @returns "ShadowGenerator"
+         */
+        getClassName(): string;
+        /**
+         * Helper function to add a mesh and its descendants to the list of shadow casters.
+         * @param mesh Mesh to add
+         * @param includeDescendants boolean indicating if the descendants should be added. Default to true
+         * @returns the Shadow Generator itself
+         */
+        addShadowCaster(mesh: AbstractMesh, includeDescendants?: boolean): CascadedShadowGenerator;
+        /**
+         * Helper function to remove a mesh and its descendants from the list of shadow casters
+         * @param mesh Mesh to remove
+         * @param includeDescendants boolean indicating if the descendants should be removed. Default to true
+         * @returns the Shadow Generator itself
+         */
+        removeShadowCaster(mesh: AbstractMesh, includeDescendants?: boolean): CascadedShadowGenerator;
+        /**
+         * Controls the extent to which the shadows fade out at the edge of the frustum
+         */
+        frustumEdgeFalloff: number;
+        private _light;
+        /**
+         * Returns the associated light object.
+         * @returns the light generating the shadow
+         */
+        getLight(): DirectionalLight;
+        /**
+         * If true the shadow map is generated by rendering the back face of the mesh instead of the front face.
+         * This can help with self-shadowing as the geometry making up the back of objects is slightly offset.
+         * It might on the other hand introduce peter panning.
+         */
+        forceBackFacesOnly: boolean;
+        private _cascadeMinExtents;
+        private _cascadeMaxExtents;
+        /**
+         * Gets a cascade minimum extents
+         * @param cascadeIndex index of the cascade
+         * @returns the minimum cascade extents
+         */
+        getCascadeMinExtents(cascadeIndex: number): Nullable<Vector3>;
+        /**
+         * Gets a cascade maximum extents
+         * @param cascadeIndex index of the cascade
+         * @returns the maximum cascade extents
+         */
+        getCascadeMaxExtents(cascadeIndex: number): Nullable<Vector3>;
+        private _scene;
+        private _lightDirection;
+        private _effect;
+        private _cascades;
+        private _cachedPosition;
+        private _cachedDirection;
+        private _cachedDefines;
+        private _currentRenderID;
+        private _mapSize;
+        private _currentLayer;
+        private _textureType;
+        private _defaultTextureMatrix;
+        private _storedUniqueId;
+        private _viewSpaceFrustumsZ;
+        private _viewMatrices;
+        private _projectionMatrices;
+        private _transformMatrices;
+        private _transformMatricesAsArray;
+        private _frustumLengths;
+        private _lightSizeUVCorrection;
+        private _depthCorrection;
+        private _frustumCornersWorldSpace;
+        private _frustumCenter;
+        private _shadowCameraPos;
+        private _shadowMaxZ;
+        /**
+         * Gets the shadow max z distance. It's the limit beyond which shadows are not displayed.
+         * It defaults to camera.maxZ
+         */
+        get shadowMaxZ(): number;
+        /**
+         * Sets the shadow max z distance.
+         */
+        set shadowMaxZ(value: number);
+        protected _debug: boolean;
+        /**
+         * Gets or sets the debug flag.
+         * When enabled, the cascades are materialized by different colors on the screen.
+         */
+        get debug(): boolean;
+        set debug(dbg: boolean);
+        private _depthClamp;
+        /**
+         * Gets or sets the depth clamping value.
+         *
+         * When enabled, it improves the shadow quality because the near z plane of the light frustum don't need to be adjusted
+         * to account for the shadow casters far away.
+         *
+         * Note that this property is incompatible with PCSS filtering, so it won't be used in that case.
+         */
+        get depthClamp(): boolean;
+        set depthClamp(value: boolean);
+        /**
+         * Gets or sets the percentage of blending between two cascades (value between 0. and 1.).
+         * It defaults to 0.1 (10% blending).
+         */
+        cascadeBlendPercentage: number;
+        private _lambda;
+        /**
+         * Gets or set the lambda parameter.
+         * This parameter is used to split the camera frustum and create the cascades.
+         * It's a value between 0. and 1.: If 0, the split is a uniform split of the frustum, if 1 it is a logarithmic split.
+         * For all values in-between, it's a linear combination of the uniform and logarithm split algorithm.
+         */
+        get lambda(): number;
+        set lambda(value: number);
+        /**
+         * Gets the view matrix corresponding to a given cascade
+         * @param cascadeNum cascade to retrieve the view matrix from
+         * @returns the cascade view matrix
+         */
+        getCascadeViewMatrix(cascadeNum: number): Nullable<Matrix>;
+        /**
+         * 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
+         * you change the camera near/far planes!
+         */
+        splitFrustum(): void;
+        private _splitFrustum;
+        /**
+         * Gets the CSM transformation matrix used to project the meshes into the map from the light point of view.
+         * (eq to view projection * shadow projection matrices)
+         * @param cascadeIndex index number of the cascaded shadow map
+         * @returns The transform matrix used to create the CSM shadow map
+         */
+        getCSMTransformMatrix(cascadeIndex: number): Matrix;
+        private _computeFrustumInWorldSpace;
+        private _computeCascadeFrustum;
+        /** @hidden */
+        static _SceneComponentInitialization: (scene: Scene) => void;
+        /**
+         * Creates a Cascaded Shadow Generator object.
+         * A ShadowGenerator is the required tool to use the shadows.
+         * Each directional light casting shadows needs to use its own ShadowGenerator.
+         * Documentation : https://doc.babylonjs.com/babylon101/cascadedShadows
+         * @param mapSize The size of the texture what stores the shadows. Example : 1024.
+         * @param light The directional light object generating the shadows.
+         * @param usefulFloatFirst By default the generator will try to use half float textures but if you need precision (for self shadowing for instance), you can use this option to enforce full float texture.
+         */
+        constructor(mapSize: number, light: DirectionalLight, usefulFloatFirst?: boolean);
+        private _initializeGenerator;
+        private _initializeShadowMap;
+        private _renderForShadowMap;
+        private _renderSubMeshForShadowMap;
+        private _applyFilterValues;
+        /**
+         * Forces all the attached effect to compile to enable rendering only once ready vs. lazyly compiling effects.
+         * @param onCompiled Callback triggered at the and of the effects compilation
+         * @param options Sets of optional options forcing the compilation with different modes
+         */
+        forceCompilation(onCompiled?: (generator: IShadowGenerator) => void, options?: Partial<{
+            useInstances: boolean;
+        }>): void;
+        /**
+         * Forces all the attached effect to compile to enable rendering only once ready vs. lazyly compiling effects.
+         * @param options Sets of optional options forcing the compilation with different modes
+         * @returns A promise that resolves when the compilation completes
+         */
+        forceCompilationAsync(options?: Partial<{
+            useInstances: boolean;
+        }>): Promise<void>;
+        /**
+         * Determine wheter the shadow generator is ready or not (mainly all effects and related post processes needs to be ready).
+         * @param subMesh The submesh we want to render in the shadow map
+         * @param useInstances Defines wether will draw in the map using instances
+         * @returns true if ready otherwise, false
+         */
+        isReady(subMesh: SubMesh, useInstances: boolean): boolean;
+        /**
+         * Prepare all the defines in a material relying on a shadow map at the specified light index.
+         * @param defines Defines of the material we want to update
+         * @param lightIndex Index of the light in the enabled light list of the material
+         */
+        prepareDefines(defines: any, lightIndex: number): void;
+        /**
+         * Binds the shadow related information inside of an effect (information like near, far, darkness...
+         * defined in the generator but impacting the effect).
+         * @param lightIndex Index of the light in the enabled light list of the material owning the effect
+         * @param effect The effect we are binfing the information for
+         */
+        bindShadowLight(lightIndex: string, effect: Effect): void;
+        /**
+         * Gets the transformation matrix of the first cascade used to project the meshes into the map from the light point of view.
+         * (eq to view projection * shadow projection matrices)
+         * @returns The transform matrix used to create the shadow map
+         */
+        getTransformMatrix(): Matrix;
+        /**
+         * Recreates the shadow map dependencies like RTT and post processes. This can be used during the switch between
+         * Cube and 2D textures for instance.
+         */
+        recreateShadowMap(): void;
+        private _disposeRTT;
+        /**
+         * Disposes the ShadowGenerator.
+         * Returns nothing.
+         */
+        dispose(): void;
+        /**
+         * Serializes the shadow generator setup to a json object.
+         * @returns The serialized JSON object
+         */
+        serialize(): any;
+        /**
+         * Parses a serialized ShadowGenerator and returns a new ShadowGenerator.
+         * @param parsedShadowGenerator The JSON object to parse
+         * @param scene The scene to create the shadow map for
+         * @returns The parsed shadow generator
+         */
+        static Parse(parsedShadowGenerator: any, scene: Scene): CascadedShadowGenerator;
+    }
+}
+declare module BABYLON {
+    /**
      * Defines the shadow generator component responsible to manage any shadow generators
      * in a given scene.
      */
@@ -67843,11 +68328,14 @@ interface WebGLRenderingContext {
     readonly UNSIGNED_INT_10F_11F_11F_REV: number;
     readonly UNSIGNED_INT_5_9_9_9_REV: number;
     readonly FLOAT_32_UNSIGNED_INT_24_8_REV: number;
+    readonly DEPTH_COMPONENT32F: number;
 
     texImage3D(target: number, level: number, internalformat: number, width: number, height: number, depth: number, border: number, format: number, type: number, pixels: ArrayBufferView | null): void;
     texImage3D(target: number, level: number, internalformat: number, width: number, height: number, depth: number, border: number, format: number, type: number, pixels: ArrayBufferView, offset: number): void;
     texImage3D(target: number, level: number, internalformat: number, width: number, height: number, depth: number, border: number, format: number, type: number, pixels: ImageBitmap | ImageData | HTMLVideoElement | HTMLImageElement | HTMLCanvasElement): void;
 
+    framebufferTextureLayer(target: number, attachment: number, texture: WebGLTexture | null, level: number, layer: number): void;
+
     compressedTexImage3D(target: number, level: number, internalformat: number, width: number, height: number, depth: number, border: number, data: ArrayBufferView, offset?: number, length?: number): void;
 
     readonly TRANSFORM_FEEDBACK: number;

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 2 - 2
dist/preview release/babylon.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 2094 - 503
dist/preview release/babylon.max.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/babylon.max.js.map


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1045 - 56
dist/preview release/babylon.module.d.ts


+ 516 - 28
dist/preview release/documentation.d.ts

@@ -8442,6 +8442,7 @@ declare module BABYLON {
             createRenderTargetTexture(size: number | {
                 width: number;
                 height: number;
+                layers?: number;
             }, options: boolean | RenderTargetCreationOptions): InternalTexture;
             /**
              * Creates a depth stencil texture.
@@ -8453,11 +8454,13 @@ declare module BABYLON {
             createDepthStencilTexture(size: number | {
                 width: number;
                 height: number;
+                layers?: number;
             }, options: DepthTextureCreationOptions): InternalTexture;
             /** @hidden */
             _createDepthStencilTexture(size: number | {
                 width: number;
                 height: number;
+                layers?: number;
             }, options: DepthTextureCreationOptions): InternalTexture;
         }
 }
@@ -9403,11 +9406,6 @@ declare module BABYLON {
          */
         getShadowMap(): Nullable<RenderTargetTexture>;
         /**
-         * Gets the RTT used during rendering (can be a blurred version of the shadow map or the shadow map itself).
-         * @returns The render target texture if the shadow map is present otherwise, null
-         */
-        getShadowMapForRendering(): Nullable<RenderTargetTexture>;
-        /**
          * Determine wheter the shadow generator is ready or not (mainly all effects and related post processes needs to be ready).
          * @param subMesh The submesh we want to render in the shadow map
          * @param useInstances Defines wether will draw in the map using instances
@@ -9444,7 +9442,7 @@ declare module BABYLON {
          * @param onCompiled Callback triggered at the and of the effects compilation
          * @param options Sets of optional options forcing the compilation with different modes
          */
-        forceCompilation(onCompiled?: (generator: ShadowGenerator) => void, options?: Partial<{
+        forceCompilation(onCompiled?: (generator: IShadowGenerator) => void, options?: Partial<{
             useInstances: boolean;
         }>): void;
         /**
@@ -9853,7 +9851,7 @@ declare module BABYLON {
          * @param onCompiled Callback triggered at the and of the effects compilation
          * @param options Sets of optional options forcing the compilation with different modes
          */
-        forceCompilation(onCompiled?: (generator: ShadowGenerator) => void, options?: Partial<{
+        forceCompilation(onCompiled?: (generator: IShadowGenerator) => void, options?: Partial<{
             useInstances: boolean;
         }>): void;
         /**
@@ -15558,6 +15556,7 @@ declare module BABYLON {
         private _options;
         private _reusable;
         private _textureType;
+        private _textureFormat;
         /**
         * Smart array of input and output textures for the post process.
         * @hidden
@@ -15660,10 +15659,11 @@ declare module BABYLON {
          * @param vertexUrl The url of the vertex shader to be used. (default: "postprocess")
          * @param indexParameters The index parameters to be used for babylons include syntax "#include<kernelBlurVaryingDeclaration>[0..varyingCount]". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx
          * @param blockCompilation If the shader should not be compiled imediatly. (default: false)
+         * @param textureFormat Format of textures used when performing the post process. (default: TEXTUREFORMAT_RGBA)
          */
         constructor(
         /** Name of the PostProcess. */
-        name: string, fragmentUrl: string, parameters: Nullable<string[]>, samplers: Nullable<string[]>, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, defines?: Nullable<string>, textureType?: number, vertexUrl?: string, indexParameters?: any, blockCompilation?: boolean);
+        name: string, fragmentUrl: string, parameters: Nullable<string[]>, samplers: Nullable<string[]>, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, defines?: Nullable<string>, textureType?: number, vertexUrl?: string, indexParameters?: any, blockCompilation?: boolean, textureFormat?: number);
         /**
          * Gets a string idenfifying the name of the class
          * @returns "PostProcess" string
@@ -20319,6 +20319,7 @@ declare module BABYLON {
         protected _size: number | {
             width: number;
             height: number;
+            layers?: number;
         };
         protected _initialSizeParameter: number | {
             width: number;
@@ -20363,7 +20364,7 @@ declare module BABYLON {
          * depth texture.
          * Otherwise, return null.
          */
-        depthStencilTexture: Nullable<InternalTexture>;
+        get depthStencilTexture(): Nullable<InternalTexture>;
         /**
          * Instantiate a render target texture. This is mainly used to render of screen the scene to for instance apply post processse
          * or used a shadow, depth texture...
@@ -20384,6 +20385,7 @@ declare module BABYLON {
         constructor(name: string, size: number | {
             width: number;
             height: number;
+            layers?: number;
         } | {
             ratio: number;
         }, scene: Nullable<Scene>, generateMipMaps?: boolean, doNotChangeAspectRatio?: boolean, type?: number, isCube?: boolean, samplingMode?: number, generateDepthBuffer?: boolean, generateStencilBuffer?: boolean, isMulti?: boolean, format?: number, delayAllocation?: boolean);
@@ -20446,6 +20448,11 @@ declare module BABYLON {
          */
         getRenderHeight(): number;
         /**
+         * Gets the actual number of layers of the texture.
+         * @returns the number of layers
+         */
+        getRenderLayers(): number;
+        /**
          * Get if the texture can be rescaled or not.
          */
         get canRescale(): boolean;
@@ -20483,8 +20490,9 @@ declare module BABYLON {
         /**
          * @hidden
          * @param faceIndex face index to bind to if this is a cubetexture
+         * @param layer defines the index of the texture to bind in the array
          */
-        _bindFrameBuffer(faceIndex?: number): void;
+        _bindFrameBuffer(faceIndex?: number, layer?: number): void;
         protected unbindFrameBuffer(engine: Engine, faceIndex: number): void;
         private renderToTarget;
         /**
@@ -30555,6 +30563,7 @@ declare module BABYLON {
         private _settings;
         private _createInternalTextureOnEvent;
         private _frameId;
+        private _currentSrc;
         /**
          * Creates a video texture.
          * If you want to display a video in your scene, this is the special texture for that.
@@ -30593,6 +30602,11 @@ declare module BABYLON {
          */
         updateURL(url: string): void;
         /**
+         * Clones the texture.
+         * @returns the cloned texture
+         */
+        clone(): VideoTexture;
+        /**
          * Dispose the texture and release its associated resources.
          */
         dispose(): void;
@@ -31089,10 +31103,10 @@ declare module BABYLON {
          * @param requiredWidth The width of the target to render to
          * @param requiredHeight The height of the target to render to
          * @param forceFullscreenViewport Forces the viewport to be the entire texture/screen if true
-         * @param depthStencilTexture The depth stencil texture to use to render
-         * @param lodLevel defines le lod level to bind to the frame buffer
+         * @param lodLevel defines the lod level to bind to the frame buffer
+         * @param layer defines the 2d array index to bind to frame buffer to
          */
-        bindFramebuffer(texture: InternalTexture, faceIndex?: number, requiredWidth?: number, requiredHeight?: number, forceFullscreenViewport?: boolean, depthStencilTexture?: InternalTexture, lodLevel?: number): void;
+        bindFramebuffer(texture: InternalTexture, faceIndex?: number, requiredWidth?: number, requiredHeight?: number, forceFullscreenViewport?: boolean, lodLevel?: number, layer?: number): void;
         /** @hidden */
         _bindUnboundFramebuffer(framebuffer: Nullable<WebGLFramebuffer>): void;
         /**
@@ -31614,11 +31628,24 @@ declare module BABYLON {
         _setupDepthStencilTexture(internalTexture: InternalTexture, size: number | {
             width: number;
             height: number;
+            layers?: number;
         }, generateStencil: boolean, bilinearFiltering: boolean, comparisonFunction: number): void;
         /** @hidden */
         _uploadCompressedDataToTextureDirectly(texture: InternalTexture, internalFormat: number, width: number, height: number, data: ArrayBufferView, faceIndex?: number, lod?: number): void;
         /** @hidden */
         _uploadDataToTextureDirectly(texture: InternalTexture, imageData: ArrayBufferView, faceIndex?: number, lod?: number, babylonInternalFormat?: number, useTextureWidthAndHeight?: boolean): void;
+        /**
+         * Update a portion of an internal texture
+         * @param texture defines the texture to update
+         * @param imageData defines the data to store into the texture
+         * @param xOffset defines the x coordinates of the update rectangle
+         * @param yOffset defines the y coordinates of the update rectangle
+         * @param width defines the width of the update rectangle
+         * @param height defines the height of the update rectangle
+         * @param faceIndex defines the face index if texture is a cube (0 by default)
+         * @param lod defines the lod level to update (0 by default)
+         */
+        updateTextureData(texture: InternalTexture, imageData: ArrayBufferView, xOffset: number, yOffset: number, width: number, height: number, faceIndex?: number, lod?: number): void;
         /** @hidden */
         _uploadArrayBufferViewToTexture(texture: InternalTexture, imageData: ArrayBufferView, faceIndex?: number, lod?: number): void;
         protected _prepareWebGLTextureContinuation(texture: InternalTexture, scene: Nullable<ISceneLike>, noMipmap: boolean, isCompressed: boolean, samplingMode: number): void;
@@ -32155,6 +32182,8 @@ declare module BABYLON {
         /** @hidden */
         _lodGenerationOffset: number;
         /** @hidden */
+        _depthStencilTexture: Nullable<InternalTexture>;
+        /** @hidden */
         _colorTextureArray: Nullable<WebGLTexture>;
         /** @hidden */
         _depthStencilTextureArray: Nullable<WebGLTexture>;
@@ -33556,11 +33585,6 @@ declare module BABYLON {
         /** @hidden */
         _uploadImageToTexture(texture: InternalTexture, image: HTMLImageElement | ImageBitmap, faceIndex?: number, lod?: number): void;
         /**
-         * Sets the frame buffer Depth / Stencil attachement of the render target to the defined depth stencil texture.
-         * @param renderTarget The render target to set the frame buffer for
-         */
-        setFrameBufferDepthStencilTexture(renderTarget: RenderTargetTexture): void;
-        /**
          * Update a dynamic index buffer
          * @param indexBuffer defines the target index buffer
          * @param indices defines the data to update
@@ -34544,8 +34568,9 @@ declare module BABYLON {
         * @param attachUp defines if you want to attach events to pointerup
         * @param attachDown defines if you want to attach events to pointerdown
         * @param attachMove defines if you want to attach events to pointermove
+        * @param elementToAttachTo defines the target DOM element to attach to (will use the canvas by default)
         */
-        attachControl(attachUp?: boolean, attachDown?: boolean, attachMove?: boolean): void;
+        attachControl(attachUp?: boolean, attachDown?: boolean, attachMove?: boolean, elementToAttachTo?: Nullable<HTMLElement>): void;
         /**
          * Detaches all event handlers
          */
@@ -43600,9 +43625,10 @@ declare module BABYLON {
          *
          * @param xrInput the xrInput to which a new controller is initialized
          * @param scene the scene to which the model will be added
+         * @param forceProfile force a certain profile for this controller
          * @return the motion controller class for this profile id or the generic standard class if none was found
          */
-        static GetMotionControllerWithXRInput(xrInput: XRInputSource, scene: Scene): WebXRAbstractMotionController;
+        static GetMotionControllerWithXRInput(xrInput: XRInputSource, scene: Scene, forceProfile?: string): WebXRAbstractMotionController;
         /**
          * Find a fallback profile if the profile was not found. There are a few predefined generic profiles.
          * @param profileId the profile to which a fallback needs to be found
@@ -43656,11 +43682,11 @@ declare module BABYLON {
          * @see https://doc.babylonjs.com/how_to/webxr
          * @param scene the scene which the controller should be associated to
          * @param inputSource the underlying input source for the controller
-         * @param parentContainer parent that the controller meshes should be children of
+         * @param controllerProfile An optional controller profile for this input. This will override the xrInput profile.
          */
         constructor(scene: Scene, 
         /** The underlying input source for the controller  */
-        inputSource: XRInputSource);
+        inputSource: XRInputSource, controllerProfile?: string);
         /**
          * Updates the controller pose based on the given XRFrame
          * @param xrFrame xr frame to update the pose with
@@ -43692,6 +43718,12 @@ declare module BABYLON {
          * If set to true no model will be automatically loaded
          */
         doNotLoadControllerMeshes?: boolean;
+        /**
+         * If set, this profile will be used for all controllers loaded (for example "microsoft-mixed-reality")
+         * If not found, the xr input profile data will be used.
+         * Profiles are defined here - https://github.com/immersive-web/webxr-input-profiles/
+         */
+        forceInputProfile?: string;
     }
     /**
      * XR input used to track XR inputs such as controllers/rays
@@ -44831,11 +44863,6 @@ declare module BABYLON {
                     "componentProperty": string;
                     "states": string[];
                 };
-                "menu": {
-                    "rootNodeName": string;
-                    "componentProperty": string;
-                    "states": string[];
-                };
             };
             axes: {
                 "xr-standard-touchpad": {
@@ -46465,7 +46492,6 @@ declare module BABYLON {
          * @param requiredWidth The width of the target to render to
          * @param requiredHeight The height of the target to render to
          * @param forceFullscreenViewport Forces the viewport to be the entire texture/screen if true
-         * @param depthStencilTexture The depth stencil texture to use to render
          * @param lodLevel defines le lod level to bind to the frame buffer
          */
         bindFramebuffer(texture: InternalTexture, faceIndex?: number, requiredWidth?: number, requiredHeight?: number, forceFullscreenViewport?: boolean): void;
@@ -53649,6 +53675,465 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * A CSM implementation allowing casting shadows on large scenes.
+     * Documentation : https://doc.babylonjs.com/babylon101/cascadedShadows
+     * Based on: https://github.com/TheRealMJP/Shadows and https://johanmedestrom.wordpress.com/2016/03/18/opengl-cascaded-shadow-maps/
+     */
+    export class CascadedShadowGenerator implements IShadowGenerator {
+        private static readonly frustumCornersNDCSpace;
+        /**
+         * Defines the default number of cascades used by the CSM.
+         */
+        static readonly DEFAULT_CASCADES_COUNT: number;
+        /**
+         * Defines the minimum number of cascades used by the CSM.
+         */
+        static readonly MIN_CASCADES_COUNT: number;
+        /**
+         * Defines the maximum number of cascades used by the CSM.
+         */
+        static readonly MAX_CASCADES_COUNT: number;
+        /**
+         * Shadow generator mode None: no filtering applied.
+         */
+        static readonly FILTER_NONE: number;
+        /**
+         * Shadow generator mode PCF: Percentage Closer Filtering
+         * benefits from Webgl 2 shadow samplers. Fallback to Poisson Sampling in Webgl 1
+         * (https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch11.html)
+         */
+        static readonly FILTER_PCF: number;
+        /**
+         * Shadow generator mode PCSS: Percentage Closering Soft Shadow.
+         * benefits from Webgl 2 shadow samplers. Fallback to Poisson Sampling in Webgl 1
+         * Contact Hardening
+         */
+        static readonly FILTER_PCSS: number;
+        /**
+         * Reserved for PCF and PCSS
+         * Highest Quality.
+         *
+         * Execute PCF on a 5*5 kernel improving a lot the shadow aliasing artifacts.
+         *
+         * Execute PCSS with 32 taps blocker search and 64 taps PCF.
+         */
+        static readonly QUALITY_HIGH: number;
+        /**
+         * Reserved for PCF and PCSS
+         * Good tradeoff for quality/perf cross devices
+         *
+         * Execute PCF on a 3*3 kernel.
+         *
+         * Execute PCSS with 16 taps blocker search and 32 taps PCF.
+         */
+        static readonly QUALITY_MEDIUM: number;
+        /**
+         * Reserved for PCF and PCSS
+         * The lowest quality but the fastest.
+         *
+         * Execute PCF on a 1*1 kernel.
+         *
+         * Execute PCSS with 16 taps blocker search and 16 taps PCF.
+         */
+        static readonly QUALITY_LOW: number;
+        private static readonly _CLEARONE;
+        /**
+         * Observable triggered before the shadow is rendered. Can be used to update internal effect state
+         */
+        onBeforeShadowMapRenderObservable: Observable<Effect>;
+        /**
+         * Observable triggered after the shadow is rendered. Can be used to restore internal effect state
+         */
+        onAfterShadowMapRenderObservable: Observable<Effect>;
+        /**
+         * Observable triggered before a mesh is rendered in the shadow map.
+         * Can be used to update internal effect state (that you can get from the onBeforeShadowMapRenderObservable)
+         */
+        onBeforeShadowMapRenderMeshObservable: Observable<Mesh>;
+        /**
+         * Observable triggered after a mesh is rendered in the shadow map.
+         * Can be used to update internal effect state (that you can get from the onAfterShadowMapRenderObservable)
+         */
+        onAfterShadowMapRenderMeshObservable: Observable<Mesh>;
+        private _bias;
+        /**
+         * Gets the bias: offset applied on the depth preventing acnea (in light direction).
+         */
+        get bias(): number;
+        /**
+         * Sets the bias: offset applied on the depth preventing acnea (in light direction).
+         */
+        set bias(bias: number);
+        private _normalBias;
+        /**
+         * Gets the normalBias: offset applied on the depth preventing acnea (along side the normal direction and proportinal to the light/normal angle).
+         */
+        get normalBias(): number;
+        /**
+         * Sets the normalBias: offset applied on the depth preventing acnea (along side the normal direction and proportinal to the light/normal angle).
+         */
+        set normalBias(normalBias: number);
+        private _filter;
+        /**
+         * Gets the current mode of the shadow generator (normal, PCF, PCSS...).
+         * The returned value is a number equal to one of the available mode defined in ShadowMap.FILTER_x like _FILTER_NONE
+         */
+        get filter(): number;
+        /**
+         * Sets the current mode of the shadow generator (normal, PCF, PCSS...).
+         * The returned value is a number equal to one of the available mode defined in ShadowMap.FILTER_x like _FILTER_NONE
+         */
+        set filter(value: number);
+        /**
+         * Gets if the current filter is set to "PCF" (percentage closer filtering).
+         */
+        get usePercentageCloserFiltering(): boolean;
+        /**
+         * Sets the current filter to "PCF" (percentage closer filtering).
+         */
+        set usePercentageCloserFiltering(value: boolean);
+        private _filteringQuality;
+        /**
+         * Gets the PCF or PCSS Quality.
+         * Only valid if usePercentageCloserFiltering or usePercentageCloserFiltering is true.
+         */
+        get filteringQuality(): number;
+        /**
+         * Sets the PCF or PCSS Quality.
+         * Only valid if usePercentageCloserFiltering or usePercentageCloserFiltering is true.
+         */
+        set filteringQuality(filteringQuality: number);
+        /**
+         * Gets if the current filter is set to "PCSS" (contact hardening).
+         */
+        get useContactHardeningShadow(): boolean;
+        /**
+         * Sets the current filter to "PCSS" (contact hardening).
+         */
+        set useContactHardeningShadow(value: boolean);
+        private _contactHardeningLightSizeUVRatio;
+        /**
+         * Gets the Light Size (in shadow map uv unit) used in PCSS to determine the blocker search area and the penumbra size.
+         * Using a ratio helps keeping shape stability independently of the map size.
+         *
+         * It does not account for the light projection as it was having too much
+         * instability during the light setup or during light position changes.
+         *
+         * Only valid if useContactHardeningShadow is true.
+         */
+        get contactHardeningLightSizeUVRatio(): number;
+        /**
+         * Sets the Light Size (in shadow map uv unit) used in PCSS to determine the blocker search area and the penumbra size.
+         * Using a ratio helps keeping shape stability independently of the map size.
+         *
+         * It does not account for the light projection as it was having too much
+         * instability during the light setup or during light position changes.
+         *
+         * Only valid if useContactHardeningShadow is true.
+         */
+        set contactHardeningLightSizeUVRatio(contactHardeningLightSizeUVRatio: number);
+        private _darkness;
+        /** Gets or sets the actual darkness of a shadow */
+        get darkness(): number;
+        set darkness(value: number);
+        /**
+         * Returns the darkness value (float). This can only decrease the actual darkness of a shadow.
+         * 0 means strongest and 1 would means no shadow.
+         * @returns the darkness.
+         */
+        getDarkness(): number;
+        /**
+         * Sets the darkness value (float). This can only decrease the actual darkness of a shadow.
+         * @param darkness The darkness value 0 means strongest and 1 would means no shadow.
+         * @returns the shadow generator allowing fluent coding.
+         */
+        setDarkness(darkness: number): CascadedShadowGenerator;
+        /**
+         * Gets or sets the actual darkness of the soft shadows while using PCSS filtering (value between 0. and 1.)
+         */
+        penumbraDarkness: number;
+        private _transparencyShadow;
+        /** Gets or sets the ability to have transparent shadow  */
+        get transparencyShadow(): boolean;
+        set transparencyShadow(value: boolean);
+        /**
+         * Sets the ability to have transparent shadow (boolean).
+         * @param transparent True if transparent else False
+         * @returns the shadow generator allowing fluent coding
+         */
+        setTransparencyShadow(transparent: boolean): CascadedShadowGenerator;
+        private _numCascades;
+        /**
+         * Gets or set the number of cascades used by the CSM.
+         */
+        get numCascades(): number;
+        set numCascades(value: number);
+        /**
+         * Sets this to true if you want that the edges of the shadows don't "swimm" / "shimmer" when rotating the camera.
+         * The trade off is that you loose some precision in the shadow rendering when enabling this setting.
+         */
+        stabilizeCascades: boolean;
+        private _shadowMap;
+        /**
+         * Gets the main RTT containing the shadow map (usually storing depth from the light point of view).
+         * @returns The render target texture if present otherwise, null
+         */
+        getShadowMap(): Nullable<RenderTargetTexture>;
+        protected _freezeShadowCastersBoundingInfo: boolean;
+        private _freezeShadowCastersBoundingInfoObservable;
+        /**
+         * Enables or disables the shadow casters bounding info computation.
+         * If your shadow casters don't move, you can disable this feature.
+         * If it is enabled, the bounding box computation is done every frame.
+         */
+        get freezeShadowCastersBoundingInfo(): boolean;
+        set freezeShadowCastersBoundingInfo(freeze: boolean);
+        private _scbiMin;
+        private _scbiMax;
+        protected _computeShadowCastersBoundingInfo(): void;
+        protected _shadowCastersBoundingInfo: BoundingInfo;
+        /**
+         * Gets or sets the shadow casters bounding info.
+         * If you provide your own shadow casters bounding info, first enable freezeShadowCastersBoundingInfo
+         * so that the system won't overwrite the bounds you provide
+         */
+        get shadowCastersBoundingInfo(): BoundingInfo;
+        set shadowCastersBoundingInfo(boundingInfo: BoundingInfo);
+        protected _breaksAreDirty: boolean;
+        protected _minDistance: number;
+        protected _maxDistance: number;
+        /**
+         * Sets the minimal and maximal distances to use when computing the cascade breaks.
+         *
+         * The values of min / max are typically the depth zmin and zmax values of your scene, for a given frame.
+         * If you don't know these values, simply leave them to their defaults and don't call this function.
+         * @param min minimal distance for the breaks (default to 0.)
+         * @param max maximal distance for the breaks (default to 1.)
+         */
+        setMinMaxDistance(min: number, max: number): void;
+        /**
+         * Gets the class name of that object
+         * @returns "ShadowGenerator"
+         */
+        getClassName(): string;
+        /**
+         * Helper function to add a mesh and its descendants to the list of shadow casters.
+         * @param mesh Mesh to add
+         * @param includeDescendants boolean indicating if the descendants should be added. Default to true
+         * @returns the Shadow Generator itself
+         */
+        addShadowCaster(mesh: AbstractMesh, includeDescendants?: boolean): CascadedShadowGenerator;
+        /**
+         * Helper function to remove a mesh and its descendants from the list of shadow casters
+         * @param mesh Mesh to remove
+         * @param includeDescendants boolean indicating if the descendants should be removed. Default to true
+         * @returns the Shadow Generator itself
+         */
+        removeShadowCaster(mesh: AbstractMesh, includeDescendants?: boolean): CascadedShadowGenerator;
+        /**
+         * Controls the extent to which the shadows fade out at the edge of the frustum
+         */
+        frustumEdgeFalloff: number;
+        private _light;
+        /**
+         * Returns the associated light object.
+         * @returns the light generating the shadow
+         */
+        getLight(): DirectionalLight;
+        /**
+         * If true the shadow map is generated by rendering the back face of the mesh instead of the front face.
+         * This can help with self-shadowing as the geometry making up the back of objects is slightly offset.
+         * It might on the other hand introduce peter panning.
+         */
+        forceBackFacesOnly: boolean;
+        private _cascadeMinExtents;
+        private _cascadeMaxExtents;
+        /**
+         * Gets a cascade minimum extents
+         * @param cascadeIndex index of the cascade
+         * @returns the minimum cascade extents
+         */
+        getCascadeMinExtents(cascadeIndex: number): Nullable<Vector3>;
+        /**
+         * Gets a cascade maximum extents
+         * @param cascadeIndex index of the cascade
+         * @returns the maximum cascade extents
+         */
+        getCascadeMaxExtents(cascadeIndex: number): Nullable<Vector3>;
+        private _scene;
+        private _lightDirection;
+        private _effect;
+        private _cascades;
+        private _cachedPosition;
+        private _cachedDirection;
+        private _cachedDefines;
+        private _currentRenderID;
+        private _mapSize;
+        private _currentLayer;
+        private _textureType;
+        private _defaultTextureMatrix;
+        private _storedUniqueId;
+        private _viewSpaceFrustumsZ;
+        private _viewMatrices;
+        private _projectionMatrices;
+        private _transformMatrices;
+        private _transformMatricesAsArray;
+        private _frustumLengths;
+        private _lightSizeUVCorrection;
+        private _depthCorrection;
+        private _frustumCornersWorldSpace;
+        private _frustumCenter;
+        private _shadowCameraPos;
+        private _shadowMaxZ;
+        /**
+         * Gets the shadow max z distance. It's the limit beyond which shadows are not displayed.
+         * It defaults to camera.maxZ
+         */
+        get shadowMaxZ(): number;
+        /**
+         * Sets the shadow max z distance.
+         */
+        set shadowMaxZ(value: number);
+        protected _debug: boolean;
+        /**
+         * Gets or sets the debug flag.
+         * When enabled, the cascades are materialized by different colors on the screen.
+         */
+        get debug(): boolean;
+        set debug(dbg: boolean);
+        private _depthClamp;
+        /**
+         * Gets or sets the depth clamping value.
+         *
+         * When enabled, it improves the shadow quality because the near z plane of the light frustum don't need to be adjusted
+         * to account for the shadow casters far away.
+         *
+         * Note that this property is incompatible with PCSS filtering, so it won't be used in that case.
+         */
+        get depthClamp(): boolean;
+        set depthClamp(value: boolean);
+        /**
+         * Gets or sets the percentage of blending between two cascades (value between 0. and 1.).
+         * It defaults to 0.1 (10% blending).
+         */
+        cascadeBlendPercentage: number;
+        private _lambda;
+        /**
+         * Gets or set the lambda parameter.
+         * This parameter is used to split the camera frustum and create the cascades.
+         * It's a value between 0. and 1.: If 0, the split is a uniform split of the frustum, if 1 it is a logarithmic split.
+         * For all values in-between, it's a linear combination of the uniform and logarithm split algorithm.
+         */
+        get lambda(): number;
+        set lambda(value: number);
+        /**
+         * Gets the view matrix corresponding to a given cascade
+         * @param cascadeNum cascade to retrieve the view matrix from
+         * @returns the cascade view matrix
+         */
+        getCascadeViewMatrix(cascadeNum: number): Nullable<Matrix>;
+        /**
+         * 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
+         * you change the camera near/far planes!
+         */
+        splitFrustum(): void;
+        private _splitFrustum;
+        /**
+         * Gets the CSM transformation matrix used to project the meshes into the map from the light point of view.
+         * (eq to view projection * shadow projection matrices)
+         * @param cascadeIndex index number of the cascaded shadow map
+         * @returns The transform matrix used to create the CSM shadow map
+         */
+        getCSMTransformMatrix(cascadeIndex: number): Matrix;
+        private _computeFrustumInWorldSpace;
+        private _computeCascadeFrustum;
+        /** @hidden */
+        static _SceneComponentInitialization: (scene: Scene) => void;
+        /**
+         * Creates a Cascaded Shadow Generator object.
+         * A ShadowGenerator is the required tool to use the shadows.
+         * Each directional light casting shadows needs to use its own ShadowGenerator.
+         * Documentation : https://doc.babylonjs.com/babylon101/cascadedShadows
+         * @param mapSize The size of the texture what stores the shadows. Example : 1024.
+         * @param light The directional light object generating the shadows.
+         * @param usefulFloatFirst By default the generator will try to use half float textures but if you need precision (for self shadowing for instance), you can use this option to enforce full float texture.
+         */
+        constructor(mapSize: number, light: DirectionalLight, usefulFloatFirst?: boolean);
+        private _initializeGenerator;
+        private _initializeShadowMap;
+        private _renderForShadowMap;
+        private _renderSubMeshForShadowMap;
+        private _applyFilterValues;
+        /**
+         * Forces all the attached effect to compile to enable rendering only once ready vs. lazyly compiling effects.
+         * @param onCompiled Callback triggered at the and of the effects compilation
+         * @param options Sets of optional options forcing the compilation with different modes
+         */
+        forceCompilation(onCompiled?: (generator: IShadowGenerator) => void, options?: Partial<{
+            useInstances: boolean;
+        }>): void;
+        /**
+         * Forces all the attached effect to compile to enable rendering only once ready vs. lazyly compiling effects.
+         * @param options Sets of optional options forcing the compilation with different modes
+         * @returns A promise that resolves when the compilation completes
+         */
+        forceCompilationAsync(options?: Partial<{
+            useInstances: boolean;
+        }>): Promise<void>;
+        /**
+         * Determine wheter the shadow generator is ready or not (mainly all effects and related post processes needs to be ready).
+         * @param subMesh The submesh we want to render in the shadow map
+         * @param useInstances Defines wether will draw in the map using instances
+         * @returns true if ready otherwise, false
+         */
+        isReady(subMesh: SubMesh, useInstances: boolean): boolean;
+        /**
+         * Prepare all the defines in a material relying on a shadow map at the specified light index.
+         * @param defines Defines of the material we want to update
+         * @param lightIndex Index of the light in the enabled light list of the material
+         */
+        prepareDefines(defines: any, lightIndex: number): void;
+        /**
+         * Binds the shadow related information inside of an effect (information like near, far, darkness...
+         * defined in the generator but impacting the effect).
+         * @param lightIndex Index of the light in the enabled light list of the material owning the effect
+         * @param effect The effect we are binfing the information for
+         */
+        bindShadowLight(lightIndex: string, effect: Effect): void;
+        /**
+         * Gets the transformation matrix of the first cascade used to project the meshes into the map from the light point of view.
+         * (eq to view projection * shadow projection matrices)
+         * @returns The transform matrix used to create the shadow map
+         */
+        getTransformMatrix(): Matrix;
+        /**
+         * Recreates the shadow map dependencies like RTT and post processes. This can be used during the switch between
+         * Cube and 2D textures for instance.
+         */
+        recreateShadowMap(): void;
+        private _disposeRTT;
+        /**
+         * Disposes the ShadowGenerator.
+         * Returns nothing.
+         */
+        dispose(): void;
+        /**
+         * Serializes the shadow generator setup to a json object.
+         * @returns The serialized JSON object
+         */
+        serialize(): any;
+        /**
+         * Parses a serialized ShadowGenerator and returns a new ShadowGenerator.
+         * @param parsedShadowGenerator The JSON object to parse
+         * @param scene The scene to create the shadow map for
+         * @returns The parsed shadow generator
+         */
+        static Parse(parsedShadowGenerator: any, scene: Scene): CascadedShadowGenerator;
+    }
+}
+declare module BABYLON {
+    /**
      * Defines the shadow generator component responsible to manage any shadow generators
      * in a given scene.
      */
@@ -67843,11 +68328,14 @@ interface WebGLRenderingContext {
     readonly UNSIGNED_INT_10F_11F_11F_REV: number;
     readonly UNSIGNED_INT_5_9_9_9_REV: number;
     readonly FLOAT_32_UNSIGNED_INT_24_8_REV: number;
+    readonly DEPTH_COMPONENT32F: number;
 
     texImage3D(target: number, level: number, internalformat: number, width: number, height: number, depth: number, border: number, format: number, type: number, pixels: ArrayBufferView | null): void;
     texImage3D(target: number, level: number, internalformat: number, width: number, height: number, depth: number, border: number, format: number, type: number, pixels: ArrayBufferView, offset: number): void;
     texImage3D(target: number, level: number, internalformat: number, width: number, height: number, depth: number, border: number, format: number, type: number, pixels: ImageBitmap | ImageData | HTMLVideoElement | HTMLImageElement | HTMLCanvasElement): void;
 
+    framebufferTextureLayer(target: number, attachment: number, texture: WebGLTexture | null, level: number, layer: number): void;
+
     compressedTexImage3D(target: number, level: number, internalformat: number, width: number, height: number, depth: number, border: number, data: ArrayBufferView, offset?: number, length?: number): void;
 
     readonly TRANSFORM_FEEDBACK: number;

+ 3 - 3
dist/preview release/gui/babylon.gui.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 8 - 8
dist/preview release/inspector/babylon.inspector.bundle.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1641 - 444
dist/preview release/inspector/babylon.inspector.bundle.max.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.max.js.map


+ 3 - 3
dist/preview release/loaders/babylon.glTF1FileLoader.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

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

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.cellMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.customMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/materialsLibrary/babylon.customMaterial.min.js


+ 3 - 3
dist/preview release/materialsLibrary/babylon.fireMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.furMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.gradientMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.gridMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.lavaMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.mixMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.normalMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.simpleMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.skyMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.terrainMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylon.waterMaterial.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/materialsLibrary/babylonjs.materials.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/materialsLibrary/babylonjs.materials.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 6 - 6
dist/preview release/nodeEditor/babylon.nodeEditor.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 2465 - 1269
dist/preview release/nodeEditor/babylon.nodeEditor.max.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map


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

@@ -1 +1 @@
-{"thinEngineOnly":111633,"engineOnly":148478,"sceneOnly":502401,"minGridMaterial":632827,"minStandardMaterial":757366}
+{"thinEngineOnly":112287,"engineOnly":148378,"sceneOnly":502161,"minGridMaterial":632857,"minStandardMaterial":773268}

+ 3 - 3
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/postProcessesLibrary/babylon.oceanPostProcess.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/postProcessesLibrary/babylonjs.postProcess.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.brickProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.cloudProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.fireProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.grassProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.marbleProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.normalMapProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.perlinNoiseProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.roadProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.starfieldProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylon.woodProceduralTexture.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/serializers/babylon.glTF2Serializer.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 3 - 3
dist/preview release/serializers/babylonjs.serializers.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!*****************************************************************!*\
-  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \*****************************************************************/
+/*!***********************************************************!*\
+  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \***********************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1045 - 56
dist/preview release/viewer/babylon.module.d.ts


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 128 - 124
dist/preview release/viewer/babylon.viewer.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 3 - 3
dist/preview release/viewer/babylon.viewer.max.js


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

@@ -16,6 +16,7 @@
 - Added support for Offscreen canvas [Doc](https://doc.babylonjs.com/how_to/using_offscreen_canvas) ([Deltakosh](https://github.com/deltakosh/)
 - Added support for multiple canvases with one engine [Doc](https://doc.babylonjs.com/how_to/multi_canvases) ([Deltakosh](https://github.com/deltakosh/)
 - Added useReverseDepthBuffer to Engine which can provide greater z depth for distant objects without the cost of a logarithmic depth buffer ([BenAdams](https://github.com/benaadams/))
+- Added the "Cascaded Shadow Mapping" (CSM) shadow rendering technic ([Popov72](https://github.com/Popov72) (initiated by [lockphase](https://github.com/lockphase/)))
 
 ## Updates
 
@@ -182,7 +183,8 @@
 - New Features Manager for WebXR features ([RaananW](https://github.com/RaananW/))
 - New features - Plane detection, Hit Test, Background remover ([RaananW](https://github.com/RaananW/))
 - Camera's API is Babylon-conform (position, rotationQuaternion, world matrix, direction etc') ([#7239](https://github.com/BabylonJS/Babylon.js/issues/7239)) ([RaananW](https://github.com/RaananW/))
-- XR Input now using standard profiles and completely separated from the gamepad class ([#7348](https://github.com/BabylonJS/Babylon.js/issues/7348)) ([RaananW](https://github.com/RaananW/))
+- XR Input now using standard profiles and completely separated from the babylon gamepad class ([#7348](https://github.com/BabylonJS/Babylon.js/issues/7348)) ([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/))
 
 ### Ray
 

+ 3 - 10
src/Cameras/XR/motionController/webXRMicrosoftMixedRealityController.ts

@@ -20,8 +20,7 @@ const MixedRealityProfile: IMotionControllerLayoutMap = {
             "xr-standard-trigger": { "type": "trigger" },
             "xr-standard-squeeze": { "type": "squeeze" },
             "xr-standard-touchpad": { "type": "touchpad" },
-            "xr-standard-thumbstick": { "type": "thumbstick" },
-            "menu": { "type": "button" }
+            "xr-standard-thumbstick": { "type": "thumbstick" }
         },
         "gamepad": {
             "mapping": "xr-standard",
@@ -29,8 +28,7 @@ const MixedRealityProfile: IMotionControllerLayoutMap = {
                 "xr-standard-trigger",
                 "xr-standard-squeeze",
                 "xr-standard-touchpad",
-                "xr-standard-thumbstick",
-                "menu"
+                "xr-standard-thumbstick"
             ],
             "axes": [
                 { "componentId": "xr-standard-touchpad", "axis": "x-axis" },
@@ -93,11 +91,6 @@ export class WebXRMicrosoftMixedRealityController extends WebXRAbstractMotionCon
                 "rootNodeName": "THUMBSTICK_PRESS",
                 "componentProperty": "state",
                 "states": ["pressed"],
-            },
-            "menu": {
-                "rootNodeName": "MENU",
-                "componentProperty": "state",
-                "states": ["pressed"]
             }
         },
         axes: {
@@ -259,6 +252,6 @@ export class WebXRMicrosoftMixedRealityController extends WebXRAbstractMotionCon
 }
 
 // register the profile
-WebXRMotionControllerManager.RegisterController("microsoft-mixed-reality", (xrInput: XRInputSource, scene: Scene) => {
+WebXRMotionControllerManager.RegisterController("windows-mixed-reality", (xrInput: XRInputSource, scene: Scene) => {
     return new WebXRMicrosoftMixedRealityController(scene, <any>(xrInput.gamepad), xrInput.handedness);
 });

+ 13 - 3
src/Cameras/XR/motionController/webXRMotionControllerManager.ts

@@ -44,9 +44,18 @@ export class WebXRMotionControllerManager {
      *
      * @param xrInput the xrInput to which a new controller is initialized
      * @param scene the scene to which the model will be added
+     * @param forceProfile force a certain profile for this controller
      * @return the motion controller class for this profile id or the generic standard class if none was found
      */
-    public static GetMotionControllerWithXRInput(xrInput: XRInputSource, scene: Scene): WebXRAbstractMotionController {
+    public static GetMotionControllerWithXRInput(xrInput: XRInputSource, scene: Scene, forceProfile?: string): WebXRAbstractMotionController {
+        //if a type was forced, try creating a controller using it. Continue if not found.
+        if (forceProfile) {
+            const constructionFunction = this._AvailableControllers[forceProfile];
+            if (constructionFunction) {
+                return constructionFunction(xrInput, scene);
+            }
+        }
+
         for (let i = 0; i < xrInput.profiles.length; ++i) {
             const constructionFunction = this._AvailableControllers[xrInput.profiles[i]];
             if (constructionFunction) {
@@ -112,11 +121,12 @@ export class WebXRMotionControllerManager {
         this.RegisterFallbacksForProfileId("htc-vive-focus", ["generic-trigger-touchpad"]);
         this.RegisterFallbacksForProfileId("htc-vive", ["generic-trigger-squeeze-touchpad"]);
         this.RegisterFallbacksForProfileId("magicleap-one", ["generic-trigger-squeeze-touchpad"]);
-        this.RegisterFallbacksForProfileId("microsoft-mixed-reality", ["generic-trigger-squeeze-touchpad-thumbstick"]);
+        this.RegisterFallbacksForProfileId("windows-mixed-reality", ["generic-trigger-squeeze-touchpad-thumbstick"]);
+        this.RegisterFallbacksForProfileId("microsoft-mixed-reality", ["windows-mixed-reality", "generic-trigger-squeeze-touchpad-thumbstick"]);
         this.RegisterFallbacksForProfileId("oculus-go", ["generic-trigger-touchpad"]);
         this.RegisterFallbacksForProfileId("oculus-touch-v2", ["oculus-touch", "generic-trigger-squeeze-thumbstick"]);
         this.RegisterFallbacksForProfileId("oculus-touch", ["generic-trigger-squeeze-thumbstick"]);
-        this.RegisterFallbacksForProfileId("samsung-gearvr", ["microsoft-mixed-reality", "generic-trigger-squeeze-touchpad-thumbstick"]);
+        this.RegisterFallbacksForProfileId("samsung-gearvr", ["windows-mixed-reality", "generic-trigger-squeeze-touchpad-thumbstick"]);
         this.RegisterFallbacksForProfileId("samsung-odyssey", ["generic-touchpad"]);
         this.RegisterFallbacksForProfileId("valve-index", ["generic-trigger-squeeze-touchpad-thumbstick"]);
     }

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

@@ -39,12 +39,13 @@ export class WebXRController {
      * @see https://doc.babylonjs.com/how_to/webxr
      * @param scene the scene which the controller should be associated to
      * @param inputSource the underlying input source for the controller
-     * @param parentContainer parent that the controller meshes should be children of
+     * @param controllerProfile An optional controller profile for this input. This will override the xrInput profile.
      */
     constructor(
         private scene: Scene,
         /** The underlying input source for the controller  */
-        public inputSource: XRInputSource) {
+        public inputSource: XRInputSource,
+        controllerProfile?: string) {
         this.pointer = new AbstractMesh("controllerPointer", scene);
         this.pointer.rotationQuaternion = new Quaternion();
 
@@ -55,7 +56,7 @@ export class WebXRController {
 
         // for now only load motion controllers if gamepad available
         if (this.inputSource.gamepad) {
-            this.gamepadController = WebXRMotionControllerManager.GetMotionControllerWithXRInput(inputSource, scene);
+            this.gamepadController = WebXRMotionControllerManager.GetMotionControllerWithXRInput(inputSource, scene, controllerProfile);
             // if the model is loaded, do your thing
             this.gamepadController.onModelLoadedObservable.addOnce(() => {
                 this.gamepadController!.rootMesh!.parent = this.pointer;

+ 8 - 1
src/Cameras/XR/webXRInput.ts

@@ -13,6 +13,13 @@ export interface IWebXRInputOptions {
      * If set to true no model will be automatically loaded
      */
     doNotLoadControllerMeshes?: boolean;
+
+    /**
+     * If set, this profile will be used for all controllers loaded (for example "microsoft-mixed-reality")
+     * If not found, the xr input profile data will be used.
+     * Profiles are defined here - https://github.com/immersive-web/webxr-input-profiles/
+     */
+    forceInputProfile?: string;
 }
 /**
  * XR input used to track XR inputs such as controllers/rays
@@ -77,7 +84,7 @@ export class WebXRInput implements IDisposable {
         let sources = this.controllers.map((c) => { return c.inputSource; });
         for (let input of addInputs) {
             if (sources.indexOf(input) === -1) {
-                let controller = new WebXRController(this.xrSessionManager.scene, input);
+                let controller = new WebXRController(this.xrSessionManager.scene, input, this.options.forceInputProfile);
                 this.controllers.push(controller);
                 if (!this.options.doNotLoadControllerMeshes && controller.gamepadController) {
                     controller.gamepadController.loadModel();

+ 0 - 1
src/Engines/Extensions/engine.multiRender.ts

@@ -243,7 +243,6 @@ ThinEngine.prototype.createMultipleRenderTarget = function(size: any, options: I
     }
 
     gl.drawBuffers(attachments);
-    gl.bindRenderbuffer(gl.RENDERBUFFER, null);
     this._bindUnboundFramebuffer(null);
 
     this.resetTextureCache();

+ 61 - 53
src/Engines/Extensions/engine.renderTarget.ts

@@ -13,7 +13,7 @@ declare module "../../Engines/thinEngine" {
          * @param options defines the options used to create the texture
          * @returns a new render target texture stored in an InternalTexture
          */
-        createRenderTargetTexture(size: number | { width: number, height: number }, options: boolean | RenderTargetCreationOptions): InternalTexture;
+        createRenderTargetTexture(size: number | { width: number, height: number, layers?: number }, options: boolean | RenderTargetCreationOptions): InternalTexture;
 
         /**
          * Creates a depth stencil texture.
@@ -22,16 +22,15 @@ declare module "../../Engines/thinEngine" {
          * @param options The options defining the texture.
          * @returns The texture
          */
-        createDepthStencilTexture(size: number | { width: number, height: number }, options: DepthTextureCreationOptions): InternalTexture;
+        createDepthStencilTexture(size: number | { width: number, height: number, layers?: number }, options: DepthTextureCreationOptions): InternalTexture;
 
         /** @hidden */
-        _createDepthStencilTexture(size: number | { width: number, height: number }, options: DepthTextureCreationOptions): InternalTexture;
+        _createDepthStencilTexture(size: number | { width: number, height: number, layers?: number }, options: DepthTextureCreationOptions): InternalTexture;
     }
 }
 
-ThinEngine.prototype.createRenderTargetTexture = function(this: ThinEngine, size: number | { width: number, height: number }, options: boolean | RenderTargetCreationOptions): InternalTexture {
-    let fullOptions = new RenderTargetCreationOptions();
-
+ThinEngine.prototype.createRenderTargetTexture = function(this: ThinEngine, size: number | { width: number, height: number, layers?: number }, options: boolean | RenderTargetCreationOptions): InternalTexture {
+    const fullOptions = new RenderTargetCreationOptions();
     if (options !== undefined && typeof options === "object") {
         fullOptions.generateMipMaps = options.generateMipMaps;
         fullOptions.generateDepthBuffer = !!options.generateDepthBuffer;
@@ -56,50 +55,63 @@ ThinEngine.prototype.createRenderTargetTexture = function(this: ThinEngine, size
         // if floating point linear (HALF_FLOAT) then force to NEAREST_SAMPLINGMODE
         fullOptions.samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;
     }
-    var gl = this._gl;
-
-    var texture = new InternalTexture(this, InternalTextureSource.RenderTarget);
-    this._bindTextureDirectly(gl.TEXTURE_2D, texture, true);
-
-    var width = (<{ width: number, height: number }>size).width || <number>size;
-    var height = (<{ width: number, height: number }>size).height || <number>size;
-
-    var filters = this._getSamplingParameters(fullOptions.samplingMode, fullOptions.generateMipMaps ? true : false);
-
     if (fullOptions.type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloat) {
         fullOptions.type = Constants.TEXTURETYPE_UNSIGNED_INT;
         Logger.Warn("Float textures are not supported. Render target forced to TEXTURETYPE_UNSIGNED_BYTE type");
     }
 
-    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filters.mag);
-    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filters.min);
-    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
-    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+    const gl = this._gl;
+    const texture = new InternalTexture(this, InternalTextureSource.RenderTarget);
+    const width = (<{ width: number, height: number, layers?: number }>size).width || <number>size;
+    const height = (<{ width: number, height: number, layers?: number }>size).height || <number>size;
+    const layers = (<{ width: number, height: number, layers?: number }>size).layers || 0;
+    const filters = this._getSamplingParameters(fullOptions.samplingMode, fullOptions.generateMipMaps ? true : false);
+    const target = layers !== 0 ? gl.TEXTURE_2D_ARRAY : gl.TEXTURE_2D;
+    const sizedFormat = this._getRGBABufferInternalSizedFormat(fullOptions.type, fullOptions.format);
+    const internalFormat = this._getInternalFormat(fullOptions.format);
+    const type = this._getWebGLTextureType(fullOptions.type);
+
+    // Bind
+    this._bindTextureDirectly(target, texture);
+
+    if (layers !== 0) {
+        texture.is2DArray = true;
+        gl.texImage3D(target, 0, sizedFormat, width, height, layers, 0, internalFormat, type, null);
+    }
+    else {
+        gl.texImage2D(target, 0, sizedFormat, width, height, 0, internalFormat, type, null);
+    }
+
+    gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, filters.mag);
+    gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, filters.min);
+    gl.texParameteri(target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+    gl.texParameteri(target, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
 
-    gl.texImage2D(gl.TEXTURE_2D, 0, this._getRGBABufferInternalSizedFormat(fullOptions.type, fullOptions.format), width, height, 0, this._getInternalFormat(fullOptions.format), this._getWebGLTextureType(fullOptions.type), null);
+    // MipMaps
+    if (fullOptions.generateMipMaps) {
+        this._gl.generateMipmap(target);
+    }
+
+    this._bindTextureDirectly(target, null);
 
     // Create the framebuffer
-    var currentFrameBuffer = this._currentFramebuffer;
-    var framebuffer = gl.createFramebuffer();
+    const framebuffer = gl.createFramebuffer();
     this._bindUnboundFramebuffer(framebuffer);
-    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture._webGLTexture, 0);
-
     texture._depthStencilBuffer = this._setupFramebufferDepthAttachments(fullOptions.generateStencilBuffer ? true : false, fullOptions.generateDepthBuffer, width, height);
 
-    if (fullOptions.generateMipMaps) {
-        this._gl.generateMipmap(this._gl.TEXTURE_2D);
+    // No need to rebind on every frame
+    if (!texture.is2DArray) {
+        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture._webGLTexture, 0);
     }
 
-    // Unbind
-    this._bindTextureDirectly(gl.TEXTURE_2D, null);
-    gl.bindRenderbuffer(gl.RENDERBUFFER, null);
-    this._bindUnboundFramebuffer(currentFrameBuffer);
+    this._bindUnboundFramebuffer(null);
 
     texture._framebuffer = framebuffer;
     texture.baseWidth = width;
     texture.baseHeight = height;
     texture.width = width;
     texture.height = height;
+    texture.depth = layers;
     texture.isReady = true;
     texture.samples = 1;
     texture.generateMipMaps = fullOptions.generateMipMaps ? true : false;
@@ -109,14 +121,12 @@ ThinEngine.prototype.createRenderTargetTexture = function(this: ThinEngine, size
     texture._generateDepthBuffer = fullOptions.generateDepthBuffer;
     texture._generateStencilBuffer = fullOptions.generateStencilBuffer ? true : false;
 
-    // this.resetTextureCache();
-
     this._internalTexturesCache.push(texture);
 
     return texture;
 };
 
-ThinEngine.prototype.createDepthStencilTexture = function(size: number | { width: number, height: number }, options: DepthTextureCreationOptions): InternalTexture {
+ThinEngine.prototype.createDepthStencilTexture = function(size: number | { width: number, height: number, layers?: number }, options: DepthTextureCreationOptions): InternalTexture {
     if (options.isCube) {
         let width = (<{ width: number, height: number }>size).width || <number>size;
         return this._createDepthStencilCubeTexture(width, options);
@@ -126,44 +136,42 @@ ThinEngine.prototype.createDepthStencilTexture = function(size: number | { width
     }
 };
 
-ThinEngine.prototype._createDepthStencilTexture = function(size: number | { width: number, height: number }, options: DepthTextureCreationOptions): InternalTexture {
-    var internalTexture = new InternalTexture(this, InternalTextureSource.Depth);
-
+ThinEngine.prototype._createDepthStencilTexture = function(size: number | { width: number, height: number, layers?: number }, options: DepthTextureCreationOptions): InternalTexture {
+    const gl = this._gl;
+    const layers = (<{ width: number, height: number, layers?: number }>size).layers || 0;
+    const target = layers !== 0 ? gl.TEXTURE_2D_ARRAY : gl.TEXTURE_2D;
+    const internalTexture = new InternalTexture(this, InternalTextureSource.Depth);
     if (!this._caps.depthTextureExtension) {
         Logger.Error("Depth texture is not supported by your browser or hardware.");
         return internalTexture;
     }
 
-    var internalOptions = {
+    const internalOptions = {
         bilinearFiltering: false,
         comparisonFunction: 0,
         generateStencil: false,
         ...options
     };
 
-    var gl = this._gl;
-    this._bindTextureDirectly(gl.TEXTURE_2D, internalTexture, true);
+    this._bindTextureDirectly(target, internalTexture, true);
 
     this._setupDepthStencilTexture(internalTexture, size, internalOptions.generateStencil, internalOptions.bilinearFiltering, internalOptions.comparisonFunction);
 
+    const type = internalOptions.generateStencil ? gl.UNSIGNED_INT_24_8 : gl.UNSIGNED_INT;
+    const internalFormat = internalOptions.generateStencil ? gl.DEPTH_STENCIL : gl.DEPTH_COMPONENT;
+    let sizedFormat = internalFormat;
     if (this.webGLVersion > 1) {
-        if (internalOptions.generateStencil) {
-            gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH24_STENCIL8, internalTexture.width, internalTexture.height, 0, gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8, null);
-        }
-        else {
-            gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT24, internalTexture.width, internalTexture.height, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, null);
-        }
+        sizedFormat = internalOptions.generateStencil ? gl.DEPTH24_STENCIL8 : gl.DEPTH_COMPONENT24;
+    }
+
+    if (internalTexture.is2DArray) {
+        gl.texImage3D(target, 0, sizedFormat, internalTexture.width, internalTexture.height, layers, 0, internalFormat, type, null);
     }
     else {
-        if (internalOptions.generateStencil) {
-            gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_STENCIL, internalTexture.width, internalTexture.height, 0, gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8, null);
-        }
-        else {
-            gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, internalTexture.width, internalTexture.height, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, null);
-        }
+        gl.texImage2D(target, 0, sizedFormat, internalTexture.width, internalTexture.height, 0, internalFormat, type, null);
     }
 
-    this._bindTextureDirectly(gl.TEXTURE_2D, null);
+    this._bindTextureDirectly(target, null);
 
     return internalTexture;
 };

+ 0 - 1
src/Engines/Extensions/engine.renderTargetCube.ts

@@ -70,7 +70,6 @@ ThinEngine.prototype.createRenderTargetCubeTexture = function(size: number, opti
 
     // Unbind
     this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
-    gl.bindRenderbuffer(gl.RENDERBUFFER, null);
     this._bindUnboundFramebuffer(null);
 
     texture._framebuffer = framebuffer;

+ 0 - 35
src/Engines/engine.ts

@@ -1650,40 +1650,6 @@ export class Engine extends ThinEngine {
     }
 
     /**
-     * Sets the frame buffer Depth / Stencil attachement of the render target to the defined depth stencil texture.
-     * @param renderTarget The render target to set the frame buffer for
-     */
-    public setFrameBufferDepthStencilTexture(renderTarget: RenderTargetTexture): void {
-        // Create the framebuffer
-        var internalTexture = renderTarget.getInternalTexture();
-        if (!internalTexture || !internalTexture._framebuffer || !renderTarget.depthStencilTexture) {
-            return;
-        }
-
-        var gl = this._gl;
-        var depthStencilTexture = renderTarget.depthStencilTexture;
-
-        this._bindUnboundFramebuffer(internalTexture._framebuffer);
-        if (depthStencilTexture.isCube) {
-            if (depthStencilTexture._generateStencilBuffer) {
-                gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.TEXTURE_CUBE_MAP_POSITIVE_X, depthStencilTexture._webGLTexture, 0);
-            }
-            else {
-                gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_CUBE_MAP_POSITIVE_X, depthStencilTexture._webGLTexture, 0);
-            }
-        }
-        else {
-            if (depthStencilTexture._generateStencilBuffer) {
-                gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.TEXTURE_2D, depthStencilTexture._webGLTexture, 0);
-            }
-            else {
-                gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthStencilTexture._webGLTexture, 0);
-            }
-        }
-        this._bindUnboundFramebuffer(null);
-    }
-
-    /**
      * Update a dynamic index buffer
      * @param indexBuffer defines the target index buffer
      * @param indices defines the data to update
@@ -1771,7 +1737,6 @@ export class Engine extends ThinEngine {
         texture.samples = samples;
         texture._depthStencilBuffer = this._setupFramebufferDepthAttachments(texture._generateStencilBuffer, texture._generateDepthBuffer, texture.width, texture.height, samples);
 
-        gl.bindRenderbuffer(gl.RENDERBUFFER, null);
         this._bindUnboundFramebuffer(null);
 
         return samples;

+ 0 - 1
src/Engines/nullEngine.ts

@@ -647,7 +647,6 @@ export class NullEngine extends Engine {
      * @param requiredWidth The width of the target to render to
      * @param requiredHeight The height of the target to render to
      * @param forceFullscreenViewport Forces the viewport to be the entire texture/screen if true
-     * @param depthStencilTexture The depth stencil texture to use to render
      * @param lodLevel defines le lod level to bind to the frame buffer
      */
     public bindFramebuffer(texture: InternalTexture, faceIndex?: number, requiredWidth?: number, requiredHeight?: number, forceFullscreenViewport?: boolean): void {

+ 62 - 23
src/Engines/thinEngine.ts

@@ -1344,29 +1344,35 @@ export class ThinEngine {
      * @param requiredWidth The width of the target to render to
      * @param requiredHeight The height of the target to render to
      * @param forceFullscreenViewport Forces the viewport to be the entire texture/screen if true
-     * @param depthStencilTexture The depth stencil texture to use to render
-     * @param lodLevel defines le lod level to bind to the frame buffer
+     * @param lodLevel defines the lod level to bind to the frame buffer
+     * @param layer defines the 2d array index to bind to frame buffer to
      */
-    public bindFramebuffer(texture: InternalTexture, faceIndex?: number, requiredWidth?: number, requiredHeight?: number, forceFullscreenViewport?: boolean, depthStencilTexture?: InternalTexture, lodLevel = 0): void {
+    public bindFramebuffer(texture: InternalTexture, faceIndex: number = 0, requiredWidth?: number, requiredHeight?: number, forceFullscreenViewport?: boolean, lodLevel = 0, layer = 0): void {
         if (this._currentRenderTarget) {
             this.unBindFramebuffer(this._currentRenderTarget);
         }
         this._currentRenderTarget = texture;
         this._bindUnboundFramebuffer(texture._MSAAFramebuffer ? texture._MSAAFramebuffer : texture._framebuffer);
-        var gl = this._gl;
-        if (texture.isCube) {
-            if (faceIndex === undefined) {
-                faceIndex = 0;
-            }
+
+        const gl = this._gl;
+        if (texture.is2DArray) {
+            gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture._webGLTexture, lodLevel, layer);
+        }
+        else if (texture.isCube) {
             gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, texture._webGLTexture, lodLevel);
+        }
 
-            if (depthStencilTexture) {
-                if (depthStencilTexture._generateStencilBuffer) {
-                    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, depthStencilTexture._webGLTexture, lodLevel);
-                }
-                else {
-                    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, depthStencilTexture._webGLTexture, lodLevel);
-                }
+        const depthStencilTexture = texture._depthStencilTexture;
+        if (depthStencilTexture) {
+            const attachment = (depthStencilTexture._generateStencilBuffer) ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT;
+            if (texture.is2DArray) {
+                gl.framebufferTextureLayer(gl.FRAMEBUFFER, attachment, depthStencilTexture._webGLTexture, lodLevel, layer);
+            }
+            else if (texture.isCube) {
+                gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, depthStencilTexture._webGLTexture, lodLevel);
+            }
+            else {
+                gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, depthStencilTexture._webGLTexture, lodLevel);
             }
         }
 
@@ -3199,13 +3205,17 @@ export class ThinEngine {
     }
 
     /** @hidden */
-    public _setupDepthStencilTexture(internalTexture: InternalTexture, size: number | { width: number, height: number }, generateStencil: boolean, bilinearFiltering: boolean, comparisonFunction: number): void {
-        var width = (<{ width: number, height: number }>size).width || <number>size;
-        var height = (<{ width: number, height: number }>size).height || <number>size;
+    public _setupDepthStencilTexture(internalTexture: InternalTexture, size: number | { width: number, height: number, layers?: number }, generateStencil: boolean, bilinearFiltering: boolean, comparisonFunction: number): void {
+        const width = (<{ width: number, height: number, layers?: number }>size).width || <number>size;
+        const height = (<{ width: number, height: number, layers?: number }>size).height || <number>size;
+        const layers = (<{ width: number, height: number, layers?: number }>size).layers || 0;
+
         internalTexture.baseWidth = width;
         internalTexture.baseHeight = height;
         internalTexture.width = width;
         internalTexture.height = height;
+        internalTexture.is2DArray = layers > 0;
+        internalTexture.depth = layers;
         internalTexture.isReady = true;
         internalTexture.samples = 1;
         internalTexture.generateMipMaps = false;
@@ -3215,9 +3225,9 @@ export class ThinEngine {
         internalTexture.type = Constants.TEXTURETYPE_UNSIGNED_INT;
         internalTexture._comparisonFunction = comparisonFunction;
 
-        var gl = this._gl;
-        var target = internalTexture.isCube ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D;
-        var samplingParameters = this._getSamplingParameters(internalTexture.samplingMode, false);
+        const gl = this._gl;
+        const target = this._getTextureTarget(internalTexture);
+        const samplingParameters = this._getSamplingParameters(internalTexture.samplingMode, false);
         gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, samplingParameters.mag);
         gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, samplingParameters.min);
         gl.texParameteri(target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
@@ -3268,6 +3278,33 @@ export class ThinEngine {
         gl.texImage2D(target, lod, internalFormat, width, height, 0, format, textureType, imageData);
     }
 
+    /**
+     * Update a portion of an internal texture
+     * @param texture defines the texture to update
+     * @param imageData defines the data to store into the texture
+     * @param xOffset defines the x coordinates of the update rectangle
+     * @param yOffset defines the y coordinates of the update rectangle
+     * @param width defines the width of the update rectangle
+     * @param height defines the height of the update rectangle
+     * @param faceIndex defines the face index if texture is a cube (0 by default)
+     * @param lod defines the lod level to update (0 by default)
+     */
+    public updateTextureData(texture: InternalTexture, imageData: ArrayBufferView, xOffset: number, yOffset: number, width: number, height: number, faceIndex: number = 0, lod: number = 0): void {
+        var gl = this._gl;
+
+        var textureType = this._getWebGLTextureType(texture.type);
+        var format = this._getInternalFormat(texture.format);
+
+        this._unpackFlipY(texture.invertY);
+
+        var target = gl.TEXTURE_2D;
+        if (texture.isCube) {
+            target = gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex;
+        }
+
+        gl.texSubImage2D(target, lod, xOffset, yOffset, width, height, format, textureType, imageData);
+    }
+
     /** @hidden */
     public _uploadArrayBufferViewToTexture(texture: InternalTexture, imageData: ArrayBufferView, faceIndex: number = 0, lod: number = 0): void {
         var gl = this._gl;
@@ -3354,10 +3391,9 @@ export class ThinEngine {
             return this._getDepthStencilBuffer(width, height, samples, gl.DEPTH_STENCIL, gl.DEPTH24_STENCIL8, gl.DEPTH_STENCIL_ATTACHMENT);
         }
         if (generateDepthBuffer) {
-            let anyGl = <any>gl;
             let depthFormat = gl.DEPTH_COMPONENT16;
             if (this._webGLVersion > 1) {
-                depthFormat = anyGl.DEPTH_COMPONENT32F;
+                depthFormat = gl.DEPTH_COMPONENT32F;
             }
 
             return this._getDepthStencilBuffer(width, height, samples, depthFormat, depthFormat, gl.DEPTH_ATTACHMENT);
@@ -3382,6 +3418,9 @@ export class ThinEngine {
         }
 
         gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, depthStencilBuffer);
+
+        gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+
         return depthStencilBuffer;
     }
 

+ 21 - 17
src/Inputs/scene.inputManager.ts

@@ -444,12 +444,16 @@ export class InputManager {
     * @param attachUp defines if you want to attach events to pointerup
     * @param attachDown defines if you want to attach events to pointerdown
     * @param attachMove defines if you want to attach events to pointermove
+    * @param elementToAttachTo defines the target DOM element to attach to (will use the canvas by default)
     */
-    public attachControl(attachUp = true, attachDown = true, attachMove = true): void {
+    public attachControl(attachUp = true, attachDown = true, attachMove = true, elementToAttachTo: Nullable<HTMLElement> = null): void {
         let scene = this._scene;
-        var canvas = scene.getEngine().getInputElement();
 
-        if (!canvas) {
+        if (!elementToAttachTo) {
+            elementToAttachTo = scene.getEngine().getInputElement();
+        }
+
+        if (!elementToAttachTo) {
             return;
         }
 
@@ -625,9 +629,9 @@ export class InputManager {
 
             this._updatePointerPosition(evt);
 
-            if (scene.preventDefaultOnPointerDown && canvas) {
+            if (scene.preventDefaultOnPointerDown && elementToAttachTo) {
                 evt.preventDefault();
-                canvas.focus();
+                elementToAttachTo.focus();
             }
 
             this._startingPointerPosition.x = this._pointerX;
@@ -669,9 +673,9 @@ export class InputManager {
 
             this._updatePointerPosition(evt);
 
-            if (scene.preventDefaultOnPointerUp && canvas) {
+            if (scene.preventDefaultOnPointerUp && elementToAttachTo) {
                 evt.preventDefault();
-                canvas.focus();
+                elementToAttachTo.focus();
             }
 
             this._initClickEvent(scene.onPrePointerObservable, scene.onPointerObservable, evt, (clickInfo: _ClickInfo, pickResult: Nullable<PickingInfo>) => {
@@ -768,42 +772,42 @@ export class InputManager {
         // Keyboard events
         this._onCanvasFocusObserver = engine.onCanvasFocusObservable.add((() => {
             let fn = () => {
-                if (!canvas) {
+                if (!elementToAttachTo) {
                     return;
                 }
-                canvas.addEventListener("keydown", this._onKeyDown, false);
-                canvas.addEventListener("keyup", this._onKeyUp, false);
+                elementToAttachTo.addEventListener("keydown", this._onKeyDown, false);
+                elementToAttachTo.addEventListener("keyup", this._onKeyUp, false);
             };
-            if (document.activeElement === canvas) {
+            if (document.activeElement === elementToAttachTo) {
                 fn();
             }
             return fn;
         })());
 
         this._onCanvasBlurObserver = engine.onCanvasBlurObservable.add(() => {
-            if (!canvas) {
+            if (!elementToAttachTo) {
                 return;
             }
-            canvas.removeEventListener("keydown", this._onKeyDown);
-            canvas.removeEventListener("keyup", this._onKeyUp);
+            elementToAttachTo.removeEventListener("keydown", this._onKeyDown);
+            elementToAttachTo.removeEventListener("keyup", this._onKeyUp);
         });
 
         // Pointer events
         var eventPrefix = Tools.GetPointerPrefix();
 
         if (attachMove) {
-            canvas.addEventListener(eventPrefix + "move", <any>this._onPointerMove, false);
+            elementToAttachTo.addEventListener(eventPrefix + "move", <any>this._onPointerMove, false);
 
             // Wheel
             this._wheelEventName = "onwheel" in document.createElement("div") ? "wheel" :       // Modern browsers support "wheel"
                 (<any>document).onmousewheel !== undefined ? "mousewheel" :                     // Webkit and IE support at least "mousewheel"
                     "DOMMouseScroll";                                                           // let's assume that remaining browsers are older Firefox
 
-            canvas.addEventListener(this._wheelEventName, <any>this._onPointerMove, false);
+                    elementToAttachTo.addEventListener(this._wheelEventName, <any>this._onPointerMove, false);
         }
 
         if (attachDown) {
-            canvas.addEventListener(eventPrefix + "down", <any>this._onPointerDown, false);
+            elementToAttachTo.addEventListener(eventPrefix + "down", <any>this._onPointerDown, false);
         }
 
         if (attachUp) {

+ 3 - 0
src/LibDeclarations/webgl2.d.ts

@@ -54,11 +54,14 @@ interface WebGLRenderingContext {
     readonly UNSIGNED_INT_10F_11F_11F_REV: number;
     readonly UNSIGNED_INT_5_9_9_9_REV: number;
     readonly FLOAT_32_UNSIGNED_INT_24_8_REV: number;
+    readonly DEPTH_COMPONENT32F: number;
 
     texImage3D(target: number, level: number, internalformat: number, width: number, height: number, depth: number, border: number, format: number, type: number, pixels: ArrayBufferView | null): void;
     texImage3D(target: number, level: number, internalformat: number, width: number, height: number, depth: number, border: number, format: number, type: number, pixels: ArrayBufferView, offset: number): void;
     texImage3D(target: number, level: number, internalformat: number, width: number, height: number, depth: number, border: number, format: number, type: number, pixels: ImageBitmap | ImageData | HTMLVideoElement | HTMLImageElement | HTMLCanvasElement): void;
 
+    framebufferTextureLayer(target: number, attachment: number, texture: WebGLTexture | null, level: number, layer: number): void;
+
     compressedTexImage3D(target: number, level: number, internalformat: number, width: number, height: number, depth: number, border: number, data: ArrayBufferView, offset?: number, length?: number): void;
 
     readonly TRANSFORM_FEEDBACK: number;

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1707 - 0
src/Lights/Shadows/cascadedShadowGenerator.ts


+ 1 - 0
src/Lights/Shadows/index.ts

@@ -1,2 +1,3 @@
 export * from "./shadowGenerator";
+export * from "./cascadedShadowGenerator";
 export * from "./shadowGeneratorSceneComponent";

+ 4 - 8
src/Lights/Shadows/shadowGenerator.ts

@@ -69,11 +69,6 @@ export interface IShadowGenerator {
      * @returns The render target texture if present otherwise, null
      */
     getShadowMap(): Nullable<RenderTargetTexture>;
-    /**
-     * Gets the RTT used during rendering (can be a blurred version of the shadow map or the shadow map itself).
-     * @returns The render target texture if the shadow map is present otherwise, null
-     */
-    getShadowMapForRendering(): Nullable<RenderTargetTexture>;
 
     /**
      * Determine wheter the shadow generator is ready or not (mainly all effects and related post processes needs to be ready).
@@ -115,7 +110,7 @@ export interface IShadowGenerator {
      * @param onCompiled Callback triggered at the and of the effects compilation
      * @param options Sets of optional options forcing the compilation with different modes
      */
-    forceCompilation(onCompiled?: (generator: ShadowGenerator) => void, options?: Partial<{ useInstances: boolean }>): void;
+    forceCompilation(onCompiled?: (generator: IShadowGenerator) => void, options?: Partial<{ useInstances: boolean }>): void;
 
     /**
      * Forces all the attached effect to compile to enable rendering only once ready vs. lazyly compiling effects.
@@ -936,12 +931,13 @@ export class ShadowGenerator implements IShadowGenerator {
         var index: number;
         let engine = this._scene.getEngine();
 
+        const colorWrite = engine.getColorWrite();
         if (depthOnlySubMeshes.length) {
             engine.setColorWrite(false);
             for (index = 0; index < depthOnlySubMeshes.length; index++) {
                 this._renderSubMeshForShadowMap(depthOnlySubMeshes.data[index]);
             }
-            engine.setColorWrite(true);
+            engine.setColorWrite(colorWrite);
         }
 
         for (index = 0; index < opaqueSubMeshes.length; index++) {
@@ -1074,7 +1070,7 @@ export class ShadowGenerator implements IShadowGenerator {
      * @param onCompiled Callback triggered at the and of the effects compilation
      * @param options Sets of optional options forcing the compilation with different modes
      */
-    public forceCompilation(onCompiled?: (generator: ShadowGenerator) => void, options?: Partial<{ useInstances: boolean }>): void {
+    public forceCompilation(onCompiled?: (generator: IShadowGenerator) => void, options?: Partial<{ useInstances: boolean }>): void {
         let localOptions = {
             useInstances: false,
             ...options

+ 9 - 0
src/Lights/Shadows/shadowGeneratorSceneComponent.ts

@@ -2,6 +2,7 @@ import { SmartArrayNoDuplicate } from "../../Misc/smartArray";
 import { Scene } from "../../scene";
 import { RenderTargetTexture } from "../../Materials/Textures/renderTargetTexture";
 import { ShadowGenerator } from "./shadowGenerator";
+import { CascadedShadowGenerator } from "./cascadedShadowGenerator";
 import { SceneComponentConstants, ISceneSerializableComponent } from "../../sceneComponent";
 import { _TimeToken } from "../../Instrumentation/timeToken";
 import { AbstractScene } from "../../abstractScene";
@@ -121,4 +122,12 @@ ShadowGenerator._SceneComponentInitialization = (scene: Scene) => {
         component = new ShadowGeneratorSceneComponent(scene);
         scene._addComponent(component);
     }
+};
+
+CascadedShadowGenerator._SceneComponentInitialization = (scene: Scene) => {
+    let component = scene._getComponent(SceneComponentConstants.NAME_SHADOWGENERATOR);
+    if (!component) {
+        component = new ShadowGeneratorSceneComponent(scene);
+        scene._addComponent(component);
+    }
 };

+ 12 - 2
src/Materials/Textures/internalTexture.ts

@@ -221,6 +221,8 @@ export class InternalTexture {
     public _lodGenerationScale: number = 0;
     /** @hidden */
     public _lodGenerationOffset: number = 0;
+    /** @hidden */
+    public _depthStencilTexture: Nullable<InternalTexture>;
 
     // Multiview
     /** @hidden */
@@ -379,7 +381,8 @@ export class InternalTexture {
                 } else {
                     let size = {
                         width: this.width,
-                        height: this.height
+                        height: this.height,
+                        layers: this.is2DArray ? this.depth : undefined
                     };
 
                     proxy = (this._engine as Engine).createRenderTargetTexture(size, options);
@@ -396,7 +399,12 @@ export class InternalTexture {
                     isCube: this.isCube
                 };
 
-                proxy = this._engine.createDepthStencilTexture({ width: this.width, height: this.height }, depthTextureOptions);
+                let size = {
+                    width: this.width,
+                    height: this.height,
+                    layers: this.is2DArray ? this.depth : undefined
+                };
+                proxy = this._engine.createDepthStencilTexture(size, depthTextureOptions);
                 proxy._swapAndDie(this);
 
                 this.isReady = true;
@@ -449,6 +457,8 @@ export class InternalTexture {
             target._depthStencilBuffer = this._depthStencilBuffer;
         }
 
+        target._depthStencilTexture = this._depthStencilTexture;
+
         if (this._lodTextureHigh) {
             if (target._lodTextureHigh) {
                 target._lodTextureHigh.dispose();

+ 41 - 13
src/Materials/Textures/renderTargetTexture.ts

@@ -208,7 +208,7 @@ export class RenderTargetTexture extends Texture {
      * Define the clear color of the Render Target if it should be different from the scene.
      */
     public clearColor: Color4;
-    protected _size: number | { width: number, height: number };
+    protected _size: number | { width: number, height: number, layers?: number };
     protected _initialSizeParameter: number | { width: number, height: number } | { ratio: number };
     protected _sizeRatio: Nullable<number>;
     /** @hidden */
@@ -270,7 +270,9 @@ export class RenderTargetTexture extends Texture {
      * depth texture.
      * Otherwise, return null.
      */
-    public depthStencilTexture: Nullable<InternalTexture>;
+    public get depthStencilTexture(): Nullable<InternalTexture> {
+        return this.getInternalTexture()?._depthStencilTexture || null;
+    }
 
     /**
      * Instantiate a render target texture. This is mainly used to render of screen the scene to for instance apply post processse
@@ -289,7 +291,7 @@ export class RenderTargetTexture extends Texture {
      * @param format The internal format of the buffer in the RTT (RED, RG, RGB, RGBA, ALPHA...)
      * @param delayAllocation if the texture allocation should be delayed (default: false)
      */
-    constructor(name: string, size: number | { width: number, height: number } | { ratio: number }, scene: Nullable<Scene>, generateMipMaps?: boolean, doNotChangeAspectRatio: boolean = true, type: number = Constants.TEXTURETYPE_UNSIGNED_INT, public isCube = false, samplingMode = Texture.TRILINEAR_SAMPLINGMODE, generateDepthBuffer = true, generateStencilBuffer = false, isMulti = false, format = Constants.TEXTUREFORMAT_RGBA, delayAllocation = false) {
+    constructor(name: string, size: number | { width: number, height: number, layers?: number } | { ratio: number }, scene: Nullable<Scene>, generateMipMaps?: boolean, doNotChangeAspectRatio: boolean = true, type: number = Constants.TEXTURETYPE_UNSIGNED_INT, public isCube = false, samplingMode = Texture.TRILINEAR_SAMPLINGMODE, generateDepthBuffer = true, generateStencilBuffer = false, isMulti = false, format = Constants.TEXTUREFORMAT_RGBA, delayAllocation = false) {
         super(null, scene, !generateMipMaps);
         scene = this.getScene();
 
@@ -352,18 +354,18 @@ export class RenderTargetTexture extends Texture {
      * @param generateStencil Specifies whether or not a stencil should be allocated in the texture
      */
     public createDepthStencilTexture(comparisonFunction: number = 0, bilinearFiltering: boolean = true, generateStencil: boolean = false): void {
-        if (!this.getScene()) {
+        const internalTexture = this.getInternalTexture();
+        if (!this.getScene() || !internalTexture) {
             return;
         }
 
         var engine = this.getScene()!.getEngine();
-        this.depthStencilTexture = engine.createDepthStencilTexture(this._size, {
+        internalTexture._depthStencilTexture = engine.createDepthStencilTexture(this._size, {
             bilinearFiltering,
             comparisonFunction,
             generateStencil,
             isCube: this.isCube
         });
-        engine.setFrameBufferDepthStencilTexture(this);
     }
 
     private _processSizeParameter(size: number | { width: number, height: number } | { ratio: number }): void {
@@ -374,7 +376,7 @@ export class RenderTargetTexture extends Texture {
                 height: this._bestReflectionRenderTargetDimension(this._engine.getRenderHeight(), this._sizeRatio)
             };
         } else {
-            this._size = <number | { width: number, height: number }>size;
+            this._size = <number | { width: number, height: number, layers?: number }>size;
         }
     }
 
@@ -528,6 +530,19 @@ export class RenderTargetTexture extends Texture {
     }
 
     /**
+     * Gets the actual number of layers of the texture.
+     * @returns the number of layers
+     */
+    public getRenderLayers(): number {
+        const layers = (<{ width: number, height: number, layers?: number }>this._size).layers;
+        if (layers) {
+            return layers;
+        }
+
+        return 0;
+    }
+
+    /**
      * Get if the texture can be rescaled or not.
      */
     public get canRescale(): boolean {
@@ -717,7 +732,14 @@ export class RenderTargetTexture extends Texture {
             }
         }
 
-        if (this.isCube) {
+        if (this.is2DArray) {
+            for (let layer = 0; layer < this.getRenderLayers(); layer++) {
+                this.renderToTarget(0, currentRenderList, useCameraPostProcess, dumpForDebug, layer);
+                scene.incrementRenderId();
+                scene.resetCachedMaterial();
+            }
+        }
+        else if (this.isCube) {
             for (var face = 0; face < 6; face++) {
                 this.renderToTarget(face, currentRenderList, useCameraPostProcess, dumpForDebug);
                 scene.incrementRenderId();
@@ -752,8 +774,9 @@ export class RenderTargetTexture extends Texture {
     /**
      * @hidden
      * @param faceIndex face index to bind to if this is a cubetexture
+     * @param layer defines the index of the texture to bind in the array
      */
-    public _bindFrameBuffer(faceIndex: number = 0) {
+    public _bindFrameBuffer(faceIndex: number = 0, layer = 0) {
         var scene = this.getScene();
         if (!scene) {
             return;
@@ -761,7 +784,7 @@ export class RenderTargetTexture extends Texture {
 
         var engine = scene.getEngine();
         if (this._texture) {
-            engine.bindFramebuffer(this._texture, this.isCube ? faceIndex : undefined, undefined, undefined, this.ignoreCameraViewport, this.depthStencilTexture ? this.depthStencilTexture : undefined);
+            engine.bindFramebuffer(this._texture, this.isCube ? faceIndex : undefined, undefined, undefined, this.ignoreCameraViewport, 0, layer);
         }
     }
 
@@ -774,7 +797,7 @@ export class RenderTargetTexture extends Texture {
         });
     }
 
-    private renderToTarget(faceIndex: number, currentRenderList: AbstractMesh[], useCameraPostProcess: boolean, dumpForDebug: boolean): void {
+    private renderToTarget(faceIndex: number, currentRenderList: AbstractMesh[], useCameraPostProcess: boolean, dumpForDebug: boolean, layer = 0): void {
         var scene = this.getScene();
 
         if (!scene) {
@@ -792,10 +815,15 @@ export class RenderTargetTexture extends Texture {
             this._postProcessManager._prepareFrame(this._texture, this._postProcesses);
         }
         else if (!useCameraPostProcess || !scene.postProcessManager._prepareFrame(this._texture)) {
-            this._bindFrameBuffer(faceIndex);
+            this._bindFrameBuffer(faceIndex, layer);
         }
 
-        this.onBeforeRenderObservable.notifyObservers(faceIndex);
+        if (this.is2DArray) {
+            this.onBeforeRenderObservable.notifyObservers(layer);
+        }
+        else {
+            this.onBeforeRenderObservable.notifyObservers(faceIndex);
+        }
 
         // Clear
         if (this.onClearObservable.hasObservers()) {

+ 19 - 0
src/Materials/Textures/videoTexture.ts

@@ -69,6 +69,7 @@ export class VideoTexture extends Texture {
     private _settings: VideoTextureSettings;
     private _createInternalTextureOnEvent: string;
     private _frameId = -1;
+    private _currentSrc: Nullable<string | string[] | HTMLVideoElement> = null;
 
     /**
      * Creates a video texture.
@@ -103,6 +104,7 @@ export class VideoTexture extends Texture {
         this._initialSamplingMode = samplingMode;
         this.autoUpdateTexture = settings.autoUpdateTexture;
 
+        this._currentSrc = src;
         this.name = name || this._getName(src);
         this.video = this._getVideo(src);
         this._settings = settings;
@@ -317,6 +319,21 @@ export class VideoTexture extends Texture {
      */
     public updateURL(url: string): void {
         this.video.src = url;
+        this._currentSrc = url;
+    }
+
+    /**
+     * Clones the texture.
+     * @returns the cloned texture
+     */
+    public clone(): VideoTexture {
+        return new VideoTexture(this.name,
+            this._currentSrc!,
+            this.getScene(),
+            this._generateMipMaps,
+            this.invertY,
+            this.samplingMode,
+            this._settings);
     }
 
     /**
@@ -325,6 +342,8 @@ export class VideoTexture extends Texture {
     public dispose(): void {
         super.dispose();
 
+        this._currentSrc = null;
+
         if (this._onUserActionRequestedObservable) {
             this._onUserActionRequestedObservable.clear();
             this._onUserActionRequestedObservable = null;

+ 17 - 0
src/Materials/materialHelper.ts

@@ -343,6 +343,10 @@ export class MaterialHelper {
 
         // Shadows
         defines["SHADOW" + lightIndex] = false;
+        defines["SHADOWCSM" + lightIndex] = false;
+        defines["SHADOWCSMDEBUG" + lightIndex] = false;
+        defines["SHADOWCSMNUM_CASCADES" + lightIndex] = false;
+        defines["SHADOWCSMUSESHADOWMAXZ" + lightIndex] = false;
         defines["SHADOWPCF" + lightIndex] = false;
         defines["SHADOWPCSS" + lightIndex] = false;
         defines["SHADOWPOISSON" + lightIndex] = false;
@@ -421,6 +425,10 @@ export class MaterialHelper {
                 defines["DIRLIGHT" + index] = false;
                 defines["SPOTLIGHT" + index] = false;
                 defines["SHADOW" + index] = false;
+                defines["SHADOWCSM" + index] = false;
+                defines["SHADOWCSMDEBUG" + index] = false;
+                defines["SHADOWCSMNUM_CASCADES" + index] = false;
+                defines["SHADOWCSMUSESHADOWMAXZ" + index] = false;
                 defines["SHADOWPCF" + index] = false;
                 defines["SHADOWPCSS" + index] = false;
                 defines["SHADOWPOISSON" + index] = false;
@@ -477,6 +485,15 @@ export class MaterialHelper {
         samplersList.push("shadowSampler" + lightIndex);
         samplersList.push("depthSampler" + lightIndex);
 
+        uniformsList.push(
+            "viewFrustumZ" + lightIndex,
+            "cascadeBlendFactor" + lightIndex,
+            "lightSizeUVCorrection" + lightIndex,
+            "depthCorrection" + lightIndex,
+            "penumbraDarkness" + lightIndex,
+            "frustumLengths" + lightIndex,
+        );
+
         if (projectedLightTexture) {
             samplersList.push("projectionLightSampler" + lightIndex);
             uniformsList.push(

+ 7 - 2
src/PostProcesses/postProcess.ts

@@ -136,6 +136,7 @@ export class PostProcess {
     private _options: number | PostProcessOptions;
     private _reusable = false;
     private _textureType: number;
+    private _textureFormat: number;
     /**
     * Smart array of input and output textures for the post process.
     * @hidden
@@ -301,12 +302,14 @@ export class PostProcess {
      * @param vertexUrl The url of the vertex shader to be used. (default: "postprocess")
      * @param indexParameters The index parameters to be used for babylons include syntax "#include<kernelBlurVaryingDeclaration>[0..varyingCount]". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx
      * @param blockCompilation If the shader should not be compiled imediatly. (default: false)
+     * @param textureFormat Format of textures used when performing the post process. (default: TEXTUREFORMAT_RGBA)
      */
     constructor(
         /** Name of the PostProcess. */
         public name: string,
         fragmentUrl: string, parameters: Nullable<string[]>, samplers: Nullable<string[]>, options: number | PostProcessOptions, camera: Nullable<Camera>,
-        samplingMode: number = Constants.TEXTURE_NEAREST_SAMPLINGMODE, engine?: Engine, reusable?: boolean, defines: Nullable<string> = null, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT, vertexUrl: string = "postprocess", indexParameters?: any, blockCompilation = false) {
+        samplingMode: number = Constants.TEXTURE_NEAREST_SAMPLINGMODE, engine?: Engine, reusable?: boolean, defines: Nullable<string> = null, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT, vertexUrl: string = "postprocess",
+        indexParameters?: any, blockCompilation = false, textureFormat = Constants.TEXTUREFORMAT_RGBA) {
         if (camera != null) {
             this._camera = camera;
             this._scene = camera.getScene();
@@ -324,6 +327,7 @@ export class PostProcess {
         this.renderTargetSamplingMode = samplingMode ? samplingMode : Constants.TEXTURE_NEAREST_SAMPLINGMODE;
         this._reusable = reusable || false;
         this._textureType = textureType;
+        this._textureFormat = textureFormat;
 
         this._samplers = samplers || [];
         this._samplers.push("textureSampler");
@@ -495,7 +499,8 @@ export class PostProcess {
                     generateDepthBuffer: forceDepthStencil || camera._postProcesses.indexOf(this) === 0,
                     generateStencilBuffer: (forceDepthStencil || camera._postProcesses.indexOf(this) === 0) && this._engine.isStencilEnable,
                     samplingMode: this.renderTargetSamplingMode,
-                    type: this._textureType
+                    type: this._textureType,
+                    format: this._textureFormat
                 };
 
                 this._textures.push(this._engine.createRenderTargetTexture(textureSize, textureOptions));

+ 1 - 1
src/PostProcesses/postProcessManager.ts

@@ -110,7 +110,7 @@ export class PostProcessManager {
                 postProcesses[index + 1].activate(this._scene.activeCamera, targetTexture);
             } else {
                 if (targetTexture) {
-                    engine.bindFramebuffer(targetTexture, faceIndex, undefined, undefined, forceFullscreenViewport, undefined, lodLevel);
+                    engine.bindFramebuffer(targetTexture, faceIndex, undefined, undefined, forceFullscreenViewport, lodLevel);
                 } else {
                     engine.restoreDefaultFramebuffer();
                 }

+ 76 - 2
src/Shaders/ShadersInclude/lightFragment.fx

@@ -125,7 +125,77 @@
     #endif
 
     #ifdef SHADOW{X}
-        #ifdef SHADOWCLOSEESM{X}
+        #ifdef SHADOWCSM{X}
+            for (int i = 0; i < SHADOWCSMNUM_CASCADES{X}; i++) 
+            {
+                diff{X} = viewFrustumZ{X}[i] - vPositionFromCamera{X}.z;
+                if (diff{X} >= 0.) {
+                    index{X} = i;
+                    break;
+                }
+            }
+
+            #ifdef SHADOWCSMUSESHADOWMAXZ{X}
+            if (index{X} >= 0)
+            #endif
+            {
+                float frustumLength = frustumLengths{X}[index{X}];
+                #if defined(SHADOWPCF{X})
+                    #if defined(SHADOWLOWQUALITY{X})
+                        shadow = computeShadowWithCSMPCF1(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], shadowSampler{X}, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w);
+                    #elif defined(SHADOWMEDIUMQUALITY{X})
+                        shadow = computeShadowWithCSMPCF3(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], shadowSampler{X}, light{X}.shadowsInfo.yz, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w);
+                    #else
+                        shadow = computeShadowWithCSMPCF5(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], shadowSampler{X}, light{X}.shadowsInfo.yz, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w);
+                    #endif
+                #elif defined(SHADOWPCSS{X})
+                    #if defined(SHADOWLOWQUALITY{X})
+                        shadow = computeShadowWithCSMPCSS16(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], depthSampler{X}, shadowSampler{X}, light{X}.shadowsInfo.y, light{X}.shadowsInfo.z, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w, lightSizeUVCorrection{X}[index{X}], depthCorrection{X}[index{X}], penumbraDarkness{X});
+                    #elif defined(SHADOWMEDIUMQUALITY{X})
+                        shadow = computeShadowWithCSMPCSS32(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], depthSampler{X}, shadowSampler{X}, light{X}.shadowsInfo.y, light{X}.shadowsInfo.z, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w, lightSizeUVCorrection{X}[index{X}], depthCorrection{X}[index{X}], penumbraDarkness{X});
+                    #else
+                        shadow = computeShadowWithCSMPCSS64(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], depthSampler{X}, shadowSampler{X}, light{X}.shadowsInfo.y, light{X}.shadowsInfo.z, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w, lightSizeUVCorrection{X}[index{X}], depthCorrection{X}[index{X}], penumbraDarkness{X});
+                    #endif
+                #else
+                    shadow = computeShadowCSM(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], shadowSampler{X}, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w);
+                #endif
+
+                #ifdef SHADOWCSMDEBUG{X}
+                    shadowDebug{X} = vec3(shadow) * vCascadeColorsMultiplier{X}[index{X}];
+                #endif
+
+                float diffRatio = clamp(diff{X} / frustumLength, 0., 1.) * cascadeBlendFactor{X};
+                if (index{X} < (SHADOWCSMNUM_CASCADES{X} - 1) && diffRatio < 1.)
+                {
+                    index{X} += 1;
+                    float nextShadow = 0.;
+                    #if defined(SHADOWPCF{X})
+                        #if defined(SHADOWLOWQUALITY{X})
+                            nextShadow = computeShadowWithCSMPCF1(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], shadowSampler{X}, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w);
+                        #elif defined(SHADOWMEDIUMQUALITY{X})
+                            nextShadow = computeShadowWithCSMPCF3(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], shadowSampler{X}, light{X}.shadowsInfo.yz, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w);
+                        #else
+                            nextShadow = computeShadowWithCSMPCF5(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], shadowSampler{X}, light{X}.shadowsInfo.yz, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w);
+                        #endif
+                    #elif defined(SHADOWPCSS{X})
+                        #if defined(SHADOWLOWQUALITY{X})
+                            nextShadow = computeShadowWithCSMPCSS16(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], depthSampler{X}, shadowSampler{X}, light{X}.shadowsInfo.y, light{X}.shadowsInfo.z, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w, lightSizeUVCorrection{X}[index{X}], depthCorrection{X}[index{X}], penumbraDarkness{X});
+                        #elif defined(SHADOWMEDIUMQUALITY{X})
+                            nextShadow = computeShadowWithCSMPCSS32(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], depthSampler{X}, shadowSampler{X}, light{X}.shadowsInfo.y, light{X}.shadowsInfo.z, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w, lightSizeUVCorrection{X}[index{X}], depthCorrection{X}[index{X}], penumbraDarkness{X});
+                        #else
+                            nextShadow = computeShadowWithCSMPCSS64(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], depthSampler{X}, shadowSampler{X}, light{X}.shadowsInfo.y, light{X}.shadowsInfo.z, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w, lightSizeUVCorrection{X}[index{X}], depthCorrection{X}[index{X}], penumbraDarkness{X});
+                        #endif
+                    #else
+                        nextShadow = computeShadowCSM(float(index{X}), vPositionFromLight{X}[index{X}], vDepthMetric{X}[index{X}], shadowSampler{X}, light{X}.shadowsInfo.x, light{X}.shadowsInfo.w);
+                    #endif
+
+                    shadow = mix(nextShadow, shadow, diffRatio);
+                    #ifdef SHADOWCSMDEBUG{X}
+                        shadowDebug{X} = mix(vec3(nextShadow) * vCascadeColorsMultiplier{X}[index{X}], shadowDebug{X}, diffRatio);
+                    #endif
+                }
+            }
+        #elif defined(SHADOWCLOSEESM{X})
             #if defined(SHADOWCUBE{X})
                 shadow = computeShadowWithCloseESMCube(light{X}.vLightData.xyz, shadowSampler{X}, light{X}.shadowsInfo.x, light{X}.shadowsInfo.z, light{X}.depthValues);
             #else
@@ -202,7 +272,11 @@
                 #endif
             #endif
         #else
-            diffuseBase += info.diffuse * shadow;
+            #ifdef SHADOWCSMDEBUG{X}
+                diffuseBase += info.diffuse * shadowDebug{X};
+            #else        
+                diffuseBase += info.diffuse * shadow;
+            #endif
             #ifdef SPECULARTERM
                 specularBase += info.specular * shadow;
             #endif

+ 45 - 1
src/Shaders/ShadersInclude/lightFragmentDeclaration.fx

@@ -8,7 +8,51 @@
 		vec4 vLightSpecular{X} = vec4(0.);
 	#endif
 	#ifdef SHADOW{X}
-		#if defined(SHADOWCUBE{X})
+        #ifdef SHADOWCSM{X}
+            uniform mat4 lightMatrix{X}[SHADOWCSMNUM_CASCADES{X}];
+            uniform float viewFrustumZ{X}[SHADOWCSMNUM_CASCADES{X}];
+            uniform float frustumLengths{X}[SHADOWCSMNUM_CASCADES{X}];
+            uniform float cascadeBlendFactor{X};
+
+            varying vec4 vPositionFromLight{X}[SHADOWCSMNUM_CASCADES{X}];
+            varying float vDepthMetric{X}[SHADOWCSMNUM_CASCADES{X}];
+            varying vec4 vPositionFromCamera{X};
+
+            #if defined(SHADOWPCSS{X})
+                uniform highp sampler2DArrayShadow shadowSampler{X};
+                uniform highp sampler2DArray depthSampler{X};
+                uniform vec2 lightSizeUVCorrection{X}[SHADOWCSMNUM_CASCADES{X}];
+                uniform float depthCorrection{X}[SHADOWCSMNUM_CASCADES{X}];
+                uniform float penumbraDarkness{X};
+            #elif defined(SHADOWPCF{X})
+                uniform highp sampler2DArrayShadow shadowSampler{X};
+            #else
+                uniform highp sampler2DArray shadowSampler{X};
+            #endif
+
+            #ifdef SHADOWCSMDEBUG{X}
+                const vec3 vCascadeColorsMultiplier{X}[8] = vec3[8]
+                (
+                    vec3 ( 1.5, 0.0, 0.0 ),
+                    vec3 ( 0.0, 1.5, 0.0 ),
+                    vec3 ( 0.0, 0.0, 5.5 ),
+                    vec3 ( 1.5, 0.0, 5.5 ),
+                    vec3 ( 1.5, 1.5, 0.0 ),
+                    vec3 ( 1.0, 1.0, 1.0 ),
+                    vec3 ( 0.0, 1.0, 5.5 ),
+                    vec3 ( 0.5, 3.5, 0.75 )
+                );
+                vec3 shadowDebug{X};
+            #endif
+
+            #ifdef SHADOWCSMUSESHADOWMAXZ{X}
+                int index{X} = -1;
+            #else
+                int index{X} = SHADOWCSMNUM_CASCADES{X} - 1;
+            #endif
+
+            float diff{X} = 0.;
+        #elif defined(SHADOWCUBE{X})
 			uniform samplerCube shadowSampler{X};
 		#else
 			varying vec4 vPositionFromLight{X};

+ 45 - 1
src/Shaders/ShadersInclude/lightUboDeclaration.fx

@@ -21,7 +21,51 @@
 	uniform sampler2D projectionLightSampler{X};
 #endif
 #ifdef SHADOW{X}
-	#if defined(SHADOWCUBE{X})
+	#ifdef SHADOWCSM{X}
+		uniform mat4 lightMatrix{X}[SHADOWCSMNUM_CASCADES{X}];
+		uniform float viewFrustumZ{X}[SHADOWCSMNUM_CASCADES{X}];
+        uniform float frustumLengths{X}[SHADOWCSMNUM_CASCADES{X}];
+        uniform float cascadeBlendFactor{X};
+
+		varying vec4 vPositionFromLight{X}[SHADOWCSMNUM_CASCADES{X}];
+		varying float vDepthMetric{X}[SHADOWCSMNUM_CASCADES{X}];
+		varying vec4 vPositionFromCamera{X};
+
+		#if defined(SHADOWPCSS{X})
+			uniform highp sampler2DArrayShadow shadowSampler{X};
+			uniform highp sampler2DArray depthSampler{X};
+            uniform vec2 lightSizeUVCorrection{X}[SHADOWCSMNUM_CASCADES{X}];
+            uniform float depthCorrection{X}[SHADOWCSMNUM_CASCADES{X}];
+            uniform float penumbraDarkness{X};
+		#elif defined(SHADOWPCF{X})
+			uniform highp sampler2DArrayShadow shadowSampler{X};
+		#else
+			uniform highp sampler2DArray shadowSampler{X};
+		#endif
+
+        #ifdef SHADOWCSMDEBUG{X}
+            const vec3 vCascadeColorsMultiplier{X}[8] = vec3[8]
+            (
+                vec3 ( 1.5, 0.0, 0.0 ),
+                vec3 ( 0.0, 1.5, 0.0 ),
+                vec3 ( 0.0, 0.0, 5.5 ),
+                vec3 ( 1.5, 0.0, 5.5 ),
+                vec3 ( 1.5, 1.5, 0.0 ),
+                vec3 ( 1.0, 1.0, 1.0 ),
+                vec3 ( 0.0, 1.0, 5.5 ),
+                vec3 ( 0.5, 3.5, 0.75 )
+            );
+            vec3 shadowDebug{X};
+        #endif
+
+        #ifdef SHADOWCSMUSESHADOWMAXZ{X}
+            int index{X} = -1;
+        #else
+            int index{X} = SHADOWCSMNUM_CASCADES{X} - 1;
+        #endif
+
+        float diff{X} = 0.;
+	#elif defined(SHADOWCUBE{X})
 		uniform samplerCube shadowSampler{X};		
 	#else
 		varying vec4 vPositionFromLight{X};

+ 218 - 1
src/Shaders/ShadersInclude/shadowsFragmentFunctions.fx

@@ -10,7 +10,7 @@
 
     float computeFallOff(float value, vec2 clipSpace, float frustumEdgeFalloff)
     {
-        float mask = smoothstep(1.0 - frustumEdgeFalloff, 1.0, clamp(dot(clipSpace, clipSpace), 0., 1.));
+        float mask = smoothstep(1.0 - frustumEdgeFalloff, 1.00000012, clamp(dot(clipSpace, clipSpace), 0., 1.));
         return mix(value, 1.0, mask);
     }
 
@@ -113,6 +113,34 @@
         return esm;
     }
 
+    #ifdef WEBGL2
+        float computeShadowCSM(float layer, vec4 vPositionFromLight, float depthMetric, highp sampler2DArray shadowSampler, float darkness, float frustumEdgeFalloff)
+        {
+            vec3 clipSpace = vPositionFromLight.xyz / vPositionFromLight.w;
+            vec2 uv = 0.5 * clipSpace.xy + vec2(0.5);
+            vec3 uvLayer = vec3(uv.x, uv.y, layer);
+
+            if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0)
+            {
+                return 1.0;
+            }
+
+            float shadowPixelDepth = clamp(depthMetric, 0., 1.0);
+
+            #ifndef SHADOWFLOAT
+                float shadow = unpack(texture2D(shadowSampler, uvLayer));
+            #else
+                float shadow = texture2D(shadowSampler, uvLayer).x;
+            #endif
+
+            if (shadowPixelDepth > shadow)
+            {
+                return computeFallOff(darkness, clipSpace.xy, frustumEdgeFalloff);
+            }
+            return 1.;
+        }
+    #endif
+
     float computeShadow(vec4 vPositionFromLight, float depthMetric, sampler2D shadowSampler, float darkness, float frustumEdgeFalloff)
     {
         vec3 clipSpace = vPositionFromLight.xyz / vPositionFromLight.w;
@@ -222,6 +250,115 @@
     }
 
     #ifdef WEBGL2
+        #define GREATEST_LESS_THAN_ONE 0.99999994
+
+        // Shadow PCF kernel size 1 with a single tap (lowest quality)
+        float computeShadowWithCSMPCF1(float layer, vec4 vPositionFromLight, float depthMetric, highp sampler2DArrayShadow shadowSampler, float darkness, float frustumEdgeFalloff)
+        {
+            vec3 clipSpace = vPositionFromLight.xyz / vPositionFromLight.w;
+            vec3 uvDepth = vec3(0.5 * clipSpace.xyz + vec3(0.5));
+
+            if (uvDepth.x < 0. || uvDepth.x > 1.0 || uvDepth.y < 0. || uvDepth.y > 1.0)
+            {
+                return 1.0;
+            }
+
+            uvDepth.z = clamp(uvDepth.z, 0., GREATEST_LESS_THAN_ONE);
+
+            vec4 uvDepthLayer = vec4(uvDepth.x, uvDepth.y, layer, uvDepth.z);
+
+            float shadow = texture(shadowSampler, uvDepthLayer);
+            shadow = mix(darkness, 1., shadow);
+            return computeFallOff(shadow, clipSpace.xy, frustumEdgeFalloff);
+        }
+
+        // Shadow PCF kernel 3*3 in only 4 taps (medium quality)
+        // This uses a well distributed taps to allow a gaussian distribution covering a 3*3 kernel
+        // https://mynameismjp.wordpress.com/2013/09/10/shadow-maps/
+        float computeShadowWithCSMPCF3(float layer, vec4 vPositionFromLight, float depthMetric, highp sampler2DArrayShadow shadowSampler, vec2 shadowMapSizeAndInverse, float darkness, float frustumEdgeFalloff)
+        {
+            vec3 clipSpace = vPositionFromLight.xyz / vPositionFromLight.w;
+            vec3 uvDepth = vec3(0.5 * clipSpace.xyz + vec3(0.5));
+
+            if (uvDepth.x < 0. || uvDepth.x > 1.0 || uvDepth.y < 0. || uvDepth.y > 1.0)
+            {
+                return 1.0;
+            }
+
+            uvDepth.z = clamp(uvDepth.z, 0., GREATEST_LESS_THAN_ONE);
+
+            vec2 uv = uvDepth.xy * shadowMapSizeAndInverse.x;	// uv in texel units
+            uv += 0.5;											// offset of half to be in the center of the texel
+            vec2 st = fract(uv);								// how far from the center
+            vec2 base_uv = floor(uv) - 0.5;						// texel coord
+            base_uv *= shadowMapSizeAndInverse.y;				// move back to uv coords
+
+            // Equation resolved to fit in a 3*3 distribution like 
+            // 1 2 1
+            // 2 4 2 
+            // 1 2 1
+            vec2 uvw0 = 3. - 2. * st;
+            vec2 uvw1 = 1. + 2. * st;
+            vec2 u = vec2((2. - st.x) / uvw0.x - 1., st.x / uvw1.x + 1.) * shadowMapSizeAndInverse.y;
+            vec2 v = vec2((2. - st.y) / uvw0.y - 1., st.y / uvw1.y + 1.) * shadowMapSizeAndInverse.y;
+
+            float shadow = 0.;
+            shadow += uvw0.x * uvw0.y * texture2D(shadowSampler, vec4(base_uv.xy + vec2(u[0], v[0]), layer, uvDepth.z));
+            shadow += uvw1.x * uvw0.y * texture2D(shadowSampler, vec4(base_uv.xy + vec2(u[1], v[0]), layer, uvDepth.z));
+            shadow += uvw0.x * uvw1.y * texture2D(shadowSampler, vec4(base_uv.xy + vec2(u[0], v[1]), layer, uvDepth.z));
+            shadow += uvw1.x * uvw1.y * texture2D(shadowSampler, vec4(base_uv.xy + vec2(u[1], v[1]), layer, uvDepth.z));
+            shadow = shadow / 16.;
+
+            shadow = mix(darkness, 1., shadow);
+            return computeFallOff(shadow, clipSpace.xy, frustumEdgeFalloff);
+        }
+
+        // Shadow PCF kernel 5*5 in only 9 taps (high quality)
+        // This uses a well distributed taps to allow a gaussian distribution covering a 5*5 kernel
+        // https://mynameismjp.wordpress.com/2013/09/10/shadow-maps/
+        float computeShadowWithCSMPCF5(float layer, vec4 vPositionFromLight, float depthMetric, highp sampler2DArrayShadow shadowSampler, vec2 shadowMapSizeAndInverse, float darkness, float frustumEdgeFalloff)
+        {
+            vec3 clipSpace = vPositionFromLight.xyz / vPositionFromLight.w;
+            vec3 uvDepth = vec3(0.5 * clipSpace.xyz + vec3(0.5));
+
+            if (uvDepth.x < 0. || uvDepth.x > 1.0 || uvDepth.y < 0. || uvDepth.y > 1.0)
+            {
+                return 1.0;
+            }
+
+            uvDepth.z = clamp(uvDepth.z, 0., GREATEST_LESS_THAN_ONE);
+
+            vec2 uv = uvDepth.xy * shadowMapSizeAndInverse.x;	// uv in texel units
+            uv += 0.5;											// offset of half to be in the center of the texel
+            vec2 st = fract(uv);								// how far from the center
+            vec2 base_uv = floor(uv) - 0.5;						// texel coord
+            base_uv *= shadowMapSizeAndInverse.y;				// move back to uv coords
+
+            // Equation resolved to fit in a 5*5 distribution like 
+            // 1 2 4 2 1
+            vec2 uvw0 = 4. - 3. * st;
+            vec2 uvw1 = vec2(7.);
+            vec2 uvw2 = 1. + 3. * st;
+
+            vec3 u = vec3((3. - 2. * st.x) / uvw0.x - 2., (3. + st.x) / uvw1.x, st.x / uvw2.x + 2.) * shadowMapSizeAndInverse.y;
+            vec3 v = vec3((3. - 2. * st.y) / uvw0.y - 2., (3. + st.y) / uvw1.y, st.y / uvw2.y + 2.) * shadowMapSizeAndInverse.y;
+
+            float shadow = 0.;
+            shadow += uvw0.x * uvw0.y * texture2D(shadowSampler, vec4(base_uv.xy + vec2(u[0], v[0]), layer, uvDepth.z));
+            shadow += uvw1.x * uvw0.y * texture2D(shadowSampler, vec4(base_uv.xy + vec2(u[1], v[0]), layer, uvDepth.z));
+            shadow += uvw2.x * uvw0.y * texture2D(shadowSampler, vec4(base_uv.xy + vec2(u[2], v[0]), layer, uvDepth.z));
+            shadow += uvw0.x * uvw1.y * texture2D(shadowSampler, vec4(base_uv.xy + vec2(u[0], v[1]), layer, uvDepth.z));
+            shadow += uvw1.x * uvw1.y * texture2D(shadowSampler, vec4(base_uv.xy + vec2(u[1], v[1]), layer, uvDepth.z));
+            shadow += uvw2.x * uvw1.y * texture2D(shadowSampler, vec4(base_uv.xy + vec2(u[2], v[1]), layer, uvDepth.z));
+            shadow += uvw0.x * uvw2.y * texture2D(shadowSampler, vec4(base_uv.xy + vec2(u[0], v[2]), layer, uvDepth.z));
+            shadow += uvw1.x * uvw2.y * texture2D(shadowSampler, vec4(base_uv.xy + vec2(u[1], v[2]), layer, uvDepth.z));
+            shadow += uvw2.x * uvw2.y * texture2D(shadowSampler, vec4(base_uv.xy + vec2(u[2], v[2]), layer, uvDepth.z));
+            shadow = shadow / 144.;
+
+            shadow = mix(darkness, 1., shadow);
+            return computeFallOff(shadow, clipSpace.xy, frustumEdgeFalloff);
+        }
+
         // Shadow PCF kernel size 1 with a single tap (lowest quality)
         float computeShadowWithPCF1(vec4 vPositionFromLight, float depthMetric, sampler2DShadow shadowSampler, float darkness, float frustumEdgeFalloff)
         {
@@ -458,6 +595,71 @@
         // It uses 16 Taps for search and a 32 PCF taps in a randomly rotating poisson sampling disc.
         // This is heavily inspired from http://developer.download.nvidia.com/shaderlibrary/docs/shadow_PCSS.pdf
         // and http://developer.download.nvidia.com/whitepapers/2008/PCSS_Integration.pdf
+        float computeShadowWithCSMPCSS(float layer, vec4 vPositionFromLight, float depthMetric, highp sampler2DArray depthSampler, highp sampler2DArrayShadow shadowSampler, float shadowMapSizeInverse, float lightSizeUV, float darkness, float frustumEdgeFalloff, int searchTapCount, int pcfTapCount, vec3[64] poissonSamplers, vec2 lightSizeUVCorrection, float depthCorrection, float penumbraDarkness)
+        {
+            vec3 clipSpace = vPositionFromLight.xyz / vPositionFromLight.w;
+            vec3 uvDepth = vec3(0.5 * clipSpace.xyz + vec3(0.5));
+
+            if (uvDepth.x < 0. || uvDepth.x > 1.0 || uvDepth.y < 0. || uvDepth.y > 1.0)
+            {
+                return 1.0;
+            }
+
+            uvDepth.z = clamp(uvDepth.z, 0., GREATEST_LESS_THAN_ONE);
+
+            vec4 uvDepthLayer = vec4(uvDepth.x, uvDepth.y, layer, uvDepth.z);
+
+            float blockerDepth = 0.0;
+            float sumBlockerDepth = 0.0;
+            float numBlocker = 0.0;
+            for (int i = 0; i < searchTapCount; i ++) {
+                blockerDepth = texture(depthSampler, vec3(uvDepth.xy + (lightSizeUV * lightSizeUVCorrection * shadowMapSizeInverse * PoissonSamplers32[i].xy), layer)).r;
+                if (blockerDepth < depthMetric) {
+                    sumBlockerDepth += blockerDepth;
+                    numBlocker++;
+                }
+            }
+
+            if (numBlocker < 1.0) {
+                return 1.0;
+            }
+            float avgBlockerDepth = sumBlockerDepth / numBlocker;
+
+            // Offset preventing aliasing on contact.
+            float AAOffset = shadowMapSizeInverse * 10.;
+            // Do not dividing by z despite being physically incorrect looks better due to the limited kernel size.
+            // float penumbraRatio = (depthMetric - avgBlockerDepth) / avgBlockerDepth;
+            float penumbraRatio = ((depthMetric - avgBlockerDepth) * depthCorrection + AAOffset);
+            vec4 filterRadius = vec4(penumbraRatio * lightSizeUV * lightSizeUVCorrection * shadowMapSizeInverse, 0., 0.);
+
+            float random = getRand(vPositionFromLight.xy);
+            float rotationAngle = random * 3.1415926;
+            vec2 rotationVector = vec2(cos(rotationAngle), sin(rotationAngle));
+
+            float shadow = 0.;
+            for (int i = 0; i < pcfTapCount; i++) {
+                vec4 offset = vec4(poissonSamplers[i], 0.);
+                // Rotated offset.
+                offset = vec4(offset.x * rotationVector.x - offset.y * rotationVector.y, offset.y * rotationVector.x + offset.x * rotationVector.y, 0., 0.);
+                shadow += texture2D(shadowSampler, uvDepthLayer + offset * filterRadius);
+            }
+            shadow /= float(pcfTapCount);
+
+            // Blocker distance falloff
+            shadow = mix(shadow, 1., min((depthMetric - avgBlockerDepth) * depthCorrection * penumbraDarkness, 1.));
+
+            // Apply darkness
+            shadow = mix(darkness, 1., shadow);
+
+            // Apply light frustrum fallof
+            return computeFallOff(shadow, clipSpace.xy, frustumEdgeFalloff);
+        }
+
+        // PCSS
+        // This helps to achieve a contact hardening effect on the shadow
+        // It uses 16 Taps for search and a 32 PCF taps in a randomly rotating poisson sampling disc.
+        // This is heavily inspired from http://developer.download.nvidia.com/shaderlibrary/docs/shadow_PCSS.pdf
+        // and http://developer.download.nvidia.com/whitepapers/2008/PCSS_Integration.pdf
         float computeShadowWithPCSS(vec4 vPositionFromLight, float depthMetric, sampler2D depthSampler, sampler2DShadow shadowSampler, float shadowMapSizeInverse, float lightSizeUV, float darkness, float frustumEdgeFalloff, int searchTapCount, int pcfTapCount, vec3[64] poissonSamplers)
         {
             if (depthMetric > 1.0 || depthMetric < 0.0) {
@@ -527,5 +729,20 @@
         {
             return computeShadowWithPCSS(vPositionFromLight, depthMetric, depthSampler, shadowSampler, shadowMapSizeInverse, lightSizeUV, darkness, frustumEdgeFalloff, 32, 64, PoissonSamplers64);
         }
+
+        float computeShadowWithCSMPCSS16(float layer, vec4 vPositionFromLight, float depthMetric, highp sampler2DArray depthSampler, highp sampler2DArrayShadow shadowSampler, float shadowMapSizeInverse, float lightSizeUV, float darkness, float frustumEdgeFalloff, vec2 lightSizeUVCorrection, float depthCorrection, float penumbraDarkness)
+        {
+            return computeShadowWithCSMPCSS(layer, vPositionFromLight, depthMetric, depthSampler, shadowSampler, shadowMapSizeInverse, lightSizeUV, darkness, frustumEdgeFalloff, 16, 16, PoissonSamplers32, lightSizeUVCorrection, depthCorrection, penumbraDarkness);
+        }
+
+        float computeShadowWithCSMPCSS32(float layer, vec4 vPositionFromLight, float depthMetric, highp sampler2DArray depthSampler, highp sampler2DArrayShadow shadowSampler, float shadowMapSizeInverse, float lightSizeUV, float darkness, float frustumEdgeFalloff, vec2 lightSizeUVCorrection, float depthCorrection, float penumbraDarkness)
+        {
+            return computeShadowWithCSMPCSS(layer, vPositionFromLight, depthMetric, depthSampler, shadowSampler, shadowMapSizeInverse, lightSizeUV, darkness, frustumEdgeFalloff, 16, 32, PoissonSamplers32, lightSizeUVCorrection, depthCorrection, penumbraDarkness);
+        }
+
+        float computeShadowWithCSMPCSS64(float layer, vec4 vPositionFromLight, float depthMetric, highp sampler2DArray depthSampler, highp sampler2DArrayShadow shadowSampler, float shadowMapSizeInverse, float lightSizeUV, float darkness, float frustumEdgeFalloff, vec2 lightSizeUVCorrection, float depthCorrection, float penumbraDarkness)
+        {
+            return computeShadowWithCSMPCSS(layer, vPositionFromLight, depthMetric, depthSampler, shadowSampler, shadowMapSizeInverse, lightSizeUV, darkness, frustumEdgeFalloff, 32, 64, PoissonSamplers64, lightSizeUVCorrection, depthCorrection, penumbraDarkness);
+        }
     #endif
 #endif

+ 7 - 1
src/Shaders/ShadersInclude/shadowsVertex.fx

@@ -1,5 +1,11 @@
 #ifdef SHADOWS
-	#if defined(SHADOW{X}) && !defined(SHADOWCUBE{X})
+	#if defined(SHADOWCSM{X})
+		vPositionFromCamera{X} = view * worldPos;
+		for (int i = 0; i < SHADOWCSMNUM_CASCADES{X}; i++) {
+			vPositionFromLight{X}[i] = lightMatrix{X}[i] * worldPos;
+			vDepthMetric{X}[i] = ((vPositionFromLight{X}[i].z + light{X}.depthValues.x) / (light{X}.depthValues.y));
+		}
+	#elif defined(SHADOW{X}) && !defined(SHADOWCUBE{X})
 		vPositionFromLight{X} = lightMatrix{X} * worldPos;
 		vDepthMetric{X} = ((vPositionFromLight{X}.z + light{X}.depthValues.x) / (light{X}.depthValues.y));
 	#endif

+ 9 - 0
src/Shaders/shadowMap.fragment.fx

@@ -12,6 +12,10 @@ uniform sampler2D diffuseSampler;
 uniform vec3 biasAndScale;
 uniform vec2 depthValues;
 
+#ifdef DEPTHCLAMP
+varying float z;
+#endif
+
 void main(void)
 {
 #ifdef ALPHATEST
@@ -21,6 +25,11 @@ void main(void)
 
     float depth = vDepthMetric;
 
+#ifdef DEPTHCLAMP
+    depth = clamp(((z + depthValues.x) / (depthValues.y)) + biasAndScale.x, 0.0, 1.0);
+    gl_FragDepth = depth;
+#endif
+
 #ifdef ESM
     depth = clamp(exp(-min(87., biasAndScale.z * depth)), 0., 1.);
 #endif

+ 9 - 0
src/Shaders/shadowMap.vertex.fx

@@ -32,6 +32,10 @@ attribute vec2 uv2;
 #endif
 #endif
 
+#ifdef DEPTHCLAMP
+varying float z;
+#endif
+
 void main(void)
 {
 vec3 positionUpdated = position;
@@ -78,8 +82,13 @@ gl_Position = viewProjection * worldPos;
     gl_Position.z += biasAndScale.x * gl_Position.w;
 #endif
 
+#ifdef DEPTHCLAMP
+    z = gl_Position.z;
+    gl_Position.z = 0.0;
+#else
     // Color Texture Linear bias.
     vDepthMetric = ((gl_Position.z + depthValues.x) / (depthValues.y)) + biasAndScale.x;
+#endif
 
 #ifdef ALPHATEST
     #ifdef UV1