Преглед изворни кода

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

DEV-UNITY-6\Utilisateur пре 6 година
родитељ
комит
ed23a2fef6
66 измењених фајлова са 8332 додато и 1433 уклоњено
  1. 546 157
      Playground/babylon.d.txt
  2. 560 159
      dist/preview release/babylon.d.ts
  3. 2 2
      dist/preview release/babylon.js
  4. 1683 84
      dist/preview release/babylon.max.js
  5. 1 1
      dist/preview release/babylon.max.js.map
  6. 1174 341
      dist/preview release/babylon.module.d.ts
  7. 560 159
      dist/preview release/documentation.d.ts
  8. 8 1
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  9. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.js.map
  10. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  11. 8 1
      dist/preview release/loaders/babylon.glTFFileLoader.js
  12. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.js.map
  13. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  14. 8 1
      dist/preview release/loaders/babylonjs.loaders.js
  15. 1 1
      dist/preview release/loaders/babylonjs.loaders.js.map
  16. 2 2
      dist/preview release/loaders/babylonjs.loaders.min.js
  17. 69 1
      dist/preview release/nodeEditor/babylon.nodeEditor.d.ts
  18. 6 6
      dist/preview release/nodeEditor/babylon.nodeEditor.js
  19. 240 15
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js
  20. 1 1
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map
  21. 157 2
      dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts
  22. 1 1
      dist/preview release/packagesSizeBaseLine.json
  23. 1174 341
      dist/preview release/viewer/babylon.module.d.ts
  24. 49 29
      dist/preview release/viewer/babylon.viewer.js
  25. 2 2
      dist/preview release/viewer/babylon.viewer.max.js
  26. 1 1
      dist/preview release/what's new.md
  27. 8 1
      loaders/src/glTF/2.0/glTFLoader.ts
  28. 10 1
      nodeEditor/src/blockTools.ts
  29. 1 15
      nodeEditor/src/components/diagram/generic/genericNodeModel.tsx
  30. 1 1
      nodeEditor/src/components/diagram/light/lightPropertyTabComponent.tsx
  31. 39 0
      nodeEditor/src/components/diagram/lightInformation/lightInformationNodeFactory.tsx
  32. 44 0
      nodeEditor/src/components/diagram/lightInformation/lightInformationNodeModel.tsx
  33. 56 0
      nodeEditor/src/components/diagram/lightInformation/lightInformationNodeWidget.tsx
  34. 40 0
      nodeEditor/src/components/diagram/lightInformation/lightInformationPropertyTabComponent.tsx
  35. 2 2
      nodeEditor/src/components/nodeList/nodeListComponent.tsx
  36. 7 1
      nodeEditor/src/graphEditor.tsx
  37. 105 0
      src/Engines/Native/nativeShaderProcessor.ts
  38. 5 4
      src/Engines/Processors/shaderCodeNode.ts
  39. 70 46
      src/Engines/engine.ts
  40. 2 1
      src/Engines/index.ts
  41. 1284 0
      src/Engines/nativeEngine.ts
  42. 1 9
      src/Engines/nullEngine.ts
  43. 18 0
      src/Lights/directionalLight.ts
  44. 6 0
      src/Lights/hemisphericLight.ts
  45. 8 0
      src/Lights/light.ts
  46. 10 0
      src/Lights/pointLight.ts
  47. 18 0
      src/Lights/spotLight.ts
  48. 2 1
      src/Materials/Node/Blocks/Vertex/index.ts
  49. 132 0
      src/Materials/Node/Blocks/Vertex/lightInformationBlock.ts
  50. 3 1
      src/Materials/Node/Blocks/index.ts
  51. 66 0
      src/Materials/Node/Blocks/maxBlock.ts
  52. 66 0
      src/Materials/Node/Blocks/minBlock.ts
  53. 1 1
      src/Materials/Node/Blocks/transformBlock.ts
  54. 6 1
      src/Materials/Node/nodeMaterial.ts
  55. 3 0
      src/Materials/Node/nodeMaterialBlock.ts
  56. 1 1
      src/Materials/Textures/internalTexture.ts
  57. 3 3
      src/Materials/Textures/texture.ts
  58. 2 2
      src/Materials/effect.ts
  59. 8 0
      src/Misc/domManagement.ts
  60. 32 14
      src/Misc/environmentTextureTools.ts
  61. 2 2
      src/Misc/fileTools.ts
  62. 1 1
      src/Misc/tools.ts
  63. 5 6
      src/Shaders/ShadersInclude/bumpFragmentFunctions.fx
  64. 2 2
      src/Shaders/ShadersInclude/pbrBRDFFunctions.fx
  65. 1 1
      src/Shaders/ShadersInclude/pbrHelperFunctions.fx
  66. 4 4
      src/Shaders/pbr.fragment.fx

+ 546 - 157
Playground/babylon.d.txt

@@ -278,6 +278,11 @@ declare module BABYLON {
          */
         static IsWindowObjectExist(): boolean;
         /**
+         * Checks if the navigator object exists
+         * @returns true if the navigator object exists
+         */
+        static IsNavigatorAvailable(): boolean;
+        /**
          * Extracts text content from a DOM element hierarchy
          * @param element defines the root element
          * @returns a string
@@ -4731,7 +4736,7 @@ declare module BABYLON {
          * @param offlineProvider offline provider for caching
          * @returns the HTMLImageElement of the loaded image
          */
-        static LoadImage(input: string | ArrayBuffer | Blob, onLoad: (img: HTMLImageElement) => void, onError: (message?: string, exception?: any) => void, offlineProvider: Nullable<IOfflineProvider>): HTMLImageElement;
+        static LoadImage(input: string | ArrayBuffer | ArrayBufferView | Blob, onLoad: (img: HTMLImageElement) => void, onError: (message?: string, exception?: any) => void, offlineProvider: Nullable<IOfflineProvider>): HTMLImageElement;
         /**
          * Loads a file
          * @param fileToLoad defines the file to load
@@ -9778,6 +9783,13 @@ declare module BABYLON {
          */
         abstract transferToEffect(effect: Effect, lightIndex: string): Light;
         /**
+         * Sets the passed Effect "effect" with the Light information.
+         * @param effect The effect to update
+         * @param lightDataUniformName The uniform used to store light data (position or direction)
+         * @returns The light
+         */
+        abstract transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string): Light;
+        /**
          * Returns the string "Light".
          * @returns the class name
          */
@@ -14321,6 +14333,7 @@ declare module BABYLON {
          * @returns The hemispheric light
          */
         transferToEffect(effect: Effect, lightIndex: string): HemisphericLight;
+        transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string): this;
         /**
          * Computes the world matrix of the node
          * @param force defines if the cache version should be invalidated forcing the world matrix to be created from scratch
@@ -15485,7 +15498,7 @@ declare module BABYLON {
         private _cachedCoordinatesMode;
         /** @hidden */
         protected _initialSamplingMode: number;
-        /** @hidden */
private _buffer: Nullable<string | ArrayBuffer | HTMLImageElement | Blob>;
+        /** @hidden */
private _buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob>;
         private _deleteBuffer;
         protected _format: Nullable<number>;
         private _delayedOnLoad;
@@ -15523,14 +15536,14 @@ declare module BABYLON {
          * @param deleteBuffer define if the buffer we are loading the texture from should be deleted after load
          * @param format define the format of the texture we are trying to load (Engine.TEXTUREFORMAT_RGBA...)
          */
-        constructor(url: Nullable<string>, sceneOrEngine: Nullable<Scene | Engine>, noMipmap?: boolean, invertY?: boolean, samplingMode?: number, onLoad?: Nullable<() => void>, onError?: Nullable<(message?: string, exception?: any) => void>, buffer?: Nullable<string | ArrayBuffer | HTMLImageElement | Blob>, deleteBuffer?: boolean, format?: number);
+        constructor(url: Nullable<string>, sceneOrEngine: Nullable<Scene | Engine>, noMipmap?: boolean, invertY?: boolean, samplingMode?: number, onLoad?: Nullable<() => void>, onError?: Nullable<(message?: string, exception?: any) => void>, buffer?: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob>, deleteBuffer?: boolean, format?: number);
         /**
          * Update the url (and optional buffer) of this texture if url was null during construction.
          * @param url the url of the texture
          * @param buffer the buffer of the texture (defaults to null)
          * @param onLoad callback called when the texture is loaded  (defaults to null)
          */
-        updateURL(url: string, buffer?: Nullable<string | ArrayBuffer | HTMLImageElement | Blob>, onLoad?: () => void): void;
+        updateURL(url: string, buffer?: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob>, onLoad?: () => void): void;
         /**
          * Finish the loading sequence of a texture flagged as delayed load.
          * @hidden
@@ -27541,7 +27554,7 @@ declare module BABYLON {
         /** @hidden */
private _invertVScale: boolean;
         /** @hidden */
private _associatedChannel: number;
         /** @hidden */
private _dataSource: number;
-        /** @hidden */
private _buffer: Nullable<string | ArrayBuffer | HTMLImageElement | Blob>;
+        /** @hidden */
private _buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob>;
         /** @hidden */
private _bufferView: Nullable<ArrayBufferView>;
         /** @hidden */
private _bufferViewArray: Nullable<ArrayBufferView[]>;
         /** @hidden */
private _bufferViewArrayArray: Nullable<ArrayBufferView[][]>;
@@ -29548,7 +29561,7 @@ declare module BABYLON {
         /** @hidden */
private _gl: WebGLRenderingContext;
         private _renderingCanvas;
         private _windowIsBackground;
-        private _webGLVersion;
+        protected _webGLVersion: number;
         protected _highPrecisionShadersAllowed: boolean;
         /** @hidden */
protected readonly _shouldUseHighPrecisionShader: boolean;
         /**
@@ -29585,7 +29598,7 @@ declare module BABYLON {
         /** @hidden */
private _caps: EngineCapabilities;
         private _pointerLockRequested;
         private _isStencilEnable;
-        private _colorWrite;
+        protected _colorWrite: boolean;
         private _loadingScreen;
         /** @hidden */
private _drawCalls: PerfCounter;
         private _glVersion;
@@ -29998,6 +30011,11 @@ declare module BABYLON {
         stopRenderLoop(renderFunction?: () => void): void;
         /** @hidden */
private _renderLoop(): void;
         /**
+         * Can be used to override the current requestAnimationFrame requester.
+         * @hidden
+         */
+        protected _queueNewFrame(bindedRenderFunction: any, requester?: any): number;
+        /**
          * Register and execute a render loop. The engine can have more than one render function
          * @param renderFunction defines the function to continuously execute
          */
@@ -30180,6 +30198,7 @@ declare module BABYLON {
          * @returns a new webGL buffer
          */
         createIndexBuffer(indices: IndicesArray, updatable?: boolean): DataBuffer;
+        protected _normalizeIndexData(indices: IndicesArray): Uint16Array | Uint32Array;
         /**
          * Bind a webGL buffer to the webGL context
          * @param buffer defines the buffer to bind
@@ -30260,6 +30279,7 @@ declare module BABYLON {
          */
         releaseVertexArrayObject(vao: WebGLVertexArrayObject): void;
         /** @hidden */
private _releaseBuffer(buffer: DataBuffer): boolean;
+        protected _deleteBuffer(buffer: DataBuffer): void;
         /**
          * Creates a webGL buffer to use with instanciation
          * @param capacity defines the size of the buffer
@@ -30338,6 +30358,7 @@ declare module BABYLON {
          * @returns the new Effect
          */
         createEffect(baseName: any, attributesNamesOrOptions: string[] | EffectCreationOptions, uniformsNamesOrEngine: string[] | Engine, samplers?: string[], defines?: string, fallbacks?: EffectFallbacks, onCompiled?: Nullable<(effect: Effect) => void>, onError?: Nullable<(effect: Effect, errors: string) => void>, indexParameters?: any): Effect;
+        protected static _concatenateShader(source: string, defines: Nullable<string>, shaderVersion?: string): string;
         private _compileShader;
         private _compileRawShader;
         /**
@@ -30365,7 +30386,7 @@ declare module BABYLON {
          * Creates a new pipeline context
          * @returns the new pipeline
          */
-        createPipelineContext(): WebGLPipelineContext;
+        createPipelineContext(): IPipelineContext;
         private _createShaderProgram;
         private _finalizePipelineContext;
         /** @hidden */
private _preparePipelineContext(pipelineContext: IPipelineContext, vertexSourceCode: string, fragmentSourceCode: string, createAsRaw: boolean, rebuildRebind: any, defines: Nullable<string>, transformFeedbackVaryings: Nullable<string[]>): void;
@@ -30649,7 +30670,7 @@ declare module BABYLON {
          * @param excludeLoaders array of texture loaders that should be excluded when picking a loader for the texture (default: empty array)
          * @returns a InternalTexture for assignment back into BABYLON.Texture
          */
-        createTexture(urlArg: Nullable<string>, noMipmap: boolean, invertY: boolean, scene: Nullable<Scene>, samplingMode?: number, onLoad?: Nullable<() => void>, onError?: Nullable<(message: string, exception: any) => void>, buffer?: Nullable<string | ArrayBuffer | HTMLImageElement | Blob>, fallback?: Nullable<InternalTexture>, format?: Nullable<number>, forcedExtension?: Nullable<string>, excludeLoaders?: Array<IInternalTextureLoader>): InternalTexture;
+        createTexture(urlArg: Nullable<string>, noMipmap: boolean, invertY: boolean, scene: Nullable<Scene>, samplingMode?: number, onLoad?: Nullable<() => void>, onError?: Nullable<(message: string, exception: any) => void>, buffer?: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob>, fallback?: Nullable<InternalTexture>, format?: Nullable<number>, forcedExtension?: Nullable<string>, excludeLoaders?: Array<IInternalTextureLoader>): InternalTexture;
         /**
          * @hidden
          * Rescales a texture
@@ -30762,13 +30783,16 @@ declare module BABYLON {
         /**
          * @hidden
          */
private _setCubeMapTextureParams(loadMipmap: boolean): void;
-        private _prepareWebGLTextureContinuation;
+        protected _prepareWebGLTextureContinuation(texture: InternalTexture, scene: Nullable<Scene>, noMipmap: boolean, isCompressed: boolean, samplingMode: number): void;
         private _prepareWebGLTexture;
         /** @hidden */
private _convertRGBtoRGBATextureData(rgbData: any, width: number, height: number, textureType: number): ArrayBufferView;
         /** @hidden */
private _releaseFramebufferObjects(texture: InternalTexture): void;
         /** @hidden */
private _releaseTexture(texture: InternalTexture): void;
-        private setProgram;
-        private _boundUniforms;
+        protected _deleteTexture(texture: Nullable<WebGLTexture>): void;
+        protected _setProgram(program: WebGLProgram): void;
+        protected _boundUniforms: {
+            [key: number]: WebGLUniformLocation;
+        };
         /**
          * Binds an effect to the webGL context
          * @param effect defines the effect to bind
@@ -30809,7 +30833,7 @@ declare module BABYLON {
         setDepthStencilTexture(channel: number, uniform: Nullable<WebGLUniformLocation>, texture: Nullable<RenderTargetTexture>): void;
         private _bindSamplerUniformToChannel;
         private _getTextureWrapMode;
-        private _setTexture;
+        protected _setTexture(channel: number, texture: Nullable<BaseTexture>, isPartOfTextureArray?: boolean, depthStencilTexture?: boolean): boolean;
         /**
          * Sets an array of texture to the webGL context
          * @param channel defines the channel where the texture array must be set
@@ -42744,7 +42768,7 @@ declare module BABYLON {
          */
         updateDynamicVertexBuffer(vertexBuffer: WebGLBuffer, vertices: FloatArray, byteOffset?: number, byteLength?: number): void;
private _bindTextureDirectly(target: number, texture: InternalTexture): boolean;
         /** @hidden */
private _bindTexture(channel: number, texture: InternalTexture): void;
-        /** @hidden */
private _releaseBuffer(buffer: DataBuffer): boolean;
+        protected _deleteBuffer(buffer: WebGLBuffer): void;
         releaseEffects(): void;
         displayLoadingUI(): void;
         hideLoadingUI(): void;
@@ -43052,6 +43076,412 @@ declare module BABYLON {
         }
 }
 declare module BABYLON {
+    /** @hidden */
+    export var rgbdEncodePixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /** @hidden */
+    export var rgbdDecodePixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /**
+     * Raw texture data and descriptor sufficient for WebGL texture upload
+     */
+    export interface EnvironmentTextureInfo {
+        /**
+         * Version of the environment map
+         */
+        version: number;
+        /**
+         * Width of image
+         */
+        width: number;
+        /**
+         * Irradiance information stored in the file.
+         */
+        irradiance: any;
+        /**
+         * Specular information stored in the file.
+         */
+        specular: any;
+    }
+    /**
+     * Defines One Image in the file. It requires only the position in the file
+     * as well as the length.
+     */
+    interface BufferImageData {
+        /**
+         * Length of the image data.
+         */
+        length: number;
+        /**
+         * Position of the data from the null terminator delimiting the end of the JSON.
+         */
+        position: number;
+    }
+    /**
+     * Defines the specular data enclosed in the file.
+     * This corresponds to the version 1 of the data.
+     */
+    export interface EnvironmentTextureSpecularInfoV1 {
+        /**
+         * Defines where the specular Payload is located. It is a runtime value only not stored in the file.
+         */
+        specularDataPosition?: number;
+        /**
+         * This contains all the images data needed to reconstruct the cubemap.
+         */
+        mipmaps: Array<BufferImageData>;
+        /**
+         * Defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness.
+         */
+        lodGenerationScale: number;
+    }
+    /**
+     * Sets of helpers addressing the serialization and deserialization of environment texture
+     * stored in a BabylonJS env file.
+     * Those files are usually stored as .env files.
+     */
+    export class EnvironmentTextureTools {
+        /**
+         * Magic number identifying the env file.
+         */
+        private static _MagicBytes;
+        /**
+         * Gets the environment info from an env file.
+         * @param data The array buffer containing the .env bytes.
+         * @returns the environment file info (the json header) if successfully parsed.
+         */
+        static GetEnvInfo(data: ArrayBuffer): Nullable<EnvironmentTextureInfo>;
+        /**
+         * Creates an environment texture from a loaded cube texture.
+         * @param texture defines the cube texture to convert in env file
+         * @return a promise containing the environment data if succesfull.
+         */
+        static CreateEnvTextureAsync(texture: CubeTexture): Promise<ArrayBuffer>;
+        /**
+         * Creates a JSON representation of the spherical data.
+         * @param texture defines the texture containing the polynomials
+         * @return the JSON representation of the spherical info
+         */
+        private static _CreateEnvTextureIrradiance;
+        /**
+         * Creates the ArrayBufferViews used for initializing environment texture image data.
+         * @param arrayBuffer the underlying ArrayBuffer to which the views refer
+         * @param info parameters that determine what views will be created for accessing the underlying buffer
+         * @return the views described by info providing access to the underlying buffer
+         */
+        static CreateImageDataArrayBufferViews(arrayBuffer: any, info: EnvironmentTextureInfo): Array<Array<ArrayBufferView>>;
+        /**
+         * Uploads the texture info contained in the env file to the GPU.
+         * @param texture defines the internal texture to upload to
+         * @param arrayBuffer defines the buffer cotaining the data to load
+         * @param info defines the texture info retrieved through the GetEnvInfo method
+         * @returns a promise
+         */
+        static UploadEnvLevelsAsync(texture: InternalTexture, arrayBuffer: any, info: EnvironmentTextureInfo): Promise<void>;
+        /**
+         * Uploads the levels of image data to the GPU.
+         * @param texture defines the internal texture to upload to
+         * @param imageData defines the array buffer views of image data [mipmap][face]
+         * @returns a promise
+         */
+        static UploadLevelsAsync(texture: InternalTexture, imageData: ArrayBufferView[][]): Promise<void>;
+        /**
+         * Uploads spherical polynomials information to the texture.
+         * @param texture defines the texture we are trying to upload the information to
+         * @param info defines the environment texture info retrieved through the GetEnvInfo method
+         */
+        static UploadEnvSpherical(texture: InternalTexture, info: EnvironmentTextureInfo): void;
+        /** @hidden */
private static _UpdateRGBDAsync(internalTexture: InternalTexture, data: ArrayBufferView[][], sphericalPolynomial: Nullable<SphericalPolynomial>, lodScale: number, lodOffset: number): Promise<void>;
+    }
+}
+declare module BABYLON {
+    /**
+     * Contains position and normal vectors for a vertex
+     */
+    export class PositionNormalVertex {
+        /** the position of the vertex (defaut: 0,0,0) */
+        position: Vector3;
+        /** the normal of the vertex (defaut: 0,1,0) */
+        normal: Vector3;
+        /**
+         * Creates a PositionNormalVertex
+         * @param position the position of the vertex (defaut: 0,0,0)
+         * @param normal the normal of the vertex (defaut: 0,1,0)
+         */
+        constructor(
+        /** the position of the vertex (defaut: 0,0,0) */
+        position?: Vector3, 
+        /** the normal of the vertex (defaut: 0,1,0) */
+        normal?: Vector3);
+        /**
+         * Clones the PositionNormalVertex
+         * @returns the cloned PositionNormalVertex
+         */
+        clone(): PositionNormalVertex;
+    }
+    /**
+     * Contains position, normal and uv vectors for a vertex
+     */
+    export class PositionNormalTextureVertex {
+        /** the position of the vertex (defaut: 0,0,0) */
+        position: Vector3;
+        /** the normal of the vertex (defaut: 0,1,0) */
+        normal: Vector3;
+        /** the uv of the vertex (default: 0,0) */
+        uv: Vector2;
+        /**
+         * Creates a PositionNormalTextureVertex
+         * @param position the position of the vertex (defaut: 0,0,0)
+         * @param normal the normal of the vertex (defaut: 0,1,0)
+         * @param uv the uv of the vertex (default: 0,0)
+         */
+        constructor(
+        /** the position of the vertex (defaut: 0,0,0) */
+        position?: Vector3, 
+        /** the normal of the vertex (defaut: 0,1,0) */
+        normal?: Vector3, 
+        /** the uv of the vertex (default: 0,0) */
+        uv?: Vector2);
+        /**
+         * Clones the PositionNormalTextureVertex
+         * @returns the cloned PositionNormalTextureVertex
+         */
+        clone(): PositionNormalTextureVertex;
+    }
+}
+declare module BABYLON {
+    /** @hidden */
+    export class NativeShaderProcessor extends WebGL2ShaderProcessor {
+        private _genericAttributeLocation;
+        private _varyingLocationCount;
+        private _varyingLocationMap;
+        private _replacements;
+        private _textureCount;
+        private _uniforms;
+        lineProcessor(line: string): string;
+        attributeProcessor(attribute: string): string;
+        varyingProcessor(varying: string, isFragment: boolean): string;
+        uniformProcessor(uniform: string): string;
+        preProcessor(code: string, defines: string[], isFragment: boolean): string;
+        postProcessor(code: string, defines: string[], isFragment: boolean): string;
+    }
+}
+declare module BABYLON {
+    /**
+     * Container for accessors for natively-stored mesh data buffers.
+     */
+    class NativeDataBuffer extends DataBuffer {
+        /**
+         * Accessor value used to identify/retrieve a natively-stored index buffer.
+         */
+        nativeIndexBuffer?: any;
+        /**
+         * Accessor value used to identify/retrieve a natively-stored vertex buffer.
+         */
+        nativeVertexBuffer?: any;
+    }
+    /** @hidden */
+    export class NativeEngine extends Engine {
+        private readonly _native;
+        getHardwareScalingLevel(): number;
+        constructor();
+        /**
+         * Can be used to override the current requestAnimationFrame requester.
+         * @hidden
+         */
+        protected _queueNewFrame(bindedRenderFunction: any, requester: any): number;
+        clear(color: Color4, backBuffer: boolean, depth: boolean, stencil?: boolean): void;
+        createIndexBuffer(indices: IndicesArray): NativeDataBuffer;
+        createVertexBuffer(data: DataArray): NativeDataBuffer;
+        recordVertexArrayObject(vertexBuffers: {
+            [key: string]: VertexBuffer;
+        }, indexBuffer: Nullable<NativeDataBuffer>, effect: Effect): WebGLVertexArrayObject;
+        bindVertexArrayObject(vertexArray: WebGLVertexArrayObject): void;
+        releaseVertexArrayObject(vertexArray: WebGLVertexArrayObject): void;
+        getAttributes(pipelineContext: IPipelineContext, attributesNames: string[]): number[];
+        /**
+         * Draw a list of indexed primitives
+         * @param fillMode defines the primitive to use
+         * @param indexStart defines the starting index
+         * @param indexCount defines the number of index to draw
+         * @param instancesCount defines the number of instances to draw (if instanciation is enabled)
+         */
+        drawElementsType(fillMode: number, indexStart: number, indexCount: number, instancesCount?: number): void;
+        /**
+         * Draw a list of unindexed primitives
+         * @param fillMode defines the primitive to use
+         * @param verticesStart defines the index of first vertex to draw
+         * @param verticesCount defines the count of vertices to draw
+         * @param instancesCount defines the number of instances to draw (if instanciation is enabled)
+         */
+        drawArraysType(fillMode: number, verticesStart: number, verticesCount: number, instancesCount?: number): void;
+        createPipelineContext(): IPipelineContext;
private _preparePipelineContext(pipelineContext: IPipelineContext, vertexSourceCode: string, fragmentSourceCode: string, createAsRaw: boolean, rebuildRebind: any, defines: Nullable<string>, transformFeedbackVaryings: Nullable<string[]>): void;
+        /** @hidden */
private _isRenderingStateCompiled(pipelineContext: IPipelineContext): boolean;
+        /** @hidden */
private _executeWhenRenderingStateIsCompiled(pipelineContext: IPipelineContext, action: () => void): void;
+        createRawShaderProgram(pipelineContext: IPipelineContext, vertexCode: string, fragmentCode: string, context?: WebGLRenderingContext, transformFeedbackVaryings?: Nullable<string[]>): any;
+        createShaderProgram(pipelineContext: IPipelineContext, vertexCode: string, fragmentCode: string, defines: Nullable<string>, context?: WebGLRenderingContext, transformFeedbackVaryings?: Nullable<string[]>): any;
+        protected _setProgram(program: WebGLProgram): void;
private _releaseEffect(effect: Effect): void;
private _deletePipelineContext(pipelineContext: IPipelineContext): void;
+        getUniforms(pipelineContext: IPipelineContext, uniformsNames: string[]): WebGLUniformLocation[];
+        bindUniformBlock(pipelineContext: IPipelineContext, blockName: string, index: number): void;
+        bindSamplers(effect: Effect): void;
+        setMatrix(uniform: WebGLUniformLocation, matrix: Matrix): void;
+        getRenderWidth(useScreen?: boolean): number;
+        getRenderHeight(useScreen?: boolean): number;
+        setViewport(viewport: Viewport, requiredWidth?: number, requiredHeight?: number): void;
+        setState(culling: boolean, zOffset?: number, force?: boolean, reverseSide?: boolean): void;
+        /**
+         * Set the z offset to apply to current rendering
+         * @param value defines the offset to apply
+         */
+        setZOffset(value: number): void;
+        /**
+         * Gets the current value of the zOffset
+         * @returns the current zOffset state
+         */
+        getZOffset(): number;
+        /**
+         * Enable or disable depth buffering
+         * @param enable defines the state to set
+         */
+        setDepthBuffer(enable: boolean): void;
+        /**
+         * Gets a boolean indicating if depth writing is enabled
+         * @returns the current depth writing state
+         */
+        getDepthWrite(): boolean;
+        /**
+         * Enable or disable depth writing
+         * @param enable defines the state to set
+         */
+        setDepthWrite(enable: boolean): void;
+        /**
+         * Enable or disable color writing
+         * @param enable defines the state to set
+         */
+        setColorWrite(enable: boolean): void;
+        /**
+         * Gets a boolean indicating if color writing is enabled
+         * @returns the current color writing state
+         */
+        getColorWrite(): boolean;
+        /**
+         * Sets alpha constants used by some alpha blending modes
+         * @param r defines the red component
+         * @param g defines the green component
+         * @param b defines the blue component
+         * @param a defines the alpha component
+         */
+        setAlphaConstants(r: number, g: number, b: number, a: number): void;
+        /**
+         * Sets the current alpha mode
+         * @param mode defines the mode to use (one of the BABYLON.Engine.ALPHA_XXX)
+         * @param noDepthWriteChange defines if depth writing state should remains unchanged (false by default)
+         * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered
+         */
+        setAlphaMode(mode: number, noDepthWriteChange?: boolean): void;
+        /**
+         * Gets the current alpha mode
+         * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered
+         * @returns the current alpha mode
+         */
+        getAlphaMode(): number;
+        setIntArray(uniform: WebGLUniformLocation, array: Int32Array): void;
+        setIntArray2(uniform: WebGLUniformLocation, array: Int32Array): void;
+        setIntArray3(uniform: WebGLUniformLocation, array: Int32Array): void;
+        setIntArray4(uniform: WebGLUniformLocation, array: Int32Array): void;
+        setFloatArray(uniform: WebGLUniformLocation, array: Float32Array): void;
+        setFloatArray2(uniform: WebGLUniformLocation, array: Float32Array): void;
+        setFloatArray3(uniform: WebGLUniformLocation, array: Float32Array): void;
+        setFloatArray4(uniform: WebGLUniformLocation, array: Float32Array): void;
+        setArray(uniform: WebGLUniformLocation, array: number[]): void;
+        setArray2(uniform: WebGLUniformLocation, array: number[]): void;
+        setArray3(uniform: WebGLUniformLocation, array: number[]): void;
+        setArray4(uniform: WebGLUniformLocation, array: number[]): void;
+        setMatrices(uniform: WebGLUniformLocation, matrices: Float32Array): void;
+        setMatrix3x3(uniform: WebGLUniformLocation, matrix: Float32Array): void;
+        setMatrix2x2(uniform: WebGLUniformLocation, matrix: Float32Array): void;
+        setFloat(uniform: WebGLUniformLocation, value: number): void;
+        setFloat2(uniform: WebGLUniformLocation, x: number, y: number): void;
+        setFloat3(uniform: WebGLUniformLocation, x: number, y: number, z: number): void;
+        setBool(uniform: WebGLUniformLocation, bool: number): void;
+        setFloat4(uniform: WebGLUniformLocation, x: number, y: number, z: number, w: number): void;
+        setColor3(uniform: WebGLUniformLocation, color3: Color3): void;
+        setColor4(uniform: WebGLUniformLocation, color3: Color3, alpha: number): void;
+        wipeCaches(bruteForce?: boolean): void;
private _createTexture(): WebGLTexture;
+        protected _deleteTexture(texture: Nullable<WebGLTexture>): void;
+        /**
+         * Usually called from BABYLON.Texture.ts.
+         * Passed information to create a WebGLTexture
+         * @param urlArg defines a value which contains one of the following:
+         * * A conventional http URL, e.g. 'http://...' or 'file://...'
+         * * A base64 string of in-line texture data, e.g. 'data:image/jpg;base64,/...'
+         * * An indicator that data being passed using the buffer parameter, e.g. 'data:mytexture.jpg'
+         * @param noMipmap defines a boolean indicating that no mipmaps shall be generated.  Ignored for compressed textures.  They must be in the file
+         * @param invertY when true, image is flipped when loaded.  You probably want true. Ignored for compressed textures.  Must be flipped in the file
+         * @param scene needed for loading to the correct scene
+         * @param samplingMode mode with should be used sample / access the texture (Default: BABYLON.Texture.TRILINEAR_SAMPLINGMODE)
+         * @param onLoad optional callback to be called upon successful completion
+         * @param onError optional callback to be called upon failure
+         * @param buffer a source of a file previously fetched as either a base64 string, an ArrayBuffer (compressed or image format), or a Blob
+         * @param fallback an internal argument in case the function must be called again, due to etc1 not having alpha capabilities
+         * @param format internal format.  Default: RGB when extension is '.jpg' else RGBA.  Ignored for compressed textures
+         * @param forcedExtension defines the extension to use to pick the right loader
+         * @returns a InternalTexture for assignment back into BABYLON.Texture
+         */
+        createTexture(urlArg: Nullable<string>, noMipmap: boolean, invertY: boolean, scene: Nullable<Scene>, samplingMode?: number, onLoad?: Nullable<() => void>, onError?: Nullable<(message: string, exception: any) => void>, buffer?: Nullable<string | ArrayBuffer | Blob>, fallback?: Nullable<InternalTexture>, format?: Nullable<number>, forcedExtension?: Nullable<string>): InternalTexture;
+        /**
+         * Creates a cube texture
+         * @param rootUrl defines the url where the files to load is located
+         * @param scene defines the current scene
+         * @param files defines the list of files to load (1 per face)
+         * @param noMipmap defines a boolean indicating that no mipmaps shall be generated (false by default)
+         * @param onLoad defines an optional callback raised when the texture is loaded
+         * @param onError defines an optional callback raised if there is an issue to load the texture
+         * @param format defines the format of the data
+         * @param forcedExtension defines the extension to use to pick the right loader
+         * @param createPolynomials if a polynomial sphere should be created for the cube texture
+         * @param lodScale defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness
+         * @param lodOffset defines the offset applied to environment texture. This manages first LOD level used for IBL according to the roughness
+         * @param fallback defines texture to use while falling back when (compressed) texture file not found.
+         * @returns the cube texture as an InternalTexture
+         */
+        createCubeTexture(rootUrl: string, scene: Nullable<Scene>, files: Nullable<string[]>, noMipmap?: boolean, onLoad?: Nullable<(data?: any) => void>, onError?: Nullable<(message?: string, exception?: any) => void>, format?: number, forcedExtension?: any, createPolynomials?: boolean, lodScale?: number, lodOffset?: number, fallback?: Nullable<InternalTexture>): InternalTexture;
+        private _getSamplingFilter;
+        createRenderTargetTexture(size: any, options: boolean | RenderTargetCreationOptions): InternalTexture;
+        updateTextureSamplingMode(samplingMode: number, texture: InternalTexture): void;
+        bindFramebuffer(texture: InternalTexture, faceIndex?: number, requiredWidth?: number, requiredHeight?: number, forceFullscreenViewport?: boolean): void;
+        unBindFramebuffer(texture: InternalTexture, disableGenerateMipMaps?: boolean, onBeforeUnbind?: () => void): void;
+        createDynamicVertexBuffer(data: DataArray): DataBuffer;
+        updateDynamicIndexBuffer(indexBuffer: DataBuffer, indices: IndicesArray, offset?: number): void;
+        /**
+         * Updates a dynamic vertex buffer.
+         * @param vertexBuffer the vertex buffer to update
+         * @param data the data used to update the vertex buffer
+         * @param byteOffset the byte offset of the data (optional)
+         * @param byteLength the byte length of the data (optional)
+         */
+        updateDynamicVertexBuffer(vertexBuffer: DataBuffer, data: DataArray, byteOffset?: number, byteLength?: number): void;
+        protected _setTexture(channel: number, texture: Nullable<BaseTexture>, isPartOfTextureArray?: boolean, depthStencilTexture?: boolean): boolean;
+        private _updateAnisotropicLevel;
+        private _getAddressMode;
+        /** @hidden */
private _bindTexture(channel: number, texture: InternalTexture): void;
+        protected _deleteBuffer(buffer: NativeDataBuffer): void;
+        releaseEffects(): void;
+        /** @hidden */
private _uploadCompressedDataToTextureDirectly(texture: InternalTexture, internalFormat: number, width: number, height: number, data: ArrayBufferView, faceIndex?: number, lod?: number): void;
+        /** @hidden */
private _uploadDataToTextureDirectly(texture: InternalTexture, imageData: ArrayBufferView, faceIndex?: number, lod?: number): void;
+        /** @hidden */
private _uploadArrayBufferViewToTexture(texture: InternalTexture, imageData: ArrayBufferView, faceIndex?: number, lod?: number): void;
+        /** @hidden */
private _uploadImageToTexture(texture: InternalTexture, image: HTMLImageElement, faceIndex?: number, lod?: number): void;
+    }
+}
+declare module BABYLON {
     /**
      * Gather the list of clipboard event types as constants.
      */
@@ -43698,6 +44128,7 @@ declare module BABYLON {
          * @returns The directional light
          */
         transferToEffect(effect: Effect, lightIndex: string): DirectionalLight;
+        transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string): Light;
         /**
          * Gets the minZ used for shadow according to both the scene and the light.
          *
@@ -43881,6 +44312,7 @@ declare module BABYLON {
          * @returns The spot light
          */
         transferToEffect(effect: Effect, lightIndex: string): SpotLight;
+        transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string): this;
         /**
          * Disposes the light and the associated resources.
          */
@@ -44679,13 +45111,6 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
-    /** @hidden */
-    export var rgbdDecodePixelShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module BABYLON {
     /**
      * Class used to host texture specific utilities
      */
@@ -46836,87 +47261,6 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
-    /** @hidden */
-    export var rgbdEncodePixelShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module BABYLON {
-    /**
-     * Raw texture data and descriptor sufficient for WebGL texture upload
-     */
-    export interface EnvironmentTextureInfo {
-        /**
-         * Version of the environment map
-         */
-        version: number;
-        /**
-         * Width of image
-         */
-        width: number;
-        /**
-         * Irradiance information stored in the file.
-         */
-        irradiance: any;
-        /**
-         * Specular information stored in the file.
-         */
-        specular: any;
-    }
-    /**
-     * Sets of helpers addressing the serialization and deserialization of environment texture
-     * stored in a BabylonJS env file.
-     * Those files are usually stored as .env files.
-     */
-    export class EnvironmentTextureTools {
-        /**
-         * Magic number identifying the env file.
-         */
-        private static _MagicBytes;
-        /**
-         * Gets the environment info from an env file.
-         * @param data The array buffer containing the .env bytes.
-         * @returns the environment file info (the json header) if successfully parsed.
-         */
-        static GetEnvInfo(data: ArrayBuffer): Nullable<EnvironmentTextureInfo>;
-        /**
-         * Creates an environment texture from a loaded cube texture.
-         * @param texture defines the cube texture to convert in env file
-         * @return a promise containing the environment data if succesfull.
-         */
-        static CreateEnvTextureAsync(texture: CubeTexture): Promise<ArrayBuffer>;
-        /**
-         * Creates a JSON representation of the spherical data.
-         * @param texture defines the texture containing the polynomials
-         * @return the JSON representation of the spherical info
-         */
-        private static _CreateEnvTextureIrradiance;
-        /**
-         * Uploads the texture info contained in the env file to the GPU.
-         * @param texture defines the internal texture to upload to
-         * @param arrayBuffer defines the buffer cotaining the data to load
-         * @param info defines the texture info retrieved through the GetEnvInfo method
-         * @returns a promise
-         */
-        static UploadEnvLevelsAsync(texture: InternalTexture, arrayBuffer: any, info: EnvironmentTextureInfo): Promise<void>;
-        /**
-         * Uploads the levels of image data to the GPU.
-         * @param texture defines the internal texture to upload to
-         * @param imageData defines the array buffer views of image data [mipmap][face]
-         * @returns a promise
-         */
-        static UploadLevelsAsync(texture: InternalTexture, imageData: ArrayBufferView[][]): Promise<void>;
-        /**
-         * Uploads spherical polynomials information to the texture.
-         * @param texture defines the texture we are trying to upload the information to
-         * @param info defines the environment texture info retrieved through the GetEnvInfo method
-         */
-        static UploadEnvSpherical(texture: InternalTexture, info: EnvironmentTextureInfo): void;
-        /** @hidden */
private static _UpdateRGBDAsync(internalTexture: InternalTexture, data: ArrayBufferView[][], sphericalPolynomial: Nullable<SphericalPolynomial>, lodScale: number, lodOffset: number): Promise<void>;
-    }
-}
-declare module BABYLON {
     /**
      * Implementation of the ENV Texture Loader.
      * @hidden
@@ -47226,61 +47570,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Contains position and normal vectors for a vertex
-     */
-    export class PositionNormalVertex {
-        /** the position of the vertex (defaut: 0,0,0) */
-        position: Vector3;
-        /** the normal of the vertex (defaut: 0,1,0) */
-        normal: Vector3;
-        /**
-         * Creates a PositionNormalVertex
-         * @param position the position of the vertex (defaut: 0,0,0)
-         * @param normal the normal of the vertex (defaut: 0,1,0)
-         */
-        constructor(
-        /** the position of the vertex (defaut: 0,0,0) */
-        position?: Vector3, 
-        /** the normal of the vertex (defaut: 0,1,0) */
-        normal?: Vector3);
-        /**
-         * Clones the PositionNormalVertex
-         * @returns the cloned PositionNormalVertex
-         */
-        clone(): PositionNormalVertex;
-    }
-    /**
-     * Contains position, normal and uv vectors for a vertex
-     */
-    export class PositionNormalTextureVertex {
-        /** the position of the vertex (defaut: 0,0,0) */
-        position: Vector3;
-        /** the normal of the vertex (defaut: 0,1,0) */
-        normal: Vector3;
-        /** the uv of the vertex (default: 0,0) */
-        uv: Vector2;
-        /**
-         * Creates a PositionNormalTextureVertex
-         * @param position the position of the vertex (defaut: 0,0,0)
-         * @param normal the normal of the vertex (defaut: 0,1,0)
-         * @param uv the uv of the vertex (default: 0,0)
-         */
-        constructor(
-        /** the position of the vertex (defaut: 0,0,0) */
-        position?: Vector3, 
-        /** the normal of the vertex (defaut: 0,1,0) */
-        normal?: Vector3, 
-        /** the uv of the vertex (default: 0,0) */
-        uv?: Vector2);
-        /**
-         * Clones the PositionNormalTextureVertex
-         * @returns the cloned PositionNormalTextureVertex
-         */
-        clone(): PositionNormalTextureVertex;
-    }
-}
-declare module BABYLON {
-    /**
      * Display a 360/180 degree video on an approximately spherical surface, useful for VR applications or skyboxes.
      * As a subclass of TransformNode, this allow parenting to the camera or multiple videos with different locations in the scene.
      * This class achieves its effect with a VideoTexture and a correctly configured BackgroundMaterial on an inverted sphere.
@@ -49012,6 +49301,7 @@ declare module BABYLON {
          * @returns The point light
          */
         transferToEffect(effect: Effect, lightIndex: string): PointLight;
+        transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string): this;
         /**
          * Prepares the list of defines specific to the light type.
          * @param defines the list of defines
@@ -51676,6 +51966,7 @@ declare module BABYLON {
         /** @hidden */
private _codeVariableName: string;
         /** @hidden */
private _inputs: NodeMaterialConnectionPoint[];
         /** @hidden */
private _outputs: NodeMaterialConnectionPoint[];
+        /** @hidden */
private _preparationId: number;
         /**
          * Gets or sets the name of the block
          */
@@ -52262,6 +52553,44 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Block used to get data information from a light
+     */
+    export class LightInformationBlock extends NodeMaterialBlock {
+        private _lightDataDefineName;
+        private _lightColorDefineName;
+        /**
+         * Gets or sets the light associated with this block
+         */
+        light: Nullable<Light>;
+        /**
+         * Creates a new LightInformationBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the world position input component
+         */
+        readonly worldPosition: NodeMaterialConnectionPoint;
+        /**
+         * Gets the direction output component
+         */
+        readonly direction: NodeMaterialConnectionPoint;
+        /**
+         * Gets the direction output component
+         */
+        readonly color: NodeMaterialConnectionPoint;
+        bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh): void;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+        serialize(): any;
private _deserialize(serializationObject: any, scene: Scene, rootUrl: string): void;
+    }
+}
+declare module BABYLON {
+    /**
      * Block used to add an alpha test in the fragment shader
      */
     export class AlphaTestBlock extends NodeMaterialBlock {
@@ -53127,6 +53456,66 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Block used to get the max of 2 values
+     */
+    export class MaxBlock extends NodeMaterialBlock {
+        /**
+         * Creates a new MaxBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the left operand input component
+         */
+        readonly left: NodeMaterialConnectionPoint;
+        /**
+         * Gets the right operand input component
+         */
+        readonly right: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
+     * Block used to get the min of 2 values
+     */
+    export class MinBlock extends NodeMaterialBlock {
+        /**
+         * Creates a new MinBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the left operand input component
+         */
+        readonly left: NodeMaterialConnectionPoint;
+        /**
+         * Gets the right operand input component
+         */
+        readonly right: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
      * Effect Render Options
      */
     export interface IEffectRendererOptions {

+ 560 - 159
dist/preview release/babylon.d.ts

@@ -279,6 +279,11 @@ declare module BABYLON {
          */
         static IsWindowObjectExist(): boolean;
         /**
+         * Checks if the navigator object exists
+         * @returns true if the navigator object exists
+         */
+        static IsNavigatorAvailable(): boolean;
+        /**
          * Extracts text content from a DOM element hierarchy
          * @param element defines the root element
          * @returns a string
@@ -4739,7 +4744,7 @@ declare module BABYLON {
          * @param offlineProvider offline provider for caching
          * @returns the HTMLImageElement of the loaded image
          */
-        static LoadImage(input: string | ArrayBuffer | Blob, onLoad: (img: HTMLImageElement) => void, onError: (message?: string, exception?: any) => void, offlineProvider: Nullable<IOfflineProvider>): HTMLImageElement;
+        static LoadImage(input: string | ArrayBuffer | ArrayBufferView | Blob, onLoad: (img: HTMLImageElement) => void, onError: (message?: string, exception?: any) => void, offlineProvider: Nullable<IOfflineProvider>): HTMLImageElement;
         /**
          * Loads a file
          * @param fileToLoad defines the file to load
@@ -9856,6 +9861,13 @@ declare module BABYLON {
          */
         abstract transferToEffect(effect: Effect, lightIndex: string): Light;
         /**
+         * Sets the passed Effect "effect" with the Light information.
+         * @param effect The effect to update
+         * @param lightDataUniformName The uniform used to store light data (position or direction)
+         * @returns The light
+         */
+        abstract transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string): Light;
+        /**
          * Returns the string "Light".
          * @returns the class name
          */
@@ -14482,6 +14494,7 @@ declare module BABYLON {
          * @returns The hemispheric light
          */
         transferToEffect(effect: Effect, lightIndex: string): HemisphericLight;
+        transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string): this;
         /**
          * Computes the world matrix of the node
          * @param force defines if the cache version should be invalidated forcing the world matrix to be created from scratch
@@ -15685,7 +15698,7 @@ declare module BABYLON {
         /** @hidden */
         protected _initialSamplingMode: number;
         /** @hidden */
-        _buffer: Nullable<string | ArrayBuffer | HTMLImageElement | Blob>;
+        _buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob>;
         private _deleteBuffer;
         protected _format: Nullable<number>;
         private _delayedOnLoad;
@@ -15723,14 +15736,14 @@ declare module BABYLON {
          * @param deleteBuffer define if the buffer we are loading the texture from should be deleted after load
          * @param format define the format of the texture we are trying to load (Engine.TEXTUREFORMAT_RGBA...)
          */
-        constructor(url: Nullable<string>, sceneOrEngine: Nullable<Scene | Engine>, noMipmap?: boolean, invertY?: boolean, samplingMode?: number, onLoad?: Nullable<() => void>, onError?: Nullable<(message?: string, exception?: any) => void>, buffer?: Nullable<string | ArrayBuffer | HTMLImageElement | Blob>, deleteBuffer?: boolean, format?: number);
+        constructor(url: Nullable<string>, sceneOrEngine: Nullable<Scene | Engine>, noMipmap?: boolean, invertY?: boolean, samplingMode?: number, onLoad?: Nullable<() => void>, onError?: Nullable<(message?: string, exception?: any) => void>, buffer?: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob>, deleteBuffer?: boolean, format?: number);
         /**
          * Update the url (and optional buffer) of this texture if url was null during construction.
          * @param url the url of the texture
          * @param buffer the buffer of the texture (defaults to null)
          * @param onLoad callback called when the texture is loaded  (defaults to null)
          */
-        updateURL(url: string, buffer?: Nullable<string | ArrayBuffer | HTMLImageElement | Blob>, onLoad?: () => void): void;
+        updateURL(url: string, buffer?: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob>, onLoad?: () => void): void;
         /**
          * Finish the loading sequence of a texture flagged as delayed load.
          * @hidden
@@ -28042,7 +28055,7 @@ declare module BABYLON {
         /** @hidden */
         _dataSource: number;
         /** @hidden */
-        _buffer: Nullable<string | ArrayBuffer | HTMLImageElement | Blob>;
+        _buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob>;
         /** @hidden */
         _bufferView: Nullable<ArrayBufferView>;
         /** @hidden */
@@ -30109,7 +30122,7 @@ declare module BABYLON {
         _gl: WebGLRenderingContext;
         private _renderingCanvas;
         private _windowIsBackground;
-        private _webGLVersion;
+        protected _webGLVersion: number;
         protected _highPrecisionShadersAllowed: boolean;
         /** @hidden */
         readonly _shouldUseHighPrecisionShader: boolean;
@@ -30150,7 +30163,7 @@ declare module BABYLON {
         _caps: EngineCapabilities;
         private _pointerLockRequested;
         private _isStencilEnable;
-        private _colorWrite;
+        protected _colorWrite: boolean;
         private _loadingScreen;
         /** @hidden */
         _drawCalls: PerfCounter;
@@ -30578,6 +30591,11 @@ declare module BABYLON {
         /** @hidden */
         _renderLoop(): void;
         /**
+         * Can be used to override the current requestAnimationFrame requester.
+         * @hidden
+         */
+        protected _queueNewFrame(bindedRenderFunction: any, requester?: any): number;
+        /**
          * Register and execute a render loop. The engine can have more than one render function
          * @param renderFunction defines the function to continuously execute
          */
@@ -30762,6 +30780,7 @@ declare module BABYLON {
          * @returns a new webGL buffer
          */
         createIndexBuffer(indices: IndicesArray, updatable?: boolean): DataBuffer;
+        protected _normalizeIndexData(indices: IndicesArray): Uint16Array | Uint32Array;
         /**
          * Bind a webGL buffer to the webGL context
          * @param buffer defines the buffer to bind
@@ -30843,6 +30862,7 @@ declare module BABYLON {
         releaseVertexArrayObject(vao: WebGLVertexArrayObject): void;
         /** @hidden */
         _releaseBuffer(buffer: DataBuffer): boolean;
+        protected _deleteBuffer(buffer: DataBuffer): void;
         /**
          * Creates a webGL buffer to use with instanciation
          * @param capacity defines the size of the buffer
@@ -30923,6 +30943,7 @@ declare module BABYLON {
          * @returns the new Effect
          */
         createEffect(baseName: any, attributesNamesOrOptions: string[] | EffectCreationOptions, uniformsNamesOrEngine: string[] | Engine, samplers?: string[], defines?: string, fallbacks?: EffectFallbacks, onCompiled?: Nullable<(effect: Effect) => void>, onError?: Nullable<(effect: Effect, errors: string) => void>, indexParameters?: any): Effect;
+        protected static _concatenateShader(source: string, defines: Nullable<string>, shaderVersion?: string): string;
         private _compileShader;
         private _compileRawShader;
         /**
@@ -30950,7 +30971,7 @@ declare module BABYLON {
          * Creates a new pipeline context
          * @returns the new pipeline
          */
-        createPipelineContext(): WebGLPipelineContext;
+        createPipelineContext(): IPipelineContext;
         private _createShaderProgram;
         private _finalizePipelineContext;
         /** @hidden */
@@ -31239,7 +31260,7 @@ declare module BABYLON {
          * @param excludeLoaders array of texture loaders that should be excluded when picking a loader for the texture (default: empty array)
          * @returns a InternalTexture for assignment back into BABYLON.Texture
          */
-        createTexture(urlArg: Nullable<string>, noMipmap: boolean, invertY: boolean, scene: Nullable<Scene>, samplingMode?: number, onLoad?: Nullable<() => void>, onError?: Nullable<(message: string, exception: any) => void>, buffer?: Nullable<string | ArrayBuffer | HTMLImageElement | Blob>, fallback?: Nullable<InternalTexture>, format?: Nullable<number>, forcedExtension?: Nullable<string>, excludeLoaders?: Array<IInternalTextureLoader>): InternalTexture;
+        createTexture(urlArg: Nullable<string>, noMipmap: boolean, invertY: boolean, scene: Nullable<Scene>, samplingMode?: number, onLoad?: Nullable<() => void>, onError?: Nullable<(message: string, exception: any) => void>, buffer?: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob>, fallback?: Nullable<InternalTexture>, format?: Nullable<number>, forcedExtension?: Nullable<string>, excludeLoaders?: Array<IInternalTextureLoader>): InternalTexture;
         /**
          * @hidden
          * Rescales a texture
@@ -31362,7 +31383,7 @@ declare module BABYLON {
          * @hidden
          */
         _setCubeMapTextureParams(loadMipmap: boolean): void;
-        private _prepareWebGLTextureContinuation;
+        protected _prepareWebGLTextureContinuation(texture: InternalTexture, scene: Nullable<Scene>, noMipmap: boolean, isCompressed: boolean, samplingMode: number): void;
         private _prepareWebGLTexture;
         /** @hidden */
         _convertRGBtoRGBATextureData(rgbData: any, width: number, height: number, textureType: number): ArrayBufferView;
@@ -31370,8 +31391,11 @@ declare module BABYLON {
         _releaseFramebufferObjects(texture: InternalTexture): void;
         /** @hidden */
         _releaseTexture(texture: InternalTexture): void;
-        private setProgram;
-        private _boundUniforms;
+        protected _deleteTexture(texture: Nullable<WebGLTexture>): void;
+        protected _setProgram(program: WebGLProgram): void;
+        protected _boundUniforms: {
+            [key: number]: WebGLUniformLocation;
+        };
         /**
          * Binds an effect to the webGL context
          * @param effect defines the effect to bind
@@ -31414,7 +31438,7 @@ declare module BABYLON {
         setDepthStencilTexture(channel: number, uniform: Nullable<WebGLUniformLocation>, texture: Nullable<RenderTargetTexture>): void;
         private _bindSamplerUniformToChannel;
         private _getTextureWrapMode;
-        private _setTexture;
+        protected _setTexture(channel: number, texture: Nullable<BaseTexture>, isPartOfTextureArray?: boolean, depthStencilTexture?: boolean): boolean;
         /**
          * Sets an array of texture to the webGL context
          * @param channel defines the channel where the texture array must be set
@@ -43482,8 +43506,7 @@ declare module BABYLON {
         _bindTextureDirectly(target: number, texture: InternalTexture): boolean;
         /** @hidden */
         _bindTexture(channel: number, texture: InternalTexture): void;
-        /** @hidden */
-        _releaseBuffer(buffer: DataBuffer): boolean;
+        protected _deleteBuffer(buffer: WebGLBuffer): void;
         releaseEffects(): void;
         displayLoadingUI(): void;
         hideLoadingUI(): void;
@@ -43804,6 +43827,424 @@ declare module BABYLON {
         }
 }
 declare module BABYLON {
+    /** @hidden */
+    export var rgbdEncodePixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /** @hidden */
+    export var rgbdDecodePixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /**
+     * Raw texture data and descriptor sufficient for WebGL texture upload
+     */
+    export interface EnvironmentTextureInfo {
+        /**
+         * Version of the environment map
+         */
+        version: number;
+        /**
+         * Width of image
+         */
+        width: number;
+        /**
+         * Irradiance information stored in the file.
+         */
+        irradiance: any;
+        /**
+         * Specular information stored in the file.
+         */
+        specular: any;
+    }
+    /**
+     * Defines One Image in the file. It requires only the position in the file
+     * as well as the length.
+     */
+    interface BufferImageData {
+        /**
+         * Length of the image data.
+         */
+        length: number;
+        /**
+         * Position of the data from the null terminator delimiting the end of the JSON.
+         */
+        position: number;
+    }
+    /**
+     * Defines the specular data enclosed in the file.
+     * This corresponds to the version 1 of the data.
+     */
+    export interface EnvironmentTextureSpecularInfoV1 {
+        /**
+         * Defines where the specular Payload is located. It is a runtime value only not stored in the file.
+         */
+        specularDataPosition?: number;
+        /**
+         * This contains all the images data needed to reconstruct the cubemap.
+         */
+        mipmaps: Array<BufferImageData>;
+        /**
+         * Defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness.
+         */
+        lodGenerationScale: number;
+    }
+    /**
+     * Sets of helpers addressing the serialization and deserialization of environment texture
+     * stored in a BabylonJS env file.
+     * Those files are usually stored as .env files.
+     */
+    export class EnvironmentTextureTools {
+        /**
+         * Magic number identifying the env file.
+         */
+        private static _MagicBytes;
+        /**
+         * Gets the environment info from an env file.
+         * @param data The array buffer containing the .env bytes.
+         * @returns the environment file info (the json header) if successfully parsed.
+         */
+        static GetEnvInfo(data: ArrayBuffer): Nullable<EnvironmentTextureInfo>;
+        /**
+         * Creates an environment texture from a loaded cube texture.
+         * @param texture defines the cube texture to convert in env file
+         * @return a promise containing the environment data if succesfull.
+         */
+        static CreateEnvTextureAsync(texture: CubeTexture): Promise<ArrayBuffer>;
+        /**
+         * Creates a JSON representation of the spherical data.
+         * @param texture defines the texture containing the polynomials
+         * @return the JSON representation of the spherical info
+         */
+        private static _CreateEnvTextureIrradiance;
+        /**
+         * Creates the ArrayBufferViews used for initializing environment texture image data.
+         * @param arrayBuffer the underlying ArrayBuffer to which the views refer
+         * @param info parameters that determine what views will be created for accessing the underlying buffer
+         * @return the views described by info providing access to the underlying buffer
+         */
+        static CreateImageDataArrayBufferViews(arrayBuffer: any, info: EnvironmentTextureInfo): Array<Array<ArrayBufferView>>;
+        /**
+         * Uploads the texture info contained in the env file to the GPU.
+         * @param texture defines the internal texture to upload to
+         * @param arrayBuffer defines the buffer cotaining the data to load
+         * @param info defines the texture info retrieved through the GetEnvInfo method
+         * @returns a promise
+         */
+        static UploadEnvLevelsAsync(texture: InternalTexture, arrayBuffer: any, info: EnvironmentTextureInfo): Promise<void>;
+        /**
+         * Uploads the levels of image data to the GPU.
+         * @param texture defines the internal texture to upload to
+         * @param imageData defines the array buffer views of image data [mipmap][face]
+         * @returns a promise
+         */
+        static UploadLevelsAsync(texture: InternalTexture, imageData: ArrayBufferView[][]): Promise<void>;
+        /**
+         * Uploads spherical polynomials information to the texture.
+         * @param texture defines the texture we are trying to upload the information to
+         * @param info defines the environment texture info retrieved through the GetEnvInfo method
+         */
+        static UploadEnvSpherical(texture: InternalTexture, info: EnvironmentTextureInfo): void;
+        /** @hidden */
+        static _UpdateRGBDAsync(internalTexture: InternalTexture, data: ArrayBufferView[][], sphericalPolynomial: Nullable<SphericalPolynomial>, lodScale: number, lodOffset: number): Promise<void>;
+    }
+}
+declare module BABYLON {
+    /**
+     * Contains position and normal vectors for a vertex
+     */
+    export class PositionNormalVertex {
+        /** the position of the vertex (defaut: 0,0,0) */
+        position: Vector3;
+        /** the normal of the vertex (defaut: 0,1,0) */
+        normal: Vector3;
+        /**
+         * Creates a PositionNormalVertex
+         * @param position the position of the vertex (defaut: 0,0,0)
+         * @param normal the normal of the vertex (defaut: 0,1,0)
+         */
+        constructor(
+        /** the position of the vertex (defaut: 0,0,0) */
+        position?: Vector3, 
+        /** the normal of the vertex (defaut: 0,1,0) */
+        normal?: Vector3);
+        /**
+         * Clones the PositionNormalVertex
+         * @returns the cloned PositionNormalVertex
+         */
+        clone(): PositionNormalVertex;
+    }
+    /**
+     * Contains position, normal and uv vectors for a vertex
+     */
+    export class PositionNormalTextureVertex {
+        /** the position of the vertex (defaut: 0,0,0) */
+        position: Vector3;
+        /** the normal of the vertex (defaut: 0,1,0) */
+        normal: Vector3;
+        /** the uv of the vertex (default: 0,0) */
+        uv: Vector2;
+        /**
+         * Creates a PositionNormalTextureVertex
+         * @param position the position of the vertex (defaut: 0,0,0)
+         * @param normal the normal of the vertex (defaut: 0,1,0)
+         * @param uv the uv of the vertex (default: 0,0)
+         */
+        constructor(
+        /** the position of the vertex (defaut: 0,0,0) */
+        position?: Vector3, 
+        /** the normal of the vertex (defaut: 0,1,0) */
+        normal?: Vector3, 
+        /** the uv of the vertex (default: 0,0) */
+        uv?: Vector2);
+        /**
+         * Clones the PositionNormalTextureVertex
+         * @returns the cloned PositionNormalTextureVertex
+         */
+        clone(): PositionNormalTextureVertex;
+    }
+}
+declare module BABYLON {
+    /** @hidden */
+    export class NativeShaderProcessor extends WebGL2ShaderProcessor {
+        private _genericAttributeLocation;
+        private _varyingLocationCount;
+        private _varyingLocationMap;
+        private _replacements;
+        private _textureCount;
+        private _uniforms;
+        lineProcessor(line: string): string;
+        attributeProcessor(attribute: string): string;
+        varyingProcessor(varying: string, isFragment: boolean): string;
+        uniformProcessor(uniform: string): string;
+        preProcessor(code: string, defines: string[], isFragment: boolean): string;
+        postProcessor(code: string, defines: string[], isFragment: boolean): string;
+    }
+}
+declare module BABYLON {
+    /**
+     * Container for accessors for natively-stored mesh data buffers.
+     */
+    class NativeDataBuffer extends DataBuffer {
+        /**
+         * Accessor value used to identify/retrieve a natively-stored index buffer.
+         */
+        nativeIndexBuffer?: any;
+        /**
+         * Accessor value used to identify/retrieve a natively-stored vertex buffer.
+         */
+        nativeVertexBuffer?: any;
+    }
+    /** @hidden */
+    export class NativeEngine extends Engine {
+        private readonly _native;
+        getHardwareScalingLevel(): number;
+        constructor();
+        /**
+         * Can be used to override the current requestAnimationFrame requester.
+         * @hidden
+         */
+        protected _queueNewFrame(bindedRenderFunction: any, requester: any): number;
+        clear(color: Color4, backBuffer: boolean, depth: boolean, stencil?: boolean): void;
+        createIndexBuffer(indices: IndicesArray): NativeDataBuffer;
+        createVertexBuffer(data: DataArray): NativeDataBuffer;
+        recordVertexArrayObject(vertexBuffers: {
+            [key: string]: VertexBuffer;
+        }, indexBuffer: Nullable<NativeDataBuffer>, effect: Effect): WebGLVertexArrayObject;
+        bindVertexArrayObject(vertexArray: WebGLVertexArrayObject): void;
+        releaseVertexArrayObject(vertexArray: WebGLVertexArrayObject): void;
+        getAttributes(pipelineContext: IPipelineContext, attributesNames: string[]): number[];
+        /**
+         * Draw a list of indexed primitives
+         * @param fillMode defines the primitive to use
+         * @param indexStart defines the starting index
+         * @param indexCount defines the number of index to draw
+         * @param instancesCount defines the number of instances to draw (if instanciation is enabled)
+         */
+        drawElementsType(fillMode: number, indexStart: number, indexCount: number, instancesCount?: number): void;
+        /**
+         * Draw a list of unindexed primitives
+         * @param fillMode defines the primitive to use
+         * @param verticesStart defines the index of first vertex to draw
+         * @param verticesCount defines the count of vertices to draw
+         * @param instancesCount defines the number of instances to draw (if instanciation is enabled)
+         */
+        drawArraysType(fillMode: number, verticesStart: number, verticesCount: number, instancesCount?: number): void;
+        createPipelineContext(): IPipelineContext;
+        _preparePipelineContext(pipelineContext: IPipelineContext, vertexSourceCode: string, fragmentSourceCode: string, createAsRaw: boolean, rebuildRebind: any, defines: Nullable<string>, transformFeedbackVaryings: Nullable<string[]>): void;
+        /** @hidden */
+        _isRenderingStateCompiled(pipelineContext: IPipelineContext): boolean;
+        /** @hidden */
+        _executeWhenRenderingStateIsCompiled(pipelineContext: IPipelineContext, action: () => void): void;
+        createRawShaderProgram(pipelineContext: IPipelineContext, vertexCode: string, fragmentCode: string, context?: WebGLRenderingContext, transformFeedbackVaryings?: Nullable<string[]>): any;
+        createShaderProgram(pipelineContext: IPipelineContext, vertexCode: string, fragmentCode: string, defines: Nullable<string>, context?: WebGLRenderingContext, transformFeedbackVaryings?: Nullable<string[]>): any;
+        protected _setProgram(program: WebGLProgram): void;
+        _releaseEffect(effect: Effect): void;
+        _deletePipelineContext(pipelineContext: IPipelineContext): void;
+        getUniforms(pipelineContext: IPipelineContext, uniformsNames: string[]): WebGLUniformLocation[];
+        bindUniformBlock(pipelineContext: IPipelineContext, blockName: string, index: number): void;
+        bindSamplers(effect: Effect): void;
+        setMatrix(uniform: WebGLUniformLocation, matrix: Matrix): void;
+        getRenderWidth(useScreen?: boolean): number;
+        getRenderHeight(useScreen?: boolean): number;
+        setViewport(viewport: Viewport, requiredWidth?: number, requiredHeight?: number): void;
+        setState(culling: boolean, zOffset?: number, force?: boolean, reverseSide?: boolean): void;
+        /**
+         * Set the z offset to apply to current rendering
+         * @param value defines the offset to apply
+         */
+        setZOffset(value: number): void;
+        /**
+         * Gets the current value of the zOffset
+         * @returns the current zOffset state
+         */
+        getZOffset(): number;
+        /**
+         * Enable or disable depth buffering
+         * @param enable defines the state to set
+         */
+        setDepthBuffer(enable: boolean): void;
+        /**
+         * Gets a boolean indicating if depth writing is enabled
+         * @returns the current depth writing state
+         */
+        getDepthWrite(): boolean;
+        /**
+         * Enable or disable depth writing
+         * @param enable defines the state to set
+         */
+        setDepthWrite(enable: boolean): void;
+        /**
+         * Enable or disable color writing
+         * @param enable defines the state to set
+         */
+        setColorWrite(enable: boolean): void;
+        /**
+         * Gets a boolean indicating if color writing is enabled
+         * @returns the current color writing state
+         */
+        getColorWrite(): boolean;
+        /**
+         * Sets alpha constants used by some alpha blending modes
+         * @param r defines the red component
+         * @param g defines the green component
+         * @param b defines the blue component
+         * @param a defines the alpha component
+         */
+        setAlphaConstants(r: number, g: number, b: number, a: number): void;
+        /**
+         * Sets the current alpha mode
+         * @param mode defines the mode to use (one of the BABYLON.Engine.ALPHA_XXX)
+         * @param noDepthWriteChange defines if depth writing state should remains unchanged (false by default)
+         * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered
+         */
+        setAlphaMode(mode: number, noDepthWriteChange?: boolean): void;
+        /**
+         * Gets the current alpha mode
+         * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered
+         * @returns the current alpha mode
+         */
+        getAlphaMode(): number;
+        setIntArray(uniform: WebGLUniformLocation, array: Int32Array): void;
+        setIntArray2(uniform: WebGLUniformLocation, array: Int32Array): void;
+        setIntArray3(uniform: WebGLUniformLocation, array: Int32Array): void;
+        setIntArray4(uniform: WebGLUniformLocation, array: Int32Array): void;
+        setFloatArray(uniform: WebGLUniformLocation, array: Float32Array): void;
+        setFloatArray2(uniform: WebGLUniformLocation, array: Float32Array): void;
+        setFloatArray3(uniform: WebGLUniformLocation, array: Float32Array): void;
+        setFloatArray4(uniform: WebGLUniformLocation, array: Float32Array): void;
+        setArray(uniform: WebGLUniformLocation, array: number[]): void;
+        setArray2(uniform: WebGLUniformLocation, array: number[]): void;
+        setArray3(uniform: WebGLUniformLocation, array: number[]): void;
+        setArray4(uniform: WebGLUniformLocation, array: number[]): void;
+        setMatrices(uniform: WebGLUniformLocation, matrices: Float32Array): void;
+        setMatrix3x3(uniform: WebGLUniformLocation, matrix: Float32Array): void;
+        setMatrix2x2(uniform: WebGLUniformLocation, matrix: Float32Array): void;
+        setFloat(uniform: WebGLUniformLocation, value: number): void;
+        setFloat2(uniform: WebGLUniformLocation, x: number, y: number): void;
+        setFloat3(uniform: WebGLUniformLocation, x: number, y: number, z: number): void;
+        setBool(uniform: WebGLUniformLocation, bool: number): void;
+        setFloat4(uniform: WebGLUniformLocation, x: number, y: number, z: number, w: number): void;
+        setColor3(uniform: WebGLUniformLocation, color3: Color3): void;
+        setColor4(uniform: WebGLUniformLocation, color3: Color3, alpha: number): void;
+        wipeCaches(bruteForce?: boolean): void;
+        _createTexture(): WebGLTexture;
+        protected _deleteTexture(texture: Nullable<WebGLTexture>): void;
+        /**
+         * Usually called from BABYLON.Texture.ts.
+         * Passed information to create a WebGLTexture
+         * @param urlArg defines a value which contains one of the following:
+         * * A conventional http URL, e.g. 'http://...' or 'file://...'
+         * * A base64 string of in-line texture data, e.g. 'data:image/jpg;base64,/...'
+         * * An indicator that data being passed using the buffer parameter, e.g. 'data:mytexture.jpg'
+         * @param noMipmap defines a boolean indicating that no mipmaps shall be generated.  Ignored for compressed textures.  They must be in the file
+         * @param invertY when true, image is flipped when loaded.  You probably want true. Ignored for compressed textures.  Must be flipped in the file
+         * @param scene needed for loading to the correct scene
+         * @param samplingMode mode with should be used sample / access the texture (Default: BABYLON.Texture.TRILINEAR_SAMPLINGMODE)
+         * @param onLoad optional callback to be called upon successful completion
+         * @param onError optional callback to be called upon failure
+         * @param buffer a source of a file previously fetched as either a base64 string, an ArrayBuffer (compressed or image format), or a Blob
+         * @param fallback an internal argument in case the function must be called again, due to etc1 not having alpha capabilities
+         * @param format internal format.  Default: RGB when extension is '.jpg' else RGBA.  Ignored for compressed textures
+         * @param forcedExtension defines the extension to use to pick the right loader
+         * @returns a InternalTexture for assignment back into BABYLON.Texture
+         */
+        createTexture(urlArg: Nullable<string>, noMipmap: boolean, invertY: boolean, scene: Nullable<Scene>, samplingMode?: number, onLoad?: Nullable<() => void>, onError?: Nullable<(message: string, exception: any) => void>, buffer?: Nullable<string | ArrayBuffer | Blob>, fallback?: Nullable<InternalTexture>, format?: Nullable<number>, forcedExtension?: Nullable<string>): InternalTexture;
+        /**
+         * Creates a cube texture
+         * @param rootUrl defines the url where the files to load is located
+         * @param scene defines the current scene
+         * @param files defines the list of files to load (1 per face)
+         * @param noMipmap defines a boolean indicating that no mipmaps shall be generated (false by default)
+         * @param onLoad defines an optional callback raised when the texture is loaded
+         * @param onError defines an optional callback raised if there is an issue to load the texture
+         * @param format defines the format of the data
+         * @param forcedExtension defines the extension to use to pick the right loader
+         * @param createPolynomials if a polynomial sphere should be created for the cube texture
+         * @param lodScale defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness
+         * @param lodOffset defines the offset applied to environment texture. This manages first LOD level used for IBL according to the roughness
+         * @param fallback defines texture to use while falling back when (compressed) texture file not found.
+         * @returns the cube texture as an InternalTexture
+         */
+        createCubeTexture(rootUrl: string, scene: Nullable<Scene>, files: Nullable<string[]>, noMipmap?: boolean, onLoad?: Nullable<(data?: any) => void>, onError?: Nullable<(message?: string, exception?: any) => void>, format?: number, forcedExtension?: any, createPolynomials?: boolean, lodScale?: number, lodOffset?: number, fallback?: Nullable<InternalTexture>): InternalTexture;
+        private _getSamplingFilter;
+        createRenderTargetTexture(size: any, options: boolean | RenderTargetCreationOptions): InternalTexture;
+        updateTextureSamplingMode(samplingMode: number, texture: InternalTexture): void;
+        bindFramebuffer(texture: InternalTexture, faceIndex?: number, requiredWidth?: number, requiredHeight?: number, forceFullscreenViewport?: boolean): void;
+        unBindFramebuffer(texture: InternalTexture, disableGenerateMipMaps?: boolean, onBeforeUnbind?: () => void): void;
+        createDynamicVertexBuffer(data: DataArray): DataBuffer;
+        updateDynamicIndexBuffer(indexBuffer: DataBuffer, indices: IndicesArray, offset?: number): void;
+        /**
+         * Updates a dynamic vertex buffer.
+         * @param vertexBuffer the vertex buffer to update
+         * @param data the data used to update the vertex buffer
+         * @param byteOffset the byte offset of the data (optional)
+         * @param byteLength the byte length of the data (optional)
+         */
+        updateDynamicVertexBuffer(vertexBuffer: DataBuffer, data: DataArray, byteOffset?: number, byteLength?: number): void;
+        protected _setTexture(channel: number, texture: Nullable<BaseTexture>, isPartOfTextureArray?: boolean, depthStencilTexture?: boolean): boolean;
+        private _updateAnisotropicLevel;
+        private _getAddressMode;
+        /** @hidden */
+        _bindTexture(channel: number, texture: InternalTexture): void;
+        protected _deleteBuffer(buffer: NativeDataBuffer): void;
+        releaseEffects(): 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): void;
+        /** @hidden */
+        _uploadArrayBufferViewToTexture(texture: InternalTexture, imageData: ArrayBufferView, faceIndex?: number, lod?: number): void;
+        /** @hidden */
+        _uploadImageToTexture(texture: InternalTexture, image: HTMLImageElement, faceIndex?: number, lod?: number): void;
+    }
+}
+declare module BABYLON {
     /**
      * Gather the list of clipboard event types as constants.
      */
@@ -44450,6 +44891,7 @@ declare module BABYLON {
          * @returns The directional light
          */
         transferToEffect(effect: Effect, lightIndex: string): DirectionalLight;
+        transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string): Light;
         /**
          * Gets the minZ used for shadow according to both the scene and the light.
          *
@@ -44633,6 +45075,7 @@ declare module BABYLON {
          * @returns The spot light
          */
         transferToEffect(effect: Effect, lightIndex: string): SpotLight;
+        transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string): this;
         /**
          * Disposes the light and the associated resources.
          */
@@ -45432,13 +45875,6 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
-    /** @hidden */
-    export var rgbdDecodePixelShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module BABYLON {
     /**
      * Class used to host texture specific utilities
      */
@@ -47600,88 +48036,6 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
-    /** @hidden */
-    export var rgbdEncodePixelShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module BABYLON {
-    /**
-     * Raw texture data and descriptor sufficient for WebGL texture upload
-     */
-    export interface EnvironmentTextureInfo {
-        /**
-         * Version of the environment map
-         */
-        version: number;
-        /**
-         * Width of image
-         */
-        width: number;
-        /**
-         * Irradiance information stored in the file.
-         */
-        irradiance: any;
-        /**
-         * Specular information stored in the file.
-         */
-        specular: any;
-    }
-    /**
-     * Sets of helpers addressing the serialization and deserialization of environment texture
-     * stored in a BabylonJS env file.
-     * Those files are usually stored as .env files.
-     */
-    export class EnvironmentTextureTools {
-        /**
-         * Magic number identifying the env file.
-         */
-        private static _MagicBytes;
-        /**
-         * Gets the environment info from an env file.
-         * @param data The array buffer containing the .env bytes.
-         * @returns the environment file info (the json header) if successfully parsed.
-         */
-        static GetEnvInfo(data: ArrayBuffer): Nullable<EnvironmentTextureInfo>;
-        /**
-         * Creates an environment texture from a loaded cube texture.
-         * @param texture defines the cube texture to convert in env file
-         * @return a promise containing the environment data if succesfull.
-         */
-        static CreateEnvTextureAsync(texture: CubeTexture): Promise<ArrayBuffer>;
-        /**
-         * Creates a JSON representation of the spherical data.
-         * @param texture defines the texture containing the polynomials
-         * @return the JSON representation of the spherical info
-         */
-        private static _CreateEnvTextureIrradiance;
-        /**
-         * Uploads the texture info contained in the env file to the GPU.
-         * @param texture defines the internal texture to upload to
-         * @param arrayBuffer defines the buffer cotaining the data to load
-         * @param info defines the texture info retrieved through the GetEnvInfo method
-         * @returns a promise
-         */
-        static UploadEnvLevelsAsync(texture: InternalTexture, arrayBuffer: any, info: EnvironmentTextureInfo): Promise<void>;
-        /**
-         * Uploads the levels of image data to the GPU.
-         * @param texture defines the internal texture to upload to
-         * @param imageData defines the array buffer views of image data [mipmap][face]
-         * @returns a promise
-         */
-        static UploadLevelsAsync(texture: InternalTexture, imageData: ArrayBufferView[][]): Promise<void>;
-        /**
-         * Uploads spherical polynomials information to the texture.
-         * @param texture defines the texture we are trying to upload the information to
-         * @param info defines the environment texture info retrieved through the GetEnvInfo method
-         */
-        static UploadEnvSpherical(texture: InternalTexture, info: EnvironmentTextureInfo): void;
-        /** @hidden */
-        static _UpdateRGBDAsync(internalTexture: InternalTexture, data: ArrayBufferView[][], sphericalPolynomial: Nullable<SphericalPolynomial>, lodScale: number, lodOffset: number): Promise<void>;
-    }
-}
-declare module BABYLON {
     /**
      * Implementation of the ENV Texture Loader.
      * @hidden
@@ -47991,61 +48345,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Contains position and normal vectors for a vertex
-     */
-    export class PositionNormalVertex {
-        /** the position of the vertex (defaut: 0,0,0) */
-        position: Vector3;
-        /** the normal of the vertex (defaut: 0,1,0) */
-        normal: Vector3;
-        /**
-         * Creates a PositionNormalVertex
-         * @param position the position of the vertex (defaut: 0,0,0)
-         * @param normal the normal of the vertex (defaut: 0,1,0)
-         */
-        constructor(
-        /** the position of the vertex (defaut: 0,0,0) */
-        position?: Vector3, 
-        /** the normal of the vertex (defaut: 0,1,0) */
-        normal?: Vector3);
-        /**
-         * Clones the PositionNormalVertex
-         * @returns the cloned PositionNormalVertex
-         */
-        clone(): PositionNormalVertex;
-    }
-    /**
-     * Contains position, normal and uv vectors for a vertex
-     */
-    export class PositionNormalTextureVertex {
-        /** the position of the vertex (defaut: 0,0,0) */
-        position: Vector3;
-        /** the normal of the vertex (defaut: 0,1,0) */
-        normal: Vector3;
-        /** the uv of the vertex (default: 0,0) */
-        uv: Vector2;
-        /**
-         * Creates a PositionNormalTextureVertex
-         * @param position the position of the vertex (defaut: 0,0,0)
-         * @param normal the normal of the vertex (defaut: 0,1,0)
-         * @param uv the uv of the vertex (default: 0,0)
-         */
-        constructor(
-        /** the position of the vertex (defaut: 0,0,0) */
-        position?: Vector3, 
-        /** the normal of the vertex (defaut: 0,1,0) */
-        normal?: Vector3, 
-        /** the uv of the vertex (default: 0,0) */
-        uv?: Vector2);
-        /**
-         * Clones the PositionNormalTextureVertex
-         * @returns the cloned PositionNormalTextureVertex
-         */
-        clone(): PositionNormalTextureVertex;
-    }
-}
-declare module BABYLON {
-    /**
      * Display a 360/180 degree video on an approximately spherical surface, useful for VR applications or skyboxes.
      * As a subclass of TransformNode, this allow parenting to the camera or multiple videos with different locations in the scene.
      * This class achieves its effect with a VideoTexture and a correctly configured BackgroundMaterial on an inverted sphere.
@@ -49784,6 +50083,7 @@ declare module BABYLON {
          * @returns The point light
          */
         transferToEffect(effect: Effect, lightIndex: string): PointLight;
+        transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string): this;
         /**
          * Prepares the list of defines specific to the light type.
          * @param defines the list of defines
@@ -52481,6 +52781,8 @@ declare module BABYLON {
         _inputs: NodeMaterialConnectionPoint[];
         /** @hidden */
         _outputs: NodeMaterialConnectionPoint[];
+        /** @hidden */
+        _preparationId: number;
         /**
          * Gets or sets the name of the block
          */
@@ -53078,6 +53380,45 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Block used to get data information from a light
+     */
+    export class LightInformationBlock extends NodeMaterialBlock {
+        private _lightDataDefineName;
+        private _lightColorDefineName;
+        /**
+         * Gets or sets the light associated with this block
+         */
+        light: Nullable<Light>;
+        /**
+         * Creates a new LightInformationBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the world position input component
+         */
+        readonly worldPosition: NodeMaterialConnectionPoint;
+        /**
+         * Gets the direction output component
+         */
+        readonly direction: NodeMaterialConnectionPoint;
+        /**
+         * Gets the direction output component
+         */
+        readonly color: NodeMaterialConnectionPoint;
+        bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh): void;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+        serialize(): any;
+        _deserialize(serializationObject: any, scene: Scene, rootUrl: string): void;
+    }
+}
+declare module BABYLON {
+    /**
      * Block used to add an alpha test in the fragment shader
      */
     export class AlphaTestBlock extends NodeMaterialBlock {
@@ -53947,6 +54288,66 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Block used to get the max of 2 values
+     */
+    export class MaxBlock extends NodeMaterialBlock {
+        /**
+         * Creates a new MaxBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the left operand input component
+         */
+        readonly left: NodeMaterialConnectionPoint;
+        /**
+         * Gets the right operand input component
+         */
+        readonly right: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
+     * Block used to get the min of 2 values
+     */
+    export class MinBlock extends NodeMaterialBlock {
+        /**
+         * Creates a new MinBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the left operand input component
+         */
+        readonly left: NodeMaterialConnectionPoint;
+        /**
+         * Gets the right operand input component
+         */
+        readonly right: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
      * Effect Render Options
      */
     export interface IEffectRendererOptions {

Разлика између датотеке није приказан због своје велике величине
+ 2 - 2
dist/preview release/babylon.js


Разлика између датотеке није приказан због своје велике величине
+ 1683 - 84
dist/preview release/babylon.max.js


Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/babylon.max.js.map


Разлика између датотеке није приказан због своје велике величине
+ 1174 - 341
dist/preview release/babylon.module.d.ts


+ 560 - 159
dist/preview release/documentation.d.ts

@@ -279,6 +279,11 @@ declare module BABYLON {
          */
         static IsWindowObjectExist(): boolean;
         /**
+         * Checks if the navigator object exists
+         * @returns true if the navigator object exists
+         */
+        static IsNavigatorAvailable(): boolean;
+        /**
          * Extracts text content from a DOM element hierarchy
          * @param element defines the root element
          * @returns a string
@@ -4739,7 +4744,7 @@ declare module BABYLON {
          * @param offlineProvider offline provider for caching
          * @returns the HTMLImageElement of the loaded image
          */
-        static LoadImage(input: string | ArrayBuffer | Blob, onLoad: (img: HTMLImageElement) => void, onError: (message?: string, exception?: any) => void, offlineProvider: Nullable<IOfflineProvider>): HTMLImageElement;
+        static LoadImage(input: string | ArrayBuffer | ArrayBufferView | Blob, onLoad: (img: HTMLImageElement) => void, onError: (message?: string, exception?: any) => void, offlineProvider: Nullable<IOfflineProvider>): HTMLImageElement;
         /**
          * Loads a file
          * @param fileToLoad defines the file to load
@@ -9856,6 +9861,13 @@ declare module BABYLON {
          */
         abstract transferToEffect(effect: Effect, lightIndex: string): Light;
         /**
+         * Sets the passed Effect "effect" with the Light information.
+         * @param effect The effect to update
+         * @param lightDataUniformName The uniform used to store light data (position or direction)
+         * @returns The light
+         */
+        abstract transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string): Light;
+        /**
          * Returns the string "Light".
          * @returns the class name
          */
@@ -14482,6 +14494,7 @@ declare module BABYLON {
          * @returns The hemispheric light
          */
         transferToEffect(effect: Effect, lightIndex: string): HemisphericLight;
+        transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string): this;
         /**
          * Computes the world matrix of the node
          * @param force defines if the cache version should be invalidated forcing the world matrix to be created from scratch
@@ -15685,7 +15698,7 @@ declare module BABYLON {
         /** @hidden */
         protected _initialSamplingMode: number;
         /** @hidden */
-        _buffer: Nullable<string | ArrayBuffer | HTMLImageElement | Blob>;
+        _buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob>;
         private _deleteBuffer;
         protected _format: Nullable<number>;
         private _delayedOnLoad;
@@ -15723,14 +15736,14 @@ declare module BABYLON {
          * @param deleteBuffer define if the buffer we are loading the texture from should be deleted after load
          * @param format define the format of the texture we are trying to load (Engine.TEXTUREFORMAT_RGBA...)
          */
-        constructor(url: Nullable<string>, sceneOrEngine: Nullable<Scene | Engine>, noMipmap?: boolean, invertY?: boolean, samplingMode?: number, onLoad?: Nullable<() => void>, onError?: Nullable<(message?: string, exception?: any) => void>, buffer?: Nullable<string | ArrayBuffer | HTMLImageElement | Blob>, deleteBuffer?: boolean, format?: number);
+        constructor(url: Nullable<string>, sceneOrEngine: Nullable<Scene | Engine>, noMipmap?: boolean, invertY?: boolean, samplingMode?: number, onLoad?: Nullable<() => void>, onError?: Nullable<(message?: string, exception?: any) => void>, buffer?: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob>, deleteBuffer?: boolean, format?: number);
         /**
          * Update the url (and optional buffer) of this texture if url was null during construction.
          * @param url the url of the texture
          * @param buffer the buffer of the texture (defaults to null)
          * @param onLoad callback called when the texture is loaded  (defaults to null)
          */
-        updateURL(url: string, buffer?: Nullable<string | ArrayBuffer | HTMLImageElement | Blob>, onLoad?: () => void): void;
+        updateURL(url: string, buffer?: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob>, onLoad?: () => void): void;
         /**
          * Finish the loading sequence of a texture flagged as delayed load.
          * @hidden
@@ -28042,7 +28055,7 @@ declare module BABYLON {
         /** @hidden */
         _dataSource: number;
         /** @hidden */
-        _buffer: Nullable<string | ArrayBuffer | HTMLImageElement | Blob>;
+        _buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob>;
         /** @hidden */
         _bufferView: Nullable<ArrayBufferView>;
         /** @hidden */
@@ -30109,7 +30122,7 @@ declare module BABYLON {
         _gl: WebGLRenderingContext;
         private _renderingCanvas;
         private _windowIsBackground;
-        private _webGLVersion;
+        protected _webGLVersion: number;
         protected _highPrecisionShadersAllowed: boolean;
         /** @hidden */
         readonly _shouldUseHighPrecisionShader: boolean;
@@ -30150,7 +30163,7 @@ declare module BABYLON {
         _caps: EngineCapabilities;
         private _pointerLockRequested;
         private _isStencilEnable;
-        private _colorWrite;
+        protected _colorWrite: boolean;
         private _loadingScreen;
         /** @hidden */
         _drawCalls: PerfCounter;
@@ -30578,6 +30591,11 @@ declare module BABYLON {
         /** @hidden */
         _renderLoop(): void;
         /**
+         * Can be used to override the current requestAnimationFrame requester.
+         * @hidden
+         */
+        protected _queueNewFrame(bindedRenderFunction: any, requester?: any): number;
+        /**
          * Register and execute a render loop. The engine can have more than one render function
          * @param renderFunction defines the function to continuously execute
          */
@@ -30762,6 +30780,7 @@ declare module BABYLON {
          * @returns a new webGL buffer
          */
         createIndexBuffer(indices: IndicesArray, updatable?: boolean): DataBuffer;
+        protected _normalizeIndexData(indices: IndicesArray): Uint16Array | Uint32Array;
         /**
          * Bind a webGL buffer to the webGL context
          * @param buffer defines the buffer to bind
@@ -30843,6 +30862,7 @@ declare module BABYLON {
         releaseVertexArrayObject(vao: WebGLVertexArrayObject): void;
         /** @hidden */
         _releaseBuffer(buffer: DataBuffer): boolean;
+        protected _deleteBuffer(buffer: DataBuffer): void;
         /**
          * Creates a webGL buffer to use with instanciation
          * @param capacity defines the size of the buffer
@@ -30923,6 +30943,7 @@ declare module BABYLON {
          * @returns the new Effect
          */
         createEffect(baseName: any, attributesNamesOrOptions: string[] | EffectCreationOptions, uniformsNamesOrEngine: string[] | Engine, samplers?: string[], defines?: string, fallbacks?: EffectFallbacks, onCompiled?: Nullable<(effect: Effect) => void>, onError?: Nullable<(effect: Effect, errors: string) => void>, indexParameters?: any): Effect;
+        protected static _concatenateShader(source: string, defines: Nullable<string>, shaderVersion?: string): string;
         private _compileShader;
         private _compileRawShader;
         /**
@@ -30950,7 +30971,7 @@ declare module BABYLON {
          * Creates a new pipeline context
          * @returns the new pipeline
          */
-        createPipelineContext(): WebGLPipelineContext;
+        createPipelineContext(): IPipelineContext;
         private _createShaderProgram;
         private _finalizePipelineContext;
         /** @hidden */
@@ -31239,7 +31260,7 @@ declare module BABYLON {
          * @param excludeLoaders array of texture loaders that should be excluded when picking a loader for the texture (default: empty array)
          * @returns a InternalTexture for assignment back into BABYLON.Texture
          */
-        createTexture(urlArg: Nullable<string>, noMipmap: boolean, invertY: boolean, scene: Nullable<Scene>, samplingMode?: number, onLoad?: Nullable<() => void>, onError?: Nullable<(message: string, exception: any) => void>, buffer?: Nullable<string | ArrayBuffer | HTMLImageElement | Blob>, fallback?: Nullable<InternalTexture>, format?: Nullable<number>, forcedExtension?: Nullable<string>, excludeLoaders?: Array<IInternalTextureLoader>): InternalTexture;
+        createTexture(urlArg: Nullable<string>, noMipmap: boolean, invertY: boolean, scene: Nullable<Scene>, samplingMode?: number, onLoad?: Nullable<() => void>, onError?: Nullable<(message: string, exception: any) => void>, buffer?: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob>, fallback?: Nullable<InternalTexture>, format?: Nullable<number>, forcedExtension?: Nullable<string>, excludeLoaders?: Array<IInternalTextureLoader>): InternalTexture;
         /**
          * @hidden
          * Rescales a texture
@@ -31362,7 +31383,7 @@ declare module BABYLON {
          * @hidden
          */
         _setCubeMapTextureParams(loadMipmap: boolean): void;
-        private _prepareWebGLTextureContinuation;
+        protected _prepareWebGLTextureContinuation(texture: InternalTexture, scene: Nullable<Scene>, noMipmap: boolean, isCompressed: boolean, samplingMode: number): void;
         private _prepareWebGLTexture;
         /** @hidden */
         _convertRGBtoRGBATextureData(rgbData: any, width: number, height: number, textureType: number): ArrayBufferView;
@@ -31370,8 +31391,11 @@ declare module BABYLON {
         _releaseFramebufferObjects(texture: InternalTexture): void;
         /** @hidden */
         _releaseTexture(texture: InternalTexture): void;
-        private setProgram;
-        private _boundUniforms;
+        protected _deleteTexture(texture: Nullable<WebGLTexture>): void;
+        protected _setProgram(program: WebGLProgram): void;
+        protected _boundUniforms: {
+            [key: number]: WebGLUniformLocation;
+        };
         /**
          * Binds an effect to the webGL context
          * @param effect defines the effect to bind
@@ -31414,7 +31438,7 @@ declare module BABYLON {
         setDepthStencilTexture(channel: number, uniform: Nullable<WebGLUniformLocation>, texture: Nullable<RenderTargetTexture>): void;
         private _bindSamplerUniformToChannel;
         private _getTextureWrapMode;
-        private _setTexture;
+        protected _setTexture(channel: number, texture: Nullable<BaseTexture>, isPartOfTextureArray?: boolean, depthStencilTexture?: boolean): boolean;
         /**
          * Sets an array of texture to the webGL context
          * @param channel defines the channel where the texture array must be set
@@ -43482,8 +43506,7 @@ declare module BABYLON {
         _bindTextureDirectly(target: number, texture: InternalTexture): boolean;
         /** @hidden */
         _bindTexture(channel: number, texture: InternalTexture): void;
-        /** @hidden */
-        _releaseBuffer(buffer: DataBuffer): boolean;
+        protected _deleteBuffer(buffer: WebGLBuffer): void;
         releaseEffects(): void;
         displayLoadingUI(): void;
         hideLoadingUI(): void;
@@ -43804,6 +43827,424 @@ declare module BABYLON {
         }
 }
 declare module BABYLON {
+    /** @hidden */
+    export var rgbdEncodePixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /** @hidden */
+    export var rgbdDecodePixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /**
+     * Raw texture data and descriptor sufficient for WebGL texture upload
+     */
+    export interface EnvironmentTextureInfo {
+        /**
+         * Version of the environment map
+         */
+        version: number;
+        /**
+         * Width of image
+         */
+        width: number;
+        /**
+         * Irradiance information stored in the file.
+         */
+        irradiance: any;
+        /**
+         * Specular information stored in the file.
+         */
+        specular: any;
+    }
+    /**
+     * Defines One Image in the file. It requires only the position in the file
+     * as well as the length.
+     */
+    interface BufferImageData {
+        /**
+         * Length of the image data.
+         */
+        length: number;
+        /**
+         * Position of the data from the null terminator delimiting the end of the JSON.
+         */
+        position: number;
+    }
+    /**
+     * Defines the specular data enclosed in the file.
+     * This corresponds to the version 1 of the data.
+     */
+    export interface EnvironmentTextureSpecularInfoV1 {
+        /**
+         * Defines where the specular Payload is located. It is a runtime value only not stored in the file.
+         */
+        specularDataPosition?: number;
+        /**
+         * This contains all the images data needed to reconstruct the cubemap.
+         */
+        mipmaps: Array<BufferImageData>;
+        /**
+         * Defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness.
+         */
+        lodGenerationScale: number;
+    }
+    /**
+     * Sets of helpers addressing the serialization and deserialization of environment texture
+     * stored in a BabylonJS env file.
+     * Those files are usually stored as .env files.
+     */
+    export class EnvironmentTextureTools {
+        /**
+         * Magic number identifying the env file.
+         */
+        private static _MagicBytes;
+        /**
+         * Gets the environment info from an env file.
+         * @param data The array buffer containing the .env bytes.
+         * @returns the environment file info (the json header) if successfully parsed.
+         */
+        static GetEnvInfo(data: ArrayBuffer): Nullable<EnvironmentTextureInfo>;
+        /**
+         * Creates an environment texture from a loaded cube texture.
+         * @param texture defines the cube texture to convert in env file
+         * @return a promise containing the environment data if succesfull.
+         */
+        static CreateEnvTextureAsync(texture: CubeTexture): Promise<ArrayBuffer>;
+        /**
+         * Creates a JSON representation of the spherical data.
+         * @param texture defines the texture containing the polynomials
+         * @return the JSON representation of the spherical info
+         */
+        private static _CreateEnvTextureIrradiance;
+        /**
+         * Creates the ArrayBufferViews used for initializing environment texture image data.
+         * @param arrayBuffer the underlying ArrayBuffer to which the views refer
+         * @param info parameters that determine what views will be created for accessing the underlying buffer
+         * @return the views described by info providing access to the underlying buffer
+         */
+        static CreateImageDataArrayBufferViews(arrayBuffer: any, info: EnvironmentTextureInfo): Array<Array<ArrayBufferView>>;
+        /**
+         * Uploads the texture info contained in the env file to the GPU.
+         * @param texture defines the internal texture to upload to
+         * @param arrayBuffer defines the buffer cotaining the data to load
+         * @param info defines the texture info retrieved through the GetEnvInfo method
+         * @returns a promise
+         */
+        static UploadEnvLevelsAsync(texture: InternalTexture, arrayBuffer: any, info: EnvironmentTextureInfo): Promise<void>;
+        /**
+         * Uploads the levels of image data to the GPU.
+         * @param texture defines the internal texture to upload to
+         * @param imageData defines the array buffer views of image data [mipmap][face]
+         * @returns a promise
+         */
+        static UploadLevelsAsync(texture: InternalTexture, imageData: ArrayBufferView[][]): Promise<void>;
+        /**
+         * Uploads spherical polynomials information to the texture.
+         * @param texture defines the texture we are trying to upload the information to
+         * @param info defines the environment texture info retrieved through the GetEnvInfo method
+         */
+        static UploadEnvSpherical(texture: InternalTexture, info: EnvironmentTextureInfo): void;
+        /** @hidden */
+        static _UpdateRGBDAsync(internalTexture: InternalTexture, data: ArrayBufferView[][], sphericalPolynomial: Nullable<SphericalPolynomial>, lodScale: number, lodOffset: number): Promise<void>;
+    }
+}
+declare module BABYLON {
+    /**
+     * Contains position and normal vectors for a vertex
+     */
+    export class PositionNormalVertex {
+        /** the position of the vertex (defaut: 0,0,0) */
+        position: Vector3;
+        /** the normal of the vertex (defaut: 0,1,0) */
+        normal: Vector3;
+        /**
+         * Creates a PositionNormalVertex
+         * @param position the position of the vertex (defaut: 0,0,0)
+         * @param normal the normal of the vertex (defaut: 0,1,0)
+         */
+        constructor(
+        /** the position of the vertex (defaut: 0,0,0) */
+        position?: Vector3, 
+        /** the normal of the vertex (defaut: 0,1,0) */
+        normal?: Vector3);
+        /**
+         * Clones the PositionNormalVertex
+         * @returns the cloned PositionNormalVertex
+         */
+        clone(): PositionNormalVertex;
+    }
+    /**
+     * Contains position, normal and uv vectors for a vertex
+     */
+    export class PositionNormalTextureVertex {
+        /** the position of the vertex (defaut: 0,0,0) */
+        position: Vector3;
+        /** the normal of the vertex (defaut: 0,1,0) */
+        normal: Vector3;
+        /** the uv of the vertex (default: 0,0) */
+        uv: Vector2;
+        /**
+         * Creates a PositionNormalTextureVertex
+         * @param position the position of the vertex (defaut: 0,0,0)
+         * @param normal the normal of the vertex (defaut: 0,1,0)
+         * @param uv the uv of the vertex (default: 0,0)
+         */
+        constructor(
+        /** the position of the vertex (defaut: 0,0,0) */
+        position?: Vector3, 
+        /** the normal of the vertex (defaut: 0,1,0) */
+        normal?: Vector3, 
+        /** the uv of the vertex (default: 0,0) */
+        uv?: Vector2);
+        /**
+         * Clones the PositionNormalTextureVertex
+         * @returns the cloned PositionNormalTextureVertex
+         */
+        clone(): PositionNormalTextureVertex;
+    }
+}
+declare module BABYLON {
+    /** @hidden */
+    export class NativeShaderProcessor extends WebGL2ShaderProcessor {
+        private _genericAttributeLocation;
+        private _varyingLocationCount;
+        private _varyingLocationMap;
+        private _replacements;
+        private _textureCount;
+        private _uniforms;
+        lineProcessor(line: string): string;
+        attributeProcessor(attribute: string): string;
+        varyingProcessor(varying: string, isFragment: boolean): string;
+        uniformProcessor(uniform: string): string;
+        preProcessor(code: string, defines: string[], isFragment: boolean): string;
+        postProcessor(code: string, defines: string[], isFragment: boolean): string;
+    }
+}
+declare module BABYLON {
+    /**
+     * Container for accessors for natively-stored mesh data buffers.
+     */
+    class NativeDataBuffer extends DataBuffer {
+        /**
+         * Accessor value used to identify/retrieve a natively-stored index buffer.
+         */
+        nativeIndexBuffer?: any;
+        /**
+         * Accessor value used to identify/retrieve a natively-stored vertex buffer.
+         */
+        nativeVertexBuffer?: any;
+    }
+    /** @hidden */
+    export class NativeEngine extends Engine {
+        private readonly _native;
+        getHardwareScalingLevel(): number;
+        constructor();
+        /**
+         * Can be used to override the current requestAnimationFrame requester.
+         * @hidden
+         */
+        protected _queueNewFrame(bindedRenderFunction: any, requester: any): number;
+        clear(color: Color4, backBuffer: boolean, depth: boolean, stencil?: boolean): void;
+        createIndexBuffer(indices: IndicesArray): NativeDataBuffer;
+        createVertexBuffer(data: DataArray): NativeDataBuffer;
+        recordVertexArrayObject(vertexBuffers: {
+            [key: string]: VertexBuffer;
+        }, indexBuffer: Nullable<NativeDataBuffer>, effect: Effect): WebGLVertexArrayObject;
+        bindVertexArrayObject(vertexArray: WebGLVertexArrayObject): void;
+        releaseVertexArrayObject(vertexArray: WebGLVertexArrayObject): void;
+        getAttributes(pipelineContext: IPipelineContext, attributesNames: string[]): number[];
+        /**
+         * Draw a list of indexed primitives
+         * @param fillMode defines the primitive to use
+         * @param indexStart defines the starting index
+         * @param indexCount defines the number of index to draw
+         * @param instancesCount defines the number of instances to draw (if instanciation is enabled)
+         */
+        drawElementsType(fillMode: number, indexStart: number, indexCount: number, instancesCount?: number): void;
+        /**
+         * Draw a list of unindexed primitives
+         * @param fillMode defines the primitive to use
+         * @param verticesStart defines the index of first vertex to draw
+         * @param verticesCount defines the count of vertices to draw
+         * @param instancesCount defines the number of instances to draw (if instanciation is enabled)
+         */
+        drawArraysType(fillMode: number, verticesStart: number, verticesCount: number, instancesCount?: number): void;
+        createPipelineContext(): IPipelineContext;
+        _preparePipelineContext(pipelineContext: IPipelineContext, vertexSourceCode: string, fragmentSourceCode: string, createAsRaw: boolean, rebuildRebind: any, defines: Nullable<string>, transformFeedbackVaryings: Nullable<string[]>): void;
+        /** @hidden */
+        _isRenderingStateCompiled(pipelineContext: IPipelineContext): boolean;
+        /** @hidden */
+        _executeWhenRenderingStateIsCompiled(pipelineContext: IPipelineContext, action: () => void): void;
+        createRawShaderProgram(pipelineContext: IPipelineContext, vertexCode: string, fragmentCode: string, context?: WebGLRenderingContext, transformFeedbackVaryings?: Nullable<string[]>): any;
+        createShaderProgram(pipelineContext: IPipelineContext, vertexCode: string, fragmentCode: string, defines: Nullable<string>, context?: WebGLRenderingContext, transformFeedbackVaryings?: Nullable<string[]>): any;
+        protected _setProgram(program: WebGLProgram): void;
+        _releaseEffect(effect: Effect): void;
+        _deletePipelineContext(pipelineContext: IPipelineContext): void;
+        getUniforms(pipelineContext: IPipelineContext, uniformsNames: string[]): WebGLUniformLocation[];
+        bindUniformBlock(pipelineContext: IPipelineContext, blockName: string, index: number): void;
+        bindSamplers(effect: Effect): void;
+        setMatrix(uniform: WebGLUniformLocation, matrix: Matrix): void;
+        getRenderWidth(useScreen?: boolean): number;
+        getRenderHeight(useScreen?: boolean): number;
+        setViewport(viewport: Viewport, requiredWidth?: number, requiredHeight?: number): void;
+        setState(culling: boolean, zOffset?: number, force?: boolean, reverseSide?: boolean): void;
+        /**
+         * Set the z offset to apply to current rendering
+         * @param value defines the offset to apply
+         */
+        setZOffset(value: number): void;
+        /**
+         * Gets the current value of the zOffset
+         * @returns the current zOffset state
+         */
+        getZOffset(): number;
+        /**
+         * Enable or disable depth buffering
+         * @param enable defines the state to set
+         */
+        setDepthBuffer(enable: boolean): void;
+        /**
+         * Gets a boolean indicating if depth writing is enabled
+         * @returns the current depth writing state
+         */
+        getDepthWrite(): boolean;
+        /**
+         * Enable or disable depth writing
+         * @param enable defines the state to set
+         */
+        setDepthWrite(enable: boolean): void;
+        /**
+         * Enable or disable color writing
+         * @param enable defines the state to set
+         */
+        setColorWrite(enable: boolean): void;
+        /**
+         * Gets a boolean indicating if color writing is enabled
+         * @returns the current color writing state
+         */
+        getColorWrite(): boolean;
+        /**
+         * Sets alpha constants used by some alpha blending modes
+         * @param r defines the red component
+         * @param g defines the green component
+         * @param b defines the blue component
+         * @param a defines the alpha component
+         */
+        setAlphaConstants(r: number, g: number, b: number, a: number): void;
+        /**
+         * Sets the current alpha mode
+         * @param mode defines the mode to use (one of the BABYLON.Engine.ALPHA_XXX)
+         * @param noDepthWriteChange defines if depth writing state should remains unchanged (false by default)
+         * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered
+         */
+        setAlphaMode(mode: number, noDepthWriteChange?: boolean): void;
+        /**
+         * Gets the current alpha mode
+         * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered
+         * @returns the current alpha mode
+         */
+        getAlphaMode(): number;
+        setIntArray(uniform: WebGLUniformLocation, array: Int32Array): void;
+        setIntArray2(uniform: WebGLUniformLocation, array: Int32Array): void;
+        setIntArray3(uniform: WebGLUniformLocation, array: Int32Array): void;
+        setIntArray4(uniform: WebGLUniformLocation, array: Int32Array): void;
+        setFloatArray(uniform: WebGLUniformLocation, array: Float32Array): void;
+        setFloatArray2(uniform: WebGLUniformLocation, array: Float32Array): void;
+        setFloatArray3(uniform: WebGLUniformLocation, array: Float32Array): void;
+        setFloatArray4(uniform: WebGLUniformLocation, array: Float32Array): void;
+        setArray(uniform: WebGLUniformLocation, array: number[]): void;
+        setArray2(uniform: WebGLUniformLocation, array: number[]): void;
+        setArray3(uniform: WebGLUniformLocation, array: number[]): void;
+        setArray4(uniform: WebGLUniformLocation, array: number[]): void;
+        setMatrices(uniform: WebGLUniformLocation, matrices: Float32Array): void;
+        setMatrix3x3(uniform: WebGLUniformLocation, matrix: Float32Array): void;
+        setMatrix2x2(uniform: WebGLUniformLocation, matrix: Float32Array): void;
+        setFloat(uniform: WebGLUniformLocation, value: number): void;
+        setFloat2(uniform: WebGLUniformLocation, x: number, y: number): void;
+        setFloat3(uniform: WebGLUniformLocation, x: number, y: number, z: number): void;
+        setBool(uniform: WebGLUniformLocation, bool: number): void;
+        setFloat4(uniform: WebGLUniformLocation, x: number, y: number, z: number, w: number): void;
+        setColor3(uniform: WebGLUniformLocation, color3: Color3): void;
+        setColor4(uniform: WebGLUniformLocation, color3: Color3, alpha: number): void;
+        wipeCaches(bruteForce?: boolean): void;
+        _createTexture(): WebGLTexture;
+        protected _deleteTexture(texture: Nullable<WebGLTexture>): void;
+        /**
+         * Usually called from BABYLON.Texture.ts.
+         * Passed information to create a WebGLTexture
+         * @param urlArg defines a value which contains one of the following:
+         * * A conventional http URL, e.g. 'http://...' or 'file://...'
+         * * A base64 string of in-line texture data, e.g. 'data:image/jpg;base64,/...'
+         * * An indicator that data being passed using the buffer parameter, e.g. 'data:mytexture.jpg'
+         * @param noMipmap defines a boolean indicating that no mipmaps shall be generated.  Ignored for compressed textures.  They must be in the file
+         * @param invertY when true, image is flipped when loaded.  You probably want true. Ignored for compressed textures.  Must be flipped in the file
+         * @param scene needed for loading to the correct scene
+         * @param samplingMode mode with should be used sample / access the texture (Default: BABYLON.Texture.TRILINEAR_SAMPLINGMODE)
+         * @param onLoad optional callback to be called upon successful completion
+         * @param onError optional callback to be called upon failure
+         * @param buffer a source of a file previously fetched as either a base64 string, an ArrayBuffer (compressed or image format), or a Blob
+         * @param fallback an internal argument in case the function must be called again, due to etc1 not having alpha capabilities
+         * @param format internal format.  Default: RGB when extension is '.jpg' else RGBA.  Ignored for compressed textures
+         * @param forcedExtension defines the extension to use to pick the right loader
+         * @returns a InternalTexture for assignment back into BABYLON.Texture
+         */
+        createTexture(urlArg: Nullable<string>, noMipmap: boolean, invertY: boolean, scene: Nullable<Scene>, samplingMode?: number, onLoad?: Nullable<() => void>, onError?: Nullable<(message: string, exception: any) => void>, buffer?: Nullable<string | ArrayBuffer | Blob>, fallback?: Nullable<InternalTexture>, format?: Nullable<number>, forcedExtension?: Nullable<string>): InternalTexture;
+        /**
+         * Creates a cube texture
+         * @param rootUrl defines the url where the files to load is located
+         * @param scene defines the current scene
+         * @param files defines the list of files to load (1 per face)
+         * @param noMipmap defines a boolean indicating that no mipmaps shall be generated (false by default)
+         * @param onLoad defines an optional callback raised when the texture is loaded
+         * @param onError defines an optional callback raised if there is an issue to load the texture
+         * @param format defines the format of the data
+         * @param forcedExtension defines the extension to use to pick the right loader
+         * @param createPolynomials if a polynomial sphere should be created for the cube texture
+         * @param lodScale defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness
+         * @param lodOffset defines the offset applied to environment texture. This manages first LOD level used for IBL according to the roughness
+         * @param fallback defines texture to use while falling back when (compressed) texture file not found.
+         * @returns the cube texture as an InternalTexture
+         */
+        createCubeTexture(rootUrl: string, scene: Nullable<Scene>, files: Nullable<string[]>, noMipmap?: boolean, onLoad?: Nullable<(data?: any) => void>, onError?: Nullable<(message?: string, exception?: any) => void>, format?: number, forcedExtension?: any, createPolynomials?: boolean, lodScale?: number, lodOffset?: number, fallback?: Nullable<InternalTexture>): InternalTexture;
+        private _getSamplingFilter;
+        createRenderTargetTexture(size: any, options: boolean | RenderTargetCreationOptions): InternalTexture;
+        updateTextureSamplingMode(samplingMode: number, texture: InternalTexture): void;
+        bindFramebuffer(texture: InternalTexture, faceIndex?: number, requiredWidth?: number, requiredHeight?: number, forceFullscreenViewport?: boolean): void;
+        unBindFramebuffer(texture: InternalTexture, disableGenerateMipMaps?: boolean, onBeforeUnbind?: () => void): void;
+        createDynamicVertexBuffer(data: DataArray): DataBuffer;
+        updateDynamicIndexBuffer(indexBuffer: DataBuffer, indices: IndicesArray, offset?: number): void;
+        /**
+         * Updates a dynamic vertex buffer.
+         * @param vertexBuffer the vertex buffer to update
+         * @param data the data used to update the vertex buffer
+         * @param byteOffset the byte offset of the data (optional)
+         * @param byteLength the byte length of the data (optional)
+         */
+        updateDynamicVertexBuffer(vertexBuffer: DataBuffer, data: DataArray, byteOffset?: number, byteLength?: number): void;
+        protected _setTexture(channel: number, texture: Nullable<BaseTexture>, isPartOfTextureArray?: boolean, depthStencilTexture?: boolean): boolean;
+        private _updateAnisotropicLevel;
+        private _getAddressMode;
+        /** @hidden */
+        _bindTexture(channel: number, texture: InternalTexture): void;
+        protected _deleteBuffer(buffer: NativeDataBuffer): void;
+        releaseEffects(): 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): void;
+        /** @hidden */
+        _uploadArrayBufferViewToTexture(texture: InternalTexture, imageData: ArrayBufferView, faceIndex?: number, lod?: number): void;
+        /** @hidden */
+        _uploadImageToTexture(texture: InternalTexture, image: HTMLImageElement, faceIndex?: number, lod?: number): void;
+    }
+}
+declare module BABYLON {
     /**
      * Gather the list of clipboard event types as constants.
      */
@@ -44450,6 +44891,7 @@ declare module BABYLON {
          * @returns The directional light
          */
         transferToEffect(effect: Effect, lightIndex: string): DirectionalLight;
+        transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string): Light;
         /**
          * Gets the minZ used for shadow according to both the scene and the light.
          *
@@ -44633,6 +45075,7 @@ declare module BABYLON {
          * @returns The spot light
          */
         transferToEffect(effect: Effect, lightIndex: string): SpotLight;
+        transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string): this;
         /**
          * Disposes the light and the associated resources.
          */
@@ -45432,13 +45875,6 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
-    /** @hidden */
-    export var rgbdDecodePixelShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module BABYLON {
     /**
      * Class used to host texture specific utilities
      */
@@ -47600,88 +48036,6 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
-    /** @hidden */
-    export var rgbdEncodePixelShader: {
-        name: string;
-        shader: string;
-    };
-}
-declare module BABYLON {
-    /**
-     * Raw texture data and descriptor sufficient for WebGL texture upload
-     */
-    export interface EnvironmentTextureInfo {
-        /**
-         * Version of the environment map
-         */
-        version: number;
-        /**
-         * Width of image
-         */
-        width: number;
-        /**
-         * Irradiance information stored in the file.
-         */
-        irradiance: any;
-        /**
-         * Specular information stored in the file.
-         */
-        specular: any;
-    }
-    /**
-     * Sets of helpers addressing the serialization and deserialization of environment texture
-     * stored in a BabylonJS env file.
-     * Those files are usually stored as .env files.
-     */
-    export class EnvironmentTextureTools {
-        /**
-         * Magic number identifying the env file.
-         */
-        private static _MagicBytes;
-        /**
-         * Gets the environment info from an env file.
-         * @param data The array buffer containing the .env bytes.
-         * @returns the environment file info (the json header) if successfully parsed.
-         */
-        static GetEnvInfo(data: ArrayBuffer): Nullable<EnvironmentTextureInfo>;
-        /**
-         * Creates an environment texture from a loaded cube texture.
-         * @param texture defines the cube texture to convert in env file
-         * @return a promise containing the environment data if succesfull.
-         */
-        static CreateEnvTextureAsync(texture: CubeTexture): Promise<ArrayBuffer>;
-        /**
-         * Creates a JSON representation of the spherical data.
-         * @param texture defines the texture containing the polynomials
-         * @return the JSON representation of the spherical info
-         */
-        private static _CreateEnvTextureIrradiance;
-        /**
-         * Uploads the texture info contained in the env file to the GPU.
-         * @param texture defines the internal texture to upload to
-         * @param arrayBuffer defines the buffer cotaining the data to load
-         * @param info defines the texture info retrieved through the GetEnvInfo method
-         * @returns a promise
-         */
-        static UploadEnvLevelsAsync(texture: InternalTexture, arrayBuffer: any, info: EnvironmentTextureInfo): Promise<void>;
-        /**
-         * Uploads the levels of image data to the GPU.
-         * @param texture defines the internal texture to upload to
-         * @param imageData defines the array buffer views of image data [mipmap][face]
-         * @returns a promise
-         */
-        static UploadLevelsAsync(texture: InternalTexture, imageData: ArrayBufferView[][]): Promise<void>;
-        /**
-         * Uploads spherical polynomials information to the texture.
-         * @param texture defines the texture we are trying to upload the information to
-         * @param info defines the environment texture info retrieved through the GetEnvInfo method
-         */
-        static UploadEnvSpherical(texture: InternalTexture, info: EnvironmentTextureInfo): void;
-        /** @hidden */
-        static _UpdateRGBDAsync(internalTexture: InternalTexture, data: ArrayBufferView[][], sphericalPolynomial: Nullable<SphericalPolynomial>, lodScale: number, lodOffset: number): Promise<void>;
-    }
-}
-declare module BABYLON {
     /**
      * Implementation of the ENV Texture Loader.
      * @hidden
@@ -47991,61 +48345,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Contains position and normal vectors for a vertex
-     */
-    export class PositionNormalVertex {
-        /** the position of the vertex (defaut: 0,0,0) */
-        position: Vector3;
-        /** the normal of the vertex (defaut: 0,1,0) */
-        normal: Vector3;
-        /**
-         * Creates a PositionNormalVertex
-         * @param position the position of the vertex (defaut: 0,0,0)
-         * @param normal the normal of the vertex (defaut: 0,1,0)
-         */
-        constructor(
-        /** the position of the vertex (defaut: 0,0,0) */
-        position?: Vector3, 
-        /** the normal of the vertex (defaut: 0,1,0) */
-        normal?: Vector3);
-        /**
-         * Clones the PositionNormalVertex
-         * @returns the cloned PositionNormalVertex
-         */
-        clone(): PositionNormalVertex;
-    }
-    /**
-     * Contains position, normal and uv vectors for a vertex
-     */
-    export class PositionNormalTextureVertex {
-        /** the position of the vertex (defaut: 0,0,0) */
-        position: Vector3;
-        /** the normal of the vertex (defaut: 0,1,0) */
-        normal: Vector3;
-        /** the uv of the vertex (default: 0,0) */
-        uv: Vector2;
-        /**
-         * Creates a PositionNormalTextureVertex
-         * @param position the position of the vertex (defaut: 0,0,0)
-         * @param normal the normal of the vertex (defaut: 0,1,0)
-         * @param uv the uv of the vertex (default: 0,0)
-         */
-        constructor(
-        /** the position of the vertex (defaut: 0,0,0) */
-        position?: Vector3, 
-        /** the normal of the vertex (defaut: 0,1,0) */
-        normal?: Vector3, 
-        /** the uv of the vertex (default: 0,0) */
-        uv?: Vector2);
-        /**
-         * Clones the PositionNormalTextureVertex
-         * @returns the cloned PositionNormalTextureVertex
-         */
-        clone(): PositionNormalTextureVertex;
-    }
-}
-declare module BABYLON {
-    /**
      * Display a 360/180 degree video on an approximately spherical surface, useful for VR applications or skyboxes.
      * As a subclass of TransformNode, this allow parenting to the camera or multiple videos with different locations in the scene.
      * This class achieves its effect with a VideoTexture and a correctly configured BackgroundMaterial on an inverted sphere.
@@ -49784,6 +50083,7 @@ declare module BABYLON {
          * @returns The point light
          */
         transferToEffect(effect: Effect, lightIndex: string): PointLight;
+        transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string): this;
         /**
          * Prepares the list of defines specific to the light type.
          * @param defines the list of defines
@@ -52481,6 +52781,8 @@ declare module BABYLON {
         _inputs: NodeMaterialConnectionPoint[];
         /** @hidden */
         _outputs: NodeMaterialConnectionPoint[];
+        /** @hidden */
+        _preparationId: number;
         /**
          * Gets or sets the name of the block
          */
@@ -53078,6 +53380,45 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Block used to get data information from a light
+     */
+    export class LightInformationBlock extends NodeMaterialBlock {
+        private _lightDataDefineName;
+        private _lightColorDefineName;
+        /**
+         * Gets or sets the light associated with this block
+         */
+        light: Nullable<Light>;
+        /**
+         * Creates a new LightInformationBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the world position input component
+         */
+        readonly worldPosition: NodeMaterialConnectionPoint;
+        /**
+         * Gets the direction output component
+         */
+        readonly direction: NodeMaterialConnectionPoint;
+        /**
+         * Gets the direction output component
+         */
+        readonly color: NodeMaterialConnectionPoint;
+        bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh): void;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+        serialize(): any;
+        _deserialize(serializationObject: any, scene: Scene, rootUrl: string): void;
+    }
+}
+declare module BABYLON {
+    /**
      * Block used to add an alpha test in the fragment shader
      */
     export class AlphaTestBlock extends NodeMaterialBlock {
@@ -53947,6 +54288,66 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Block used to get the max of 2 values
+     */
+    export class MaxBlock extends NodeMaterialBlock {
+        /**
+         * Creates a new MaxBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the left operand input component
+         */
+        readonly left: NodeMaterialConnectionPoint;
+        /**
+         * Gets the right operand input component
+         */
+        readonly right: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
+     * Block used to get the min of 2 values
+     */
+    export class MinBlock extends NodeMaterialBlock {
+        /**
+         * Creates a new MinBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the left operand input component
+         */
+        readonly left: NodeMaterialConnectionPoint;
+        /**
+         * Gets the right operand input component
+         */
+        readonly right: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
      * Effect Render Options
      */
     export interface IEffectRendererOptions {

+ 8 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -2734,6 +2734,13 @@ var GLTFLoader = /** @class */ (function () {
                 return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"](_this._babylonScene.getEngine(), data, kind, false);
             });
         }
+        // Load joint indices as a float array since the shaders expect float data but glTF uses unsigned byte/short.
+        // This prevents certain platforms (e.g. D3D) from having to convert the data to float on the fly.
+        else if (kind === babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesKind) {
+            accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
+                return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"](_this._babylonScene.getEngine(), data, kind, false);
+            });
+        }
         else {
             var bufferView_2 = ArrayItem.Get(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
             accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync(bufferView_2, kind).then(function (babylonBuffer) {
@@ -3004,7 +3011,7 @@ var GLTFLoader = /** @class */ (function () {
             promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
                 var name = image.uri || _this._fileName + "#image" + image.index;
                 var dataUrl = "data:" + _this._uniqueRootUrl + name;
-                babylonTexture.updateURL(dataUrl, new Blob([data], { type: image.mimeType }));
+                babylonTexture.updateURL(dataUrl, data);
             }));
         }
         babylonTexture.wrapU = samplerData.wrapU;

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.js.map


Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 8 - 1
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -5294,6 +5294,13 @@ var GLTFLoader = /** @class */ (function () {
                 return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"](_this._babylonScene.getEngine(), data, kind, false);
             });
         }
+        // Load joint indices as a float array since the shaders expect float data but glTF uses unsigned byte/short.
+        // This prevents certain platforms (e.g. D3D) from having to convert the data to float on the fly.
+        else if (kind === babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesKind) {
+            accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
+                return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"](_this._babylonScene.getEngine(), data, kind, false);
+            });
+        }
         else {
             var bufferView_2 = ArrayItem.Get(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
             accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync(bufferView_2, kind).then(function (babylonBuffer) {
@@ -5564,7 +5571,7 @@ var GLTFLoader = /** @class */ (function () {
             promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
                 var name = image.uri || _this._fileName + "#image" + image.index;
                 var dataUrl = "data:" + _this._uniqueRootUrl + name;
-                babylonTexture.updateURL(dataUrl, new Blob([data], { type: image.mimeType }));
+                babylonTexture.updateURL(dataUrl, data);
             }));
         }
         babylonTexture.wrapU = samplerData.wrapU;

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.js.map


Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 8 - 1
dist/preview release/loaders/babylonjs.loaders.js

@@ -6636,6 +6636,13 @@ var GLTFLoader = /** @class */ (function () {
                 return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"](_this._babylonScene.getEngine(), data, kind, false);
             });
         }
+        // Load joint indices as a float array since the shaders expect float data but glTF uses unsigned byte/short.
+        // This prevents certain platforms (e.g. D3D) from having to convert the data to float on the fly.
+        else if (kind === babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesKind) {
+            accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
+                return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"](_this._babylonScene.getEngine(), data, kind, false);
+            });
+        }
         else {
             var bufferView_2 = ArrayItem.Get(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
             accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync(bufferView_2, kind).then(function (babylonBuffer) {
@@ -6906,7 +6913,7 @@ var GLTFLoader = /** @class */ (function () {
             promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
                 var name = image.uri || _this._fileName + "#image" + image.index;
                 var dataUrl = "data:" + _this._uniqueRootUrl + name;
-                babylonTexture.updateURL(dataUrl, new Blob([data], { type: image.mimeType }));
+                babylonTexture.updateURL(dataUrl, data);
             }));
         }
         babylonTexture.wrapU = samplerData.wrapU;

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.js.map


Разлика између датотеке није приказан због своје велике величине
+ 2 - 2
dist/preview release/loaders/babylonjs.loaders.min.js


Разлика између датотеке није приказан због своје велике величине
+ 69 - 1
dist/preview release/nodeEditor/babylon.nodeEditor.d.ts


Разлика између датотеке није приказан због своје велике величине
+ 6 - 6
dist/preview release/nodeEditor/babylon.nodeEditor.js


+ 240 - 15
dist/preview release/nodeEditor/babylon.nodeEditor.max.js

@@ -68346,6 +68346,9 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
+
+
 var BlockTools = /** @class */ (function () {
     function BlockTools() {
     }
@@ -68415,6 +68418,12 @@ var BlockTools = /** @class */ (function () {
                 return new babylonjs_Materials_Node_Blocks_Fragment_alphaTestBlock__WEBPACK_IMPORTED_MODULE_0__["OppositeBlock"]("Opposite");
             case "ViewDirectionBlock":
                 return new babylonjs_Materials_Node_Blocks_Fragment_alphaTestBlock__WEBPACK_IMPORTED_MODULE_0__["ViewDirectionBlock"]("View direction");
+            case "LightInformationBlock":
+                return new babylonjs_Materials_Node_Blocks_Fragment_alphaTestBlock__WEBPACK_IMPORTED_MODULE_0__["LightInformationBlock"]("Light information");
+            case "MaxBlock":
+                return new babylonjs_Materials_Node_Blocks_Fragment_alphaTestBlock__WEBPACK_IMPORTED_MODULE_0__["MaxBlock"]("Max");
+            case "MinBlock":
+                return new babylonjs_Materials_Node_Blocks_Fragment_alphaTestBlock__WEBPACK_IMPORTED_MODULE_0__["MinBlock"]("Min");
             case "CosBlock": {
                 var cosBlock = new babylonjs_Materials_Node_Blocks_Fragment_alphaTestBlock__WEBPACK_IMPORTED_MODULE_0__["TrigonometryBlock"]("Cos");
                 cosBlock.operation = babylonjs_Materials_Node_Blocks_Fragment_alphaTestBlock__WEBPACK_IMPORTED_MODULE_0__["TrigonometryBlockOperations"].Cos;
@@ -69038,18 +69047,6 @@ var GenericNodeModel = /** @class */ (function (_super) {
                                 transformBlock.complementW = 1;
                             }
                             globalState.onRebuildRequiredObservable.notifyObservers();
-                        }, isSelected: function () { return _this.block.complementW === 0; } })),
-            this.block.getClassName() === "TransformBlock" &&
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_lineContainerComponent__WEBPACK_IMPORTED_MODULE_4__["LineContainerComponent"], { title: "PROPERTIES" },
-                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_6__["CheckBoxLineComponent"], { label: "Transform as direction", onSelect: function (value) {
-                            var transformBlock = _this.block;
-                            if (value) {
-                                transformBlock.complementW = 0;
-                            }
-                            else {
-                                transformBlock.complementW = 1;
-                            }
-                            globalState.onRebuildRequiredObservable.notifyObservers();
                         }, isSelected: function () { return _this.block.complementW === 0; } }))));
     };
     return GenericNodeModel;
@@ -69761,7 +69758,7 @@ var LightPropertyTabComponent = /** @class */ (function (_super) {
         lightOptions.splice(0, 0, { label: "All", value: "" });
         return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", null,
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { title: "GENERAL" },
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_textLineComponent__WEBPACK_IMPORTED_MODULE_2__["TextLineComponent"], { label: "Type", value: "Light" }),
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_textLineComponent__WEBPACK_IMPORTED_MODULE_2__["TextLineComponent"], { label: "Type", value: "LightBlock" }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_textInputLineComponent__WEBPACK_IMPORTED_MODULE_4__["TextInputLineComponent"], { globalState: this.props.globalState, label: "Name", propertyName: "name", target: this.props.node.block, onChange: function () { return _this.props.globalState.onUpdateRequiredObservable.notifyObservers(); } })),
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { title: "PROPERTIES" },
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_optionsLineComponent__WEBPACK_IMPORTED_MODULE_5__["OptionsLineComponent"], { label: "Light", defaultIfNull: 0, noDirectUpdate: true, valuesAreStrings: true, options: lightOptions, target: this.props.node.light, propertyName: "name", onSelect: function (name) {
@@ -69782,6 +69779,225 @@ var LightPropertyTabComponent = /** @class */ (function (_super) {
 
 /***/ }),
 
+/***/ "./components/diagram/lightInformation/lightInformationNodeFactory.tsx":
+/*!*****************************************************************************!*\
+  !*** ./components/diagram/lightInformation/lightInformationNodeFactory.tsx ***!
+  \*****************************************************************************/
+/*! exports provided: LightInformationNodeFactory */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LightInformationNodeFactory", function() { return LightInformationNodeFactory; });
+/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
+/* harmony import */ var storm_react_diagrams__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! storm-react-diagrams */ "../../node_modules/storm-react-diagrams/dist/main.js");
+/* harmony import */ var storm_react_diagrams__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(storm_react_diagrams__WEBPACK_IMPORTED_MODULE_1__);
+/* harmony import */ var _lightInformationNodeWidget__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lightInformationNodeWidget */ "./components/diagram/lightInformation/lightInformationNodeWidget.tsx");
+/* harmony import */ var _lightInformationNodeModel__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./lightInformationNodeModel */ "./components/diagram/lightInformation/lightInformationNodeModel.tsx");
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! react */ "../../node_modules/react/index.js");
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_4__);
+
+
+
+
+
+/**
+ * Node factory which creates editor nodes
+ */
+var LightInformationNodeFactory = /** @class */ (function (_super) {
+    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](LightInformationNodeFactory, _super);
+    /**
+     * Constructs a LightNodeFactory
+     */
+    function LightInformationNodeFactory(globalState) {
+        var _this = _super.call(this, "light-information") || this;
+        _this._globalState = globalState;
+        return _this;
+    }
+    /**
+     * Generates a node widget
+     * @param diagramEngine diagram engine
+     * @param node node to generate
+     * @returns node widget jsx
+     */
+    LightInformationNodeFactory.prototype.generateReactWidget = function (diagramEngine, node) {
+        return react__WEBPACK_IMPORTED_MODULE_4__["createElement"](_lightInformationNodeWidget__WEBPACK_IMPORTED_MODULE_2__["LightInformationNodeWidget"], { node: node, globalState: this._globalState });
+    };
+    /**
+     * Gets a new instance of a node model
+     * @returns light node model
+     */
+    LightInformationNodeFactory.prototype.getNewInstance = function () {
+        return new _lightInformationNodeModel__WEBPACK_IMPORTED_MODULE_3__["LightInformationNodeModel"]();
+    };
+    return LightInformationNodeFactory;
+}(storm_react_diagrams__WEBPACK_IMPORTED_MODULE_1__["AbstractNodeFactory"]));
+
+
+
+/***/ }),
+
+/***/ "./components/diagram/lightInformation/lightInformationNodeModel.tsx":
+/*!***************************************************************************!*\
+  !*** ./components/diagram/lightInformation/lightInformationNodeModel.tsx ***!
+  \***************************************************************************/
+/*! exports provided: LightInformationNodeModel */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LightInformationNodeModel", function() { return LightInformationNodeModel; });
+/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "../../node_modules/react/index.js");
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
+/* harmony import */ var _defaultNodeModel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../defaultNodeModel */ "./components/diagram/defaultNodeModel.ts");
+/* harmony import */ var _lightInformationPropertyTabComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./lightInformationPropertyTabComponent */ "./components/diagram/lightInformation/lightInformationPropertyTabComponent.tsx");
+
+
+
+
+var LightInformationNodeModel = /** @class */ (function (_super) {
+    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](LightInformationNodeModel, _super);
+    /**
+     * Constructs the node model
+     */
+    function LightInformationNodeModel() {
+        return _super.call(this, "light-information") || this;
+    }
+    Object.defineProperty(LightInformationNodeModel.prototype, "light", {
+        /**
+         * Light for the node if it exists
+         */
+        get: function () {
+            return this._block.light;
+        },
+        set: function (value) {
+            this._block.light = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    LightInformationNodeModel.prototype.renderProperties = function (globalState) {
+        return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lightInformationPropertyTabComponent__WEBPACK_IMPORTED_MODULE_3__["LightInformationPropertyTabComponent"], { globalState: globalState, node: this }));
+    };
+    LightInformationNodeModel.prototype.prepare = function (options, nodes, model, graphEditor) {
+        this._block = options.nodeMaterialBlock;
+        _super.prototype.prepare.call(this, options, nodes, model, graphEditor);
+    };
+    return LightInformationNodeModel;
+}(_defaultNodeModel__WEBPACK_IMPORTED_MODULE_2__["DefaultNodeModel"]));
+
+
+
+/***/ }),
+
+/***/ "./components/diagram/lightInformation/lightInformationNodeWidget.tsx":
+/*!****************************************************************************!*\
+  !*** ./components/diagram/lightInformation/lightInformationNodeWidget.tsx ***!
+  \****************************************************************************/
+/*! exports provided: LightInformationNodeWidget */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LightInformationNodeWidget", function() { return LightInformationNodeWidget; });
+/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "../../node_modules/react/index.js");
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
+/* harmony import */ var _portHelper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../portHelper */ "./components/diagram/portHelper.tsx");
+
+
+
+/**
+ * Used to display a node block for the node editor
+ */
+var LightInformationNodeWidget = /** @class */ (function (_super) {
+    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](LightInformationNodeWidget, _super);
+    /**
+     * Creates a GenericNodeWidget
+     * @param props
+     */
+    function LightInformationNodeWidget(props) {
+        var _this = _super.call(this, props) || this;
+        _this.state = {};
+        if (_this.props.node) {
+            _this.props.node.addListener({
+                selectionChanged: function () {
+                    var selected = _this.props.node.selected;
+                    _this.props.globalState.onSelectionChangedObservable.notifyObservers(selected ? _this.props.node : null);
+                }
+            });
+        }
+        return _this;
+    }
+    LightInformationNodeWidget.prototype.render = function () {
+        // Input/Output ports
+        var outputPorts = _portHelper__WEBPACK_IMPORTED_MODULE_2__["PortHelper"].GenerateOutputPorts(this.props.node, false);
+        var inputPorts = _portHelper__WEBPACK_IMPORTED_MODULE_2__["PortHelper"].GenerateInputPorts(this.props.node);
+        return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", { className: "diagramBlock" },
+            react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", { className: "header" }, this.props.node.block.name + " (" + (this.props.node.light ? this.props.node.light.name : "No light") + ")"),
+            react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", { className: "inputs" }, inputPorts),
+            react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", { className: "outputs" }, outputPorts)));
+    };
+    return LightInformationNodeWidget;
+}(react__WEBPACK_IMPORTED_MODULE_1__["Component"]));
+
+
+
+/***/ }),
+
+/***/ "./components/diagram/lightInformation/lightInformationPropertyTabComponent.tsx":
+/*!**************************************************************************************!*\
+  !*** ./components/diagram/lightInformation/lightInformationPropertyTabComponent.tsx ***!
+  \**************************************************************************************/
+/*! exports provided: LightInformationPropertyTabComponent */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LightInformationPropertyTabComponent", function() { return LightInformationPropertyTabComponent; });
+/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "../../node_modules/react/index.js");
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
+/* harmony import */ var _sharedComponents_textLineComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../sharedComponents/textLineComponent */ "./sharedComponents/textLineComponent.tsx");
+/* harmony import */ var _sharedComponents_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../sharedComponents/lineContainerComponent */ "./sharedComponents/lineContainerComponent.tsx");
+/* harmony import */ var _sharedComponents_textInputLineComponent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../sharedComponents/textInputLineComponent */ "./sharedComponents/textInputLineComponent.tsx");
+/* harmony import */ var _sharedComponents_optionsLineComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../sharedComponents/optionsLineComponent */ "./sharedComponents/optionsLineComponent.tsx");
+
+
+
+
+
+
+var LightInformationPropertyTabComponent = /** @class */ (function (_super) {
+    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](LightInformationPropertyTabComponent, _super);
+    function LightInformationPropertyTabComponent() {
+        return _super !== null && _super.apply(this, arguments) || this;
+    }
+    LightInformationPropertyTabComponent.prototype.render = function () {
+        var _this = this;
+        var scene = this.props.globalState.nodeMaterial.getScene();
+        var lightOptions = scene.lights.map(function (l) {
+            return { label: l.name, value: l.name };
+        });
+        return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", null,
+            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { title: "GENERAL" },
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_textLineComponent__WEBPACK_IMPORTED_MODULE_2__["TextLineComponent"], { label: "Type", value: "LightInformationBlock" }),
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_textInputLineComponent__WEBPACK_IMPORTED_MODULE_4__["TextInputLineComponent"], { globalState: this.props.globalState, label: "Name", propertyName: "name", target: this.props.node.block, onChange: function () { return _this.props.globalState.onUpdateRequiredObservable.notifyObservers(); } })),
+            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { title: "PROPERTIES" },
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_optionsLineComponent__WEBPACK_IMPORTED_MODULE_5__["OptionsLineComponent"], { label: "Light", noDirectUpdate: true, valuesAreStrings: true, options: lightOptions, target: this.props.node.light, propertyName: "name", onSelect: function (name) {
+                        _this.props.node.light = scene.getLightByName(name);
+                        _this.forceUpdate();
+                        _this.props.globalState.onRebuildRequiredObservable.notifyObservers();
+                    } }))));
+    };
+    return LightInformationPropertyTabComponent;
+}(react__WEBPACK_IMPORTED_MODULE_1__["Component"]));
+
+
+
+/***/ }),
+
 /***/ "./components/diagram/link/advancedLinkFactory.tsx":
 /*!*********************************************************!*\
   !*** ./components/diagram/link/advancedLinkFactory.tsx ***!
@@ -70948,7 +71164,7 @@ var NodeListComponent = /** @class */ (function (_super) {
         // Block types used to create the menu from
         var allBlocks = {
             Animation: ["BonesBlock", "MorphTargetsBlock"],
-            Basic_Math: ["AddBlock", "DivideBlock", "MultiplyBlock", "ScaleBlock", "SubtractBlock", "OppositeBlock"],
+            Basic_Math: ["AddBlock", "DivideBlock", "MultiplyBlock", "ScaleBlock", "SubtractBlock", "OppositeBlock", "MaxBlock", "MinBlock"],
             Conversion_Blocks: ["ColorMergerBlock", "ColorSplitterBlock", "VectorMergerBlock", "VectorSplitterBlock"],
             Inputs: ["Float", "Vector2", "Vector3", "Vector4", "Color3", "Color4", "TextureBlock", "TimeBlock"],
             Interpolation: ["LerpBlock"],
@@ -70957,7 +71173,7 @@ var NodeListComponent = /** @class */ (function (_super) {
             Output_Blocks: ["VertexOutputBlock", "FragmentOutputBlock", "AlphaTestBlock"],
             Range: ["ClampBlock", "RemapBlock", "NormalizeBlock"],
             Round: ["StepBlock", "RoundBlock", "CeilingBlock", "FloorBlock"],
-            Scene_Attributes: ["FogBlock", "CameraPositionBlock", "FogColorBlock", "ImageProcessingBlock", "LightBlock", "ReflectionTextureBlock", "ViewDirectionBlock"],
+            Scene_Attributes: ["FogBlock", "CameraPositionBlock", "FogColorBlock", "ImageProcessingBlock", "LightBlock", "LightInformationBlock", "ReflectionTextureBlock", "ViewDirectionBlock"],
             Trigonometry: ["CosBlock", "SinBlock", "AbsBlock", "ExpBlock", "Exp2Block"],
             Vector_Math: ["CrossBlock", "DotBlock", "TransformBlock", "FresnelBlock"],
         };
@@ -71623,6 +71839,11 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _components_diagram_trigonometry_trigonometryNodeModel__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./components/diagram/trigonometry/trigonometryNodeModel */ "./components/diagram/trigonometry/trigonometryNodeModel.tsx");
 /* harmony import */ var _components_diagram_clamp_clampNodeFactory__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./components/diagram/clamp/clampNodeFactory */ "./components/diagram/clamp/clampNodeFactory.tsx");
 /* harmony import */ var _components_diagram_clamp_clampNodeModel__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./components/diagram/clamp/clampNodeModel */ "./components/diagram/clamp/clampNodeModel.tsx");
+/* harmony import */ var _components_diagram_lightInformation_lightInformationNodeFactory__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./components/diagram/lightInformation/lightInformationNodeFactory */ "./components/diagram/lightInformation/lightInformationNodeFactory.tsx");
+/* harmony import */ var _components_diagram_lightInformation_lightInformationNodeModel__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./components/diagram/lightInformation/lightInformationNodeModel */ "./components/diagram/lightInformation/lightInformationNodeModel.tsx");
+
+
+
 
 
 
@@ -71692,6 +71913,7 @@ var GraphEditor = /** @class */ (function (_super) {
         _this._engine.registerNodeFactory(new _components_diagram_remap_remapNodeFactory__WEBPACK_IMPORTED_MODULE_21__["RemapNodeFactory"](_this.props.globalState));
         _this._engine.registerNodeFactory(new _components_diagram_trigonometry_trigonometryNodeFactory__WEBPACK_IMPORTED_MODULE_26__["TrigonometryNodeFactory"](_this.props.globalState));
         _this._engine.registerNodeFactory(new _components_diagram_clamp_clampNodeFactory__WEBPACK_IMPORTED_MODULE_28__["ClampNodeFactory"](_this.props.globalState));
+        _this._engine.registerNodeFactory(new _components_diagram_lightInformation_lightInformationNodeFactory__WEBPACK_IMPORTED_MODULE_30__["LightInformationNodeFactory"](_this.props.globalState));
         _this._engine.registerLinkFactory(new _components_diagram_link_advancedLinkFactory__WEBPACK_IMPORTED_MODULE_20__["AdvancedLinkFactory"]());
         _this.props.globalState.onRebuildRequiredObservable.add(function () {
             if (_this.props.globalState.nodeMaterial) {
@@ -71803,6 +72025,9 @@ var GraphEditor = /** @class */ (function (_super) {
         else if (options.nodeMaterialBlock instanceof babylonjs_Materials_Node_Blocks_Dual_textureBlock__WEBPACK_IMPORTED_MODULE_13__["ClampBlock"]) {
             newNode = new _components_diagram_clamp_clampNodeModel__WEBPACK_IMPORTED_MODULE_29__["ClampNodeModel"]();
         }
+        else if (options.nodeMaterialBlock instanceof babylonjs_Materials_Node_Blocks_Dual_textureBlock__WEBPACK_IMPORTED_MODULE_13__["LightInformationBlock"]) {
+            newNode = new _components_diagram_lightInformation_lightInformationNodeModel__WEBPACK_IMPORTED_MODULE_31__["LightInformationNodeModel"]();
+        }
         else {
             newNode = new _components_diagram_generic_genericNodeModel__WEBPACK_IMPORTED_MODULE_4__["GenericNodeModel"]();
         }

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map


Разлика између датотеке није приказан због своје велике величине
+ 157 - 2
dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts


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

@@ -1 +1 @@
-{"engineOnly":167207,"sceneOnly":507666,"minGridMaterial":637194,"minStandardMaterial":766571}
+{"engineOnly":167798,"sceneOnly":508287,"minGridMaterial":637946,"minStandardMaterial":767330}

Разлика између датотеке није приказан због своје велике величине
+ 1174 - 341
dist/preview release/viewer/babylon.module.d.ts


Разлика између датотеке није приказан због своје велике величине
+ 49 - 29
dist/preview release/viewer/babylon.viewer.js


Разлика између датотеке није приказан због своје велике величине
+ 2 - 2
dist/preview release/viewer/babylon.viewer.max.js


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

@@ -23,7 +23,7 @@
 - Individual gizmos can now be enabled/disabled ([Balupg](https://github.com/balupg))
 - Unify preparation of instance attributes. Added `MaterialHelper.PushAttributesForInstances` ([MarkusBillharz](https://github.com/MarkusBillharz))
 - Added support for PBR [irradiance map](https://doc.babylonjs.com/how_to/physically_based_rendering_master#irradiance-map)
-- Ability to set render camera on utility layer instead of using the latest active camera ([TrevorDev](https://github.com/TrevorDev))
+- Added ability to set render camera on utility layer instead of using the latest active camera ([TrevorDev](https://github.com/TrevorDev))
 - Move normalizeToUnitCube to transformNode instead of abstract mesh and add predicate to exclude sub objects when scaling ([TrevorDev](https://github.com/TrevorDev))
 - Method to check if device orientation is available ([TrevorDev](https://github.com/TrevorDev))
 - Added support for sound sprites [Doc](https://doc.babylonjs.com/how_to/playing_sounds_and_music#playing-a-sound-sprite) ([Deltakosh](https://github.com/deltakosh/))

+ 8 - 1
loaders/src/glTF/2.0/glTFLoader.ts

@@ -1546,6 +1546,13 @@ export class GLTFLoader implements IGLTFLoader {
                 return new VertexBuffer(this._babylonScene.getEngine(), data, kind, false);
             });
         }
+        // Load joint indices as a float array since the shaders expect float data but glTF uses unsigned byte/short.
+        // This prevents certain platforms (e.g. D3D) from having to convert the data to float on the fly.
+        else if (kind === VertexBuffer.MatricesIndicesKind) {
+            accessor._babylonVertexBuffer = this._loadFloatAccessorAsync(`/accessors/${accessor.index}`, accessor).then((data) => {
+                return new VertexBuffer(this._babylonScene.getEngine(), data, kind, false);
+            });
+        }
         else {
             const bufferView = ArrayItem.Get(`${context}/bufferView`, this._gltf.bufferViews, accessor.bufferView);
             accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync(bufferView, kind).then((babylonBuffer) => {
@@ -1866,7 +1873,7 @@ export class GLTFLoader implements IGLTFLoader {
             promises.push(this.loadImageAsync(`/images/${image.index}`, image).then((data) => {
                 const name = image.uri || `${this._fileName}#image${image.index}`;
                 const dataUrl = `data:${this._uniqueRootUrl}${name}`;
-                babylonTexture.updateURL(dataUrl, new Blob([data], { type: image.mimeType }));
+                babylonTexture.updateURL(dataUrl, data);
             }));
         }
 

+ 10 - 1
nodeEditor/src/blockTools.ts

@@ -34,6 +34,9 @@ import { NodeMaterialWellKnownValues } from 'babylonjs/Materials/Node/nodeMateri
 import { AnimatedInputBlockTypes } from 'babylonjs/Materials/Node/Blocks/Input/animatedInputBlockTypes';
 import { OppositeBlock } from 'babylonjs/Materials/Node/Blocks/oppositeBlock';
 import { ViewDirectionBlock } from 'babylonjs/Materials/Node/Blocks/viewDirectionBlock';
+import { LightInformationBlock } from 'babylonjs/Materials/Node/Blocks/Vertex/lightInformationBlock';
+import { MaxBlock } from 'babylonjs/Materials/Node/Blocks/maxBlock';
+import { MinBlock } from 'babylonjs/Materials/Node/Blocks/minBlock';
 
 export class BlockTools {
     public static GetBlockFromString(data: string) {
@@ -101,7 +104,13 @@ export class BlockTools {
             case "OppositeBlock":
                 return new OppositeBlock("Opposite");      
             case "ViewDirectionBlock":
-                return new ViewDirectionBlock("View direction");                    
+                return new ViewDirectionBlock("View direction");    
+            case "LightInformationBlock":
+                return new LightInformationBlock("Light information");         
+            case "MaxBlock":
+                return new MaxBlock("Max");       
+            case "MinBlock":
+                return new MinBlock("Min");                                                  
             case "CosBlock": {
                 let cosBlock = new TrigonometryBlock("Cos");
                 cosBlock.operation = TrigonometryBlockOperations.Cos;

+ 1 - 15
nodeEditor/src/components/diagram/generic/genericNodeModel.tsx

@@ -64,21 +64,7 @@ export class GenericNodeModel extends DefaultNodeModel {
                         globalState.onRebuildRequiredObservable.notifyObservers();
                     }} isSelected={() => (this.block as TransformBlock).complementW === 0} />
                 </LineContainerComponent>
-            }
-            {
-                this.block!.getClassName() === "TransformBlock" &&
-                <LineContainerComponent title="PROPERTIES">
-                    <CheckBoxLineComponent label="Transform as direction" onSelect={value => {
-                        let transformBlock = this.block as TransformBlock;
-                        if (value) {
-                            transformBlock.complementW = 0;
-                        } else {
-                            transformBlock.complementW = 1;
-                        }
-                        globalState.onRebuildRequiredObservable.notifyObservers();
-                    }} isSelected={() => (this.block as TransformBlock).complementW === 0} />
-                </LineContainerComponent>
-            }            
+            }        
             </div>
         );
     }

+ 1 - 1
nodeEditor/src/components/diagram/light/lightPropertyTabComponent.tsx

@@ -25,7 +25,7 @@ export class LightPropertyTabComponent extends React.Component<ILightPropertyTab
         return (
             <div>
                 <LineContainerComponent title="GENERAL">
-                    <TextLineComponent label="Type" value="Light" />
+                    <TextLineComponent label="Type" value="LightBlock" />
                     <TextInputLineComponent globalState={this.props.globalState} label="Name" propertyName="name" target={this.props.node.block!} onChange={() => this.props.globalState.onUpdateRequiredObservable.notifyObservers()} />
                 </LineContainerComponent>
 

+ 39 - 0
nodeEditor/src/components/diagram/lightInformation/lightInformationNodeFactory.tsx

@@ -0,0 +1,39 @@
+import * as SRD from "storm-react-diagrams";
+import { LightInformationNodeWidget } from "./lightInformationNodeWidget";
+import { LightInformationNodeModel } from "./lightInformationNodeModel";
+import * as React from "react";
+import { GlobalState } from '../../../globalState';
+
+/**
+ * Node factory which creates editor nodes
+ */
+export class LightInformationNodeFactory extends SRD.AbstractNodeFactory {
+    private _globalState: GlobalState;
+
+	/**
+	 * Constructs a LightNodeFactory
+	 */
+    constructor(globalState: GlobalState) {
+        super("light-information");
+
+        this._globalState = globalState;
+    }
+
+	/**
+	 * Generates a node widget
+	 * @param diagramEngine diagram engine
+	 * @param node node to generate
+	 * @returns node widget jsx
+	 */
+    generateReactWidget(diagramEngine: SRD.DiagramEngine, node: LightInformationNodeModel): JSX.Element {
+        return <LightInformationNodeWidget node={node} globalState={this._globalState} />;
+    }
+
+	/**
+	 * Gets a new instance of a node model
+	 * @returns light node model
+	 */
+    getNewInstance() {
+        return new LightInformationNodeModel();
+    }
+}

+ 44 - 0
nodeEditor/src/components/diagram/lightInformation/lightInformationNodeModel.tsx

@@ -0,0 +1,44 @@
+import * as React from 'react';
+import { Nullable } from 'babylonjs/types';
+import { Light } from 'babylonjs/Lights/light';
+import { DefaultNodeModel } from '../defaultNodeModel';
+import { GlobalState } from '../../../globalState';
+import { LightInformationPropertyTabComponent } from './lightInformationPropertyTabComponent';
+import { NodeCreationOptions, GraphEditor } from '../../../graphEditor';
+import { DiagramModel } from 'storm-react-diagrams/dist/@types/src/models/DiagramModel';
+import { LightInformationBlock } from 'babylonjs/Materials/Node/Blocks/Vertex/lightInformationBlock';
+
+export class LightInformationNodeModel extends DefaultNodeModel {
+    private _block: LightInformationBlock;
+
+	/**
+	 * Light for the node if it exists
+	 */
+    public get light(): Nullable<Light> {
+        return this._block.light;
+    }
+
+    public set light(value: Nullable<Light>) {
+        this._block.light = value;
+    }
+
+	/**
+	 * Constructs the node model
+	 */
+    constructor() {
+        super("light-information");
+    }
+
+    renderProperties(globalState: GlobalState) {
+        return (
+            <LightInformationPropertyTabComponent globalState={globalState} node={this} />
+        );
+    }
+
+    prepare(options: NodeCreationOptions, nodes: Array<DefaultNodeModel>, model: DiagramModel, graphEditor: GraphEditor) {
+        this._block = options.nodeMaterialBlock as LightInformationBlock;
+
+        super.prepare(options, nodes, model, graphEditor);
+    }
+
+}

+ 56 - 0
nodeEditor/src/components/diagram/lightInformation/lightInformationNodeWidget.tsx

@@ -0,0 +1,56 @@
+import * as React from "react";
+import { LightInformationNodeModel } from './lightInformationNodeModel';
+import { Nullable } from 'babylonjs/types';
+import { GlobalState } from '../../../globalState';
+import { PortHelper } from '../portHelper';
+
+/**
+ * GenericNodeWidgetProps
+ */
+export interface ILightInformationNodeWidgetProps {
+    node: Nullable<LightInformationNodeModel>;
+    globalState: GlobalState;
+}
+
+/**
+ * Used to display a node block for the node editor
+ */
+export class LightInformationNodeWidget extends React.Component<ILightInformationNodeWidgetProps> {
+	/**
+	 * Creates a GenericNodeWidget
+	 * @param props 
+	 */
+    constructor(props: ILightInformationNodeWidgetProps) {
+        super(props);
+        this.state = {};
+
+        if (this.props.node) {
+            this.props.node.addListener({
+                selectionChanged: () => {
+                    let selected = (this.props.node as any).selected;
+                    this.props.globalState.onSelectionChangedObservable.notifyObservers(selected ? this.props.node : null);
+                }
+            });
+        }
+    }
+
+    render() {
+        // Input/Output ports
+        var outputPorts = PortHelper.GenerateOutputPorts(this.props.node, false);
+        var inputPorts = PortHelper.GenerateInputPorts(this.props.node);
+
+        return (
+            <div className={"diagramBlock"}>
+                <div className="header">
+                    {`${this.props.node!.block!.name} (${this.props.node!.light ? this.props.node!.light.name : "No light"})`}
+                </div>
+                <div className="inputs">
+                    {inputPorts}
+                </div>
+                <div className="outputs">
+                    {outputPorts}
+                </div>
+            </div>
+        );
+    }
+}

+ 40 - 0
nodeEditor/src/components/diagram/lightInformation/lightInformationPropertyTabComponent.tsx

@@ -0,0 +1,40 @@
+
+import * as React from "react";
+import { GlobalState } from '../../../globalState';
+import { LightInformationNodeModel } from './lightInformationNodeModel';
+import { TextLineComponent } from '../../../sharedComponents/textLineComponent';
+import { LineContainerComponent } from '../../../sharedComponents/lineContainerComponent';
+import { TextInputLineComponent } from '../../../sharedComponents/textInputLineComponent';
+import { OptionsLineComponent } from '../../../sharedComponents/optionsLineComponent';
+
+interface ILightPropertyTabComponentProps {
+    globalState: GlobalState;
+    node: LightInformationNodeModel;
+}
+
+export class LightInformationPropertyTabComponent extends React.Component<ILightPropertyTabComponentProps> {
+
+    render() {
+        let scene = this.props.globalState.nodeMaterial!.getScene();
+        var lightOptions = scene.lights.map(l => {
+            return { label: l.name, value: l.name }
+        });
+
+        return (
+            <div>
+                <LineContainerComponent title="GENERAL">
+                    <TextLineComponent label="Type" value="LightInformationBlock" />
+                    <TextInputLineComponent globalState={this.props.globalState} label="Name" propertyName="name" target={this.props.node.block!} onChange={() => this.props.globalState.onUpdateRequiredObservable.notifyObservers()} />
+                </LineContainerComponent>
+
+                <LineContainerComponent title="PROPERTIES">
+                    <OptionsLineComponent label="Light" noDirectUpdate={true} valuesAreStrings={true} options={lightOptions} target={this.props.node.light} propertyName="name" onSelect={(name: any) => {
+                        this.props.node.light = scene.getLightByName(name);
+                        this.forceUpdate();
+                        this.props.globalState.onRebuildRequiredObservable.notifyObservers();
+                    }} />
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

+ 2 - 2
nodeEditor/src/components/nodeList/nodeListComponent.tsx

@@ -26,7 +26,7 @@ export class NodeListComponent extends React.Component<INodeListComponentProps,
         // Block types used to create the menu from
         const allBlocks = {
             Animation: ["BonesBlock", "MorphTargetsBlock"],
-            Basic_Math: ["AddBlock",  "DivideBlock", "MultiplyBlock", "ScaleBlock", "SubtractBlock", "OppositeBlock"],
+            Basic_Math: ["AddBlock",  "DivideBlock", "MultiplyBlock", "ScaleBlock", "SubtractBlock", "OppositeBlock", "MaxBlock", "MinBlock"],
             Conversion_Blocks: ["ColorMergerBlock", "ColorSplitterBlock", "VectorMergerBlock", "VectorSplitterBlock"],
             Inputs: ["Float", "Vector2", "Vector3", "Vector4", "Color3", "Color4", "TextureBlock", "TimeBlock"],
             Interpolation: ["LerpBlock"],
@@ -35,7 +35,7 @@ export class NodeListComponent extends React.Component<INodeListComponentProps,
             Output_Blocks: ["VertexOutputBlock", "FragmentOutputBlock", "AlphaTestBlock"],
             Range: ["ClampBlock", "RemapBlock", "NormalizeBlock"],
             Round: ["StepBlock", "RoundBlock", "CeilingBlock", "FloorBlock"],
-            Scene_Attributes: ["FogBlock", "CameraPositionBlock", "FogColorBlock", "ImageProcessingBlock", "LightBlock", "ReflectionTextureBlock", "ViewDirectionBlock"],
+            Scene_Attributes: ["FogBlock", "CameraPositionBlock", "FogColorBlock", "ImageProcessingBlock", "LightBlock", "LightInformationBlock", "ReflectionTextureBlock", "ViewDirectionBlock"],
             Trigonometry: ["CosBlock", "SinBlock", "AbsBlock", "ExpBlock", "Exp2Block"],
             Vector_Math: ["CrossBlock", "DotBlock", "TransformBlock", "FresnelBlock"],
         }

+ 7 - 1
nodeEditor/src/graphEditor.tsx

@@ -47,6 +47,9 @@ import { AdvancedLinkModel } from './components/diagram/link/advancedLinkModel';
 import { ClampNodeFactory } from './components/diagram/clamp/clampNodeFactory';
 import { ClampNodeModel } from './components/diagram/clamp/clampNodeModel';
 import { ClampBlock } from 'babylonjs/Materials/Node/Blocks/clampBlock';
+import { LightInformationNodeFactory } from './components/diagram/lightInformation/lightInformationNodeFactory';
+import { LightInformationNodeModel } from './components/diagram/lightInformation/lightInformationNodeModel';
+import { LightInformationBlock } from 'babylonjs/Materials/Node/Blocks/Vertex/lightInformationBlock';
 
 require("storm-react-diagrams/dist/style.min.css");
 require("./main.scss");
@@ -114,7 +117,9 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
         } else if (options.nodeMaterialBlock instanceof RemapBlock) {
             newNode = new RemapNodeModel();
         } else if (options.nodeMaterialBlock instanceof ClampBlock) {
-            newNode = new ClampNodeModel();
+            newNode = new ClampNodeModel();        
+        } else if (options.nodeMaterialBlock instanceof LightInformationBlock) {
+            newNode = new LightInformationNodeModel();
         } else {
             newNode = new GenericNodeModel();
         }
@@ -184,6 +189,7 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
         this._engine.registerNodeFactory(new RemapNodeFactory(this.props.globalState));
         this._engine.registerNodeFactory(new TrigonometryNodeFactory(this.props.globalState));
         this._engine.registerNodeFactory(new ClampNodeFactory(this.props.globalState));
+        this._engine.registerNodeFactory(new LightInformationNodeFactory(this.props.globalState));
         this._engine.registerLinkFactory(new AdvancedLinkFactory());
 
         this.props.globalState.onRebuildRequiredObservable.add(() => {

+ 105 - 0
src/Engines/Native/nativeShaderProcessor.ts

@@ -0,0 +1,105 @@
+import { WebGL2ShaderProcessor } from "../WebGL/webGL2ShaderProcessors";
+import { VertexBuffer } from "../../Meshes/buffer";
+
+// These numbers must match the values for bgfx::Attrib::Enum
+const attributeLocations: { [kind: string]: number } = {
+    [VertexBuffer.PositionKind]: 0,
+    [VertexBuffer.NormalKind]: 1,
+    [VertexBuffer.TangentKind]: 2,
+    [VertexBuffer.ColorKind]: 4,
+    [VertexBuffer.MatricesIndicesKind]: 8,
+    [VertexBuffer.MatricesWeightsKind]: 9,
+};
+
+// Must match bgfx::Attrib::TexCoord0
+const firstGenericAttributeLocation = 10;
+
+// Must match bgfx::Attrib::TexCoord7
+const lastGenericAttributeLocation = 17;
+
+/** @hidden */
+export class NativeShaderProcessor extends WebGL2ShaderProcessor {
+    private _genericAttributeLocation: number;
+    private _varyingLocationCount: number;
+    private _varyingLocationMap: { [name: string]: number };
+    private _replacements: Array<{ searchValue: RegExp, replaceValue: string }>;
+    private _textureCount: number;
+    private _uniforms: Array<string>;
+
+    public lineProcessor(line: string): string {
+        for (const replacement of this._replacements) {
+            line = line.replace(replacement.searchValue, replacement.replaceValue);
+        }
+
+        return line;
+    }
+
+    public attributeProcessor(attribute: string): string {
+        const match = attribute.match(/attribute\s+[^\s]+\s+([^\s]+)\s*(?:\[.+\])?\s*;/)!;
+        const name = match[1];
+
+        let location = attributeLocations[name];
+        if (location === undefined) {
+            location = this._genericAttributeLocation++;
+            if (location > lastGenericAttributeLocation) {
+                throw new Error("Exceeded maximum custom attributes");
+            }
+        }
+
+        return `layout(location=${location}) ${super.attributeProcessor(attribute)}`;
+    }
+
+    public varyingProcessor(varying: string, isFragment: boolean): string {
+        let location: number;
+
+        if (isFragment) {
+            location = this._varyingLocationMap[varying];
+        }
+        else {
+            location = this._varyingLocationCount++;
+            this._varyingLocationMap[varying] = location;
+        }
+
+        return `layout(location=${location}) ${super.varyingProcessor(varying, isFragment)}`;
+    }
+
+    public uniformProcessor(uniform: string): string {
+        const match = uniform.match(/uniform\s+([^\s]+)\s+([^\s]+)\s*(?:\[.+\])?\s*;/)!;
+        const type = match[1];
+        const name = match[2];
+
+        switch (type) {
+            case "sampler2D":
+            case "samplerCube": {
+                const suffix = type.substr(7);
+                const binding = this._textureCount++;
+                this._replacements.push({ searchValue: new RegExp(`\\b${name}\\b`), replaceValue: `sampler${suffix}(${name}Texture, ${name})` });
+                return `layout(binding=${binding}) uniform texture${suffix} ${name}Texture;\nlayout(binding=${binding}) uniform sampler ${name};`;
+            }
+        }
+
+        this._uniforms.push(uniform);
+        return this._uniforms.length === 1 ? "<UNIFORM>" : "";
+    }
+
+    public preProcessor(code: string, defines: string[], isFragment: boolean): string {
+        this._genericAttributeLocation = firstGenericAttributeLocation;
+
+        if (!isFragment) {
+            this._varyingLocationCount = 0;
+            this._varyingLocationMap = {};
+        }
+
+        this._replacements = [];
+        this._textureCount = 0;
+        this._uniforms = [];
+        return code;
+    }
+
+   public postProcessor(code: string, defines: string[], isFragment: boolean): string {
+        code = super.postProcessor(code, defines, isFragment);
+        code = code.replace("<UNIFORM>", `uniform Frame {\n${this._uniforms.join("\n")}\n};`);
+        code = code.replace("out vec4 glFragColor", "layout(location=0) out vec4 glFragColor");
+        return code;
+    }
+}

+ 5 - 4
src/Engines/Processors/shaderCodeNode.ts

@@ -18,6 +18,11 @@ export class ShaderCodeNode {
             let value: string = this.line;
             let processor = options.processor;
             if (processor) {
+                // This must be done before other replacements to avoid mistakenly changing something that was already changed.
+                if (processor.lineProcessor) {
+                    value = processor.lineProcessor(value, options.isFragment);
+                }
+
                 if (processor.attributeProcessor && StringTools.StartsWith(this.line, "attribute")) {
                     value = processor.attributeProcessor(this.line);
                 } else if (processor.varyingProcessor && StringTools.StartsWith(this.line, "varying")) {
@@ -43,10 +48,6 @@ export class ShaderCodeNode {
                         value = processor.endOfUniformBufferProcessor(this.line, options.isFragment);
                     }
                 }
-
-                if (processor.lineProcessor) {
-                    value = processor.lineProcessor(value, options.isFragment);
-                }
             }
 
             result += value + "\r\n";

+ 70 - 46
src/Engines/engine.ts

@@ -708,7 +708,7 @@ export class Engine {
     public _gl: WebGLRenderingContext;
     private _renderingCanvas: Nullable<HTMLCanvasElement>;
     private _windowIsBackground = false;
-    private _webGLVersion = 1.0;
+    protected _webGLVersion = 1.0;
 
     protected _highPrecisionShadersAllowed = true;
     /** @hidden */
@@ -764,7 +764,7 @@ export class Engine {
     public _caps: EngineCapabilities;
     private _pointerLockRequested: boolean;
     private _isStencilEnable: boolean;
-    private _colorWrite = true;
+    protected _colorWrite = true;
 
     private _loadingScreen: ILoadingScreen;
 
@@ -2045,12 +2045,12 @@ export class Engine {
         if (this._activeRenderLoops.length > 0) {
             // Register new frame
             if (this.customAnimationFrameRequester) {
-                this.customAnimationFrameRequester.requestID = Engine.QueueNewFrame(this.customAnimationFrameRequester.renderFunction || this._bindedRenderFunction, this.customAnimationFrameRequester);
+                this.customAnimationFrameRequester.requestID = this._queueNewFrame(this.customAnimationFrameRequester.renderFunction || this._bindedRenderFunction, this.customAnimationFrameRequester);
                 this._frameHandler = this.customAnimationFrameRequester.requestID;
             } else if (this.isVRPresenting()) {
                 this._requestVRFrame();
             } else {
-                this._frameHandler = Engine.QueueNewFrame(this._bindedRenderFunction, this.getHostWindow());
+                this._frameHandler = this._queueNewFrame(this._bindedRenderFunction, this.getHostWindow());
             }
         } else {
             this._renderingQueueLaunched = false;
@@ -2058,6 +2058,14 @@ export class Engine {
     }
 
     /**
+     * Can be used to override the current requestAnimationFrame requester.
+     * @hidden
+     */
+    protected _queueNewFrame(bindedRenderFunction: any, requester?: any): number {
+        return Engine.QueueNewFrame(bindedRenderFunction, requester);
+    }
+
+    /**
      * Register and execute a render loop. The engine can have more than one render function
      * @param renderFunction defines the function to continuously execute
      */
@@ -2071,7 +2079,7 @@ export class Engine {
         if (!this._renderingQueueLaunched) {
             this._renderingQueueLaunched = true;
             this._bindedRenderFunction = this._renderLoop.bind(this);
-            this._frameHandler = Engine.QueueNewFrame(this._bindedRenderFunction, this.getHostWindow());
+            this._frameHandler = this._queueNewFrame(this._bindedRenderFunction, this.getHostWindow());
         }
     }
 
@@ -2676,40 +2684,38 @@ export class Engine {
 
         this.bindIndexBuffer(dataBuffer);
 
-        // Check for 32 bits indices
-        var arrayBuffer;
-        var need32Bits = false;
+        const data = this._normalizeIndexData(indices);
+        this._gl.bufferData(this._gl.ELEMENT_ARRAY_BUFFER, data, updatable ? this._gl.DYNAMIC_DRAW : this._gl.STATIC_DRAW);
+        this._resetIndexBufferBinding();
+        dataBuffer.references = 1;
+        dataBuffer.is32Bits = (data.BYTES_PER_ELEMENT === 4);
+        return dataBuffer;
+    }
 
+    protected _normalizeIndexData(indices: IndicesArray): Uint16Array | Uint32Array
+    {
         if (indices instanceof Uint16Array) {
-            arrayBuffer = indices;
-        } else {
-            //check 32 bit support
-            if (this._caps.uintIndices) {
-                if (indices instanceof Uint32Array) {
-                    arrayBuffer = indices;
-                    need32Bits = true;
-                } else {
-                    //number[] or Int32Array, check if 32 bit is necessary
-                    for (var index = 0; index < indices.length; index++) {
-                        if (indices[index] > 65535) {
-                            need32Bits = true;
-                            break;
-                        }
-                    }
+            return indices;
+        }
 
-                    arrayBuffer = need32Bits ? new Uint32Array(indices) : new Uint16Array(indices);
-                }
+        // Check 32 bit support
+        if (this._caps.uintIndices) {
+            if (indices instanceof Uint32Array) {
+                return indices;
             } else {
-                //no 32 bit support, force conversion to 16 bit (values greater 16 bit are lost)
-                arrayBuffer = new Uint16Array(indices);
+                // number[] or Int32Array, check if 32 bit is necessary
+                for (var index = 0; index < indices.length; index++) {
+                    if (indices[index] > 65535) {
+                        return new Uint32Array(indices);
+                    }
+                }
+
+                return new Uint16Array(indices);
             }
         }
 
-        this._gl.bufferData(this._gl.ELEMENT_ARRAY_BUFFER, arrayBuffer, updatable ? this._gl.DYNAMIC_DRAW : this._gl.STATIC_DRAW);
-        this._resetIndexBufferBinding();
-        dataBuffer.references = 1;
-        dataBuffer.is32Bits = need32Bits;
-        return dataBuffer;
+        // No 32 bit support, force conversion to 16 bit (values greater 16 bit are lost)
+        return new Uint16Array(indices);
     }
 
     /**
@@ -2997,13 +3003,17 @@ export class Engine {
         buffer.references--;
 
         if (buffer.references === 0) {
-            this._gl.deleteBuffer(buffer.underlyingResource);
+            this._deleteBuffer(buffer);
             return true;
         }
 
         return false;
     }
 
+    protected _deleteBuffer(buffer: DataBuffer): void {
+        this._gl.deleteBuffer(buffer.underlyingResource);
+    }
+
     /**
      * Creates a webGL buffer to use with instanciation
      * @param capacity defines the size of the buffer
@@ -3252,8 +3262,12 @@ export class Engine {
         return effect;
     }
 
+    protected static _concatenateShader(source: string, defines: Nullable<string>, shaderVersion: string = ""): string {
+        return shaderVersion + (defines ? defines + "\n" : "") + source;
+    }
+
     private _compileShader(source: string, type: string, defines: Nullable<string>, shaderVersion: string): WebGLShader {
-        return this._compileRawShader(shaderVersion + (defines ? defines + "\n" : "") + source, type);
+        return this._compileRawShader(Engine._concatenateShader(source, defines, shaderVersion), type);
     }
 
     private _compileRawShader(source: string, type: string): WebGLShader {
@@ -3318,7 +3332,7 @@ export class Engine {
      * Creates a new pipeline context
      * @returns the new pipeline
      */
-    public createPipelineContext() {
+    public createPipelineContext(): IPipelineContext {
         var pipelineContext = new WebGLPipelineContext();
         pipelineContext.engine = this;
 
@@ -4188,7 +4202,7 @@ export class Engine {
      */
     public createTexture(urlArg: Nullable<string>, noMipmap: boolean, invertY: boolean, scene: Nullable<Scene>, samplingMode: number = Engine.TEXTURE_TRILINEAR_SAMPLINGMODE,
         onLoad: Nullable<() => void> = null, onError: Nullable<(message: string, exception: any) => void> = null,
-        buffer: Nullable<string | ArrayBuffer | HTMLImageElement | Blob> = null, fallback: Nullable<InternalTexture> = null, format: Nullable<number> = null,
+        buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob> = null, fallback: Nullable<InternalTexture> = null, format: Nullable<number> = null,
         forcedExtension: Nullable<string> = null, excludeLoaders: Array<IInternalTextureLoader> = []): InternalTexture {
         var url = String(urlArg); // assign a new string, so that the original is still available in case of fallback
         var fromData = url.substr(0, 5) === "data:";
@@ -4285,7 +4299,15 @@ export class Engine {
                     onInternalError("Unable to load " + (request ? request.responseURL : url, exception));
                 });
             } else {
-                callback(buffer as ArrayBuffer);
+                //callback(buffer as ArrayBuffer);
+                if (buffer instanceof ArrayBuffer) {
+                    callback(buffer);
+                }
+                else {
+                    if (onError) {
+                        onError("Unable to load: only ArrayBuffer supported here", null);
+                    }
+                }
             }
         } else {
             var onload = (img: HTMLImageElement) => {
@@ -4348,7 +4370,7 @@ export class Engine {
                     FileTools.LoadImage(url, onload, onInternalError, scene ? scene.offlineProvider : null);
                 }
             }
-            else if (typeof buffer === "string" || buffer instanceof ArrayBuffer || buffer instanceof Blob) {
+            else if (typeof buffer === "string" || buffer instanceof ArrayBuffer || ArrayBuffer.isView(buffer) || buffer instanceof Blob) {
                 FileTools.LoadImage(buffer, onload, onInternalError, scene ? scene.offlineProvider : null);
             }
             else {
@@ -5106,7 +5128,7 @@ export class Engine {
         throw _DevTools.WarnImport("Engine.RawTexture");
     }
 
-    private _prepareWebGLTextureContinuation(texture: InternalTexture, scene: Nullable<Scene>, noMipmap: boolean, isCompressed: boolean, samplingMode: number): void {
+    protected _prepareWebGLTextureContinuation(texture: InternalTexture, scene: Nullable<Scene>, noMipmap: boolean, isCompressed: boolean, samplingMode: number): void {
         var gl = this._gl;
         if (!gl) {
             return;
@@ -5228,11 +5250,9 @@ export class Engine {
 
     /** @hidden */
     public _releaseTexture(texture: InternalTexture): void {
-        var gl = this._gl;
-
         this._releaseFramebufferObjects(texture);
 
-        gl.deleteTexture(texture._webGLTexture);
+        this._deleteTexture(texture._webGLTexture);
 
         // Unbind channels
         this.unbindAllTextures();
@@ -5277,14 +5297,18 @@ export class Engine {
         });
     }
 
-    private setProgram(program: WebGLProgram): void {
+    protected _deleteTexture(texture: Nullable<WebGLTexture>): void {
+        this._gl.deleteTexture(texture);
+    }
+
+    protected _setProgram(program: WebGLProgram): void {
         if (this._currentProgram !== program) {
             this._gl.useProgram(program);
             this._currentProgram = program;
         }
     }
 
-    private _boundUniforms: { [key: number]: WebGLUniformLocation } = {};
+    protected _boundUniforms: { [key: number]: WebGLUniformLocation } = {};
 
     /**
      * Binds an effect to the webGL context
@@ -5292,7 +5316,7 @@ export class Engine {
      */
     public bindSamplers(effect: Effect): void {
         let webGLPipelineContext = effect.getPipelineContext() as WebGLPipelineContext;
-        this.setProgram(webGLPipelineContext.program!);
+        this._setProgram(webGLPipelineContext.program!);
         var samplers = effect.getSamplers();
         for (var index = 0; index < samplers.length; index++) {
             var uniform = effect.getUniform(samplers[index]);
@@ -5455,7 +5479,7 @@ export class Engine {
         return this._gl.REPEAT;
     }
 
-    private _setTexture(channel: number, texture: Nullable<BaseTexture>, isPartOfTextureArray = false, depthStencilTexture = false): boolean {
+    protected _setTexture(channel: number, texture: Nullable<BaseTexture>, isPartOfTextureArray = false, depthStencilTexture = false): boolean {
         // Not ready?
         if (!texture) {
             if (this._boundTexturesCache[channel] != null) {

+ 2 - 1
src/Engines/index.ts

@@ -5,4 +5,5 @@ export * from "./nullEngine";
 export * from "./Extensions/index";
 export * from "./IPipelineContext";
 export * from "./WebGL/webGLPipelineContext";
-export * from "./WebGL/webGL2ShaderProcessors";
+export * from "./WebGL/webGL2ShaderProcessors";
+export * from "./nativeEngine";

Разлика између датотеке није приказан због своје велике величине
+ 1284 - 0
src/Engines/nativeEngine.ts


+ 1 - 9
src/Engines/nullEngine.ts

@@ -485,15 +485,7 @@ export class NullEngine extends Engine {
         this._bindTextureDirectly(0, texture);
     }
 
-    /** @hidden */
-    public _releaseBuffer(buffer: DataBuffer): boolean {
-        buffer.references--;
-
-        if (buffer.references === 0) {
-            return true;
-        }
-
-        return false;
+    protected _deleteBuffer(buffer: WebGLBuffer): void {
     }
 
     public releaseEffects() {

+ 18 - 0
src/Lights/directionalLight.ts

@@ -226,6 +226,24 @@ export class DirectionalLight extends ShadowLight {
         return this;
     }
 
+    public transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string): Light {
+        if (this.computeTransformedInformation()) {
+            if (this.getScene().useRightHandedSystem) {
+                effect.setFloat3(lightDataUniformName, -this.transformedDirection.x, -this.transformedDirection.y, -this.transformedDirection.z);
+            } else {
+                effect.setFloat3(lightDataUniformName, this.transformedDirection.x, this.transformedDirection.y, this.transformedDirection.z);
+            }
+            return this;
+        }
+        if (this.getScene().useRightHandedSystem) {
+            effect.setFloat3(lightDataUniformName, -this.direction.x, -this.direction.y, -this.direction.z);
+        } else {
+            effect.setFloat3(lightDataUniformName, this.direction.x, this.direction.y, this.direction.z);
+        }
+
+        return this;
+    }
+
     /**
      * Gets the minZ used for shadow according to both the scene and the light.
      *

+ 6 - 0
src/Lights/hemisphericLight.ts

@@ -101,6 +101,12 @@ export class HemisphericLight extends Light {
         return this;
     }
 
+    public transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string) {
+        var normalizeDirection = Vector3.Normalize(this.direction);
+        effect.setFloat3(lightDataUniformName, normalizeDirection.x, normalizeDirection.y, normalizeDirection.z);
+        return this;
+    }
+
     /**
      * Computes the world matrix of the node
      * @param force defines if the cache version should be invalidated forcing the world matrix to be created from scratch

+ 8 - 0
src/Lights/light.ts

@@ -363,6 +363,14 @@ export abstract class Light extends Node {
     public abstract transferToEffect(effect: Effect, lightIndex: string): Light;
 
     /**
+     * Sets the passed Effect "effect" with the Light information.
+     * @param effect The effect to update
+     * @param lightDataUniformName The uniform used to store light data (position or direction)
+     * @returns The light
+     */
+    public abstract transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string): Light;
+
+    /**
      * Returns the string "Light".
      * @returns the class name
      */

+ 10 - 0
src/Lights/pointLight.ts

@@ -190,6 +190,16 @@ export class PointLight extends ShadowLight {
         return this;
     }
 
+    public transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string) {
+        if (this.computeTransformedInformation()) {
+            effect.setFloat3(lightDataUniformName, this.transformedPosition.x, this.transformedPosition.y, this.transformedPosition.z);        }
+        else {
+            effect.setFloat3(lightDataUniformName, this.position.x, this.position.y, this.position.z);
+        }
+
+        return this;
+    }
+
     /**
      * Prepares the list of defines specific to the light type.
      * @param defines the list of defines

+ 18 - 0
src/Lights/spotLight.ts

@@ -392,6 +392,24 @@ export class SpotLight extends ShadowLight {
         return this;
     }
 
+    public transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string) {
+        var normalizeDirection;
+
+        if (this.computeTransformedInformation()) {
+            normalizeDirection = Vector3.Normalize(this.transformedDirection);
+        } else {
+            normalizeDirection = Vector3.Normalize(this.direction);
+        }
+
+        if (this.getScene().useRightHandedSystem) {
+            effect.setFloat3(lightDataUniformName, -normalizeDirection.x, -normalizeDirection.y, -normalizeDirection.z);
+        } else {
+            effect.setFloat3(lightDataUniformName, normalizeDirection.x, normalizeDirection.y, normalizeDirection.z);
+        }
+
+        return this;
+    }
+
     /**
      * Disposes the light and the associated resources.
      */

+ 2 - 1
src/Materials/Node/Blocks/Vertex/index.ts

@@ -1,4 +1,5 @@
 export * from "./vertexOutputBlock";
 export * from "./bonesBlock";
 export * from "./instancesBlock";
-export * from "./morphTargetsBlock";
+export * from "./morphTargetsBlock";
+export * from "./lightInformationBlock";

+ 132 - 0
src/Materials/Node/Blocks/Vertex/lightInformationBlock.ts

@@ -0,0 +1,132 @@
+import { NodeMaterialBlock } from '../../nodeMaterialBlock';
+import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockConnectionPointTypes';
+import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
+import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
+import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
+import { _TypeStore } from '../../../../Misc/typeStore';
+import { Nullable } from '../../../../types';
+import { Scene } from '../../../../scene';
+import { Effect } from '../../../effect';
+import { NodeMaterial } from '../../nodeMaterial';
+import { Mesh } from '../../../../Meshes/mesh';
+import { Light } from '../../../../Lights/light';
+import { PointLight } from '../../../../Lights/pointLight';
+/**
+ * Block used to get data information from a light
+ */
+export class LightInformationBlock extends NodeMaterialBlock {
+    private _lightDataDefineName: string;
+    private _lightColorDefineName: string;
+
+    /**
+     * Gets or sets the light associated with this block
+     */
+    public light: Nullable<Light>;
+
+    /**
+     * Creates a new LightInformationBlock
+     * @param name defines the block name
+     */
+    public constructor(name: string) {
+        super(name, NodeMaterialBlockTargets.Vertex);
+
+        this.registerInput("worldPosition", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Vertex);
+        this.registerOutput("direction", NodeMaterialBlockConnectionPointTypes.Vector3);
+        this.registerOutput("color", NodeMaterialBlockConnectionPointTypes.Color3);
+    }
+
+    /**
+     * Gets the current class name
+     * @returns the class name
+     */
+    public getClassName() {
+        return "LightInformationBlock";
+    }
+
+    /**
+     * Gets the world position input component
+     */
+    public get worldPosition(): NodeMaterialConnectionPoint {
+        return this._inputs[0];
+    }
+
+    /**
+     * Gets the direction output component
+     */
+    public get direction(): NodeMaterialConnectionPoint {
+        return this._outputs[0];
+    }
+
+    /**
+     * Gets the direction output component
+     */
+    public get color(): NodeMaterialConnectionPoint {
+        return this._outputs[1];
+    }
+
+    public bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {
+        if (!mesh) {
+            return;
+        }
+
+        if (!this.light || !this.light.isEnabled) {
+            effect.setFloat3(this._lightDataDefineName, 0, 0, 0);
+            effect.setFloat3(this._lightColorDefineName, 0, 0, 0);
+            return;
+        }
+
+        this.light.transferToNodeMaterialEffect(effect, this._lightDataDefineName);
+
+        effect.setColor3(this._lightColorDefineName, this.light.diffuse);
+    }
+
+    protected _buildBlock(state: NodeMaterialBuildState) {
+        super._buildBlock(state);
+
+        state.sharedData.bindableBlocks.push(this);
+
+        let direction = this.direction;
+        let color = this.color;
+
+        if (!this.light) {
+            state.compilationString += this._declareOutput(direction, state) + ` = vec3(0.);\r\n`;
+            state.compilationString += this._declareOutput(color, state) + ` = vec3(0.);\r\n`;
+        } else {
+            this._lightDataDefineName = state._getFreeDefineName("lightData");
+            state._emitUniformFromString(this._lightDataDefineName, "vec3");
+
+            this._lightColorDefineName = state._getFreeDefineName("lightColor");
+            state._emitUniformFromString(this._lightColorDefineName, "vec3");
+
+            if (this.light instanceof PointLight) {
+                state.compilationString += this._declareOutput(direction, state) + ` = normalize(${this._lightDataDefineName} - ${this.worldPosition.associatedVariableName}.xyz);\r\n`;
+            } else {
+                state.compilationString += this._declareOutput(direction, state) + ` = ${this._lightDataDefineName};\r\n`;
+            }
+
+            state.compilationString += this._declareOutput(color, state) + ` = ${this._lightColorDefineName};\r\n`;
+        }
+
+        return this;
+    }
+
+    public serialize(): any {
+        let serializationObject = super.serialize();
+
+        if (this.light) {
+            serializationObject.lightId = this.light.id;
+        }
+
+        return serializationObject;
+    }
+
+    public _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {
+        super._deserialize(serializationObject, scene, rootUrl);
+
+        if (serializationObject.lightId) {
+            this.light = scene.getLightByID(serializationObject.lightId);
+        }
+    }
+}
+
+_TypeStore.RegisteredTypes["BABYLON.LightInformationBlock"] = LightInformationBlock;

+ 3 - 1
src/Materials/Node/Blocks/index.ts

@@ -22,4 +22,6 @@ export * from "./subtractBlock";
 export * from "./stepBlock";
 export * from "./oppositeBlock";
 export * from "./viewDirectionBlock";
-export * from "./fresnelBlock";
+export * from "./fresnelBlock";
+export * from "./maxBlock";
+export * from "./minBlock";

+ 66 - 0
src/Materials/Node/Blocks/maxBlock.ts

@@ -0,0 +1,66 @@
+import { NodeMaterialBlock } from '../nodeMaterialBlock';
+import { NodeMaterialBlockConnectionPointTypes } from '../nodeMaterialBlockConnectionPointTypes';
+import { NodeMaterialBuildState } from '../nodeMaterialBuildState';
+import { NodeMaterialConnectionPoint } from '../nodeMaterialBlockConnectionPoint';
+import { NodeMaterialBlockTargets } from '../nodeMaterialBlockTargets';
+import { _TypeStore } from '../../../Misc/typeStore';
+/**
+ * Block used to get the max of 2 values
+ */
+export class MaxBlock extends NodeMaterialBlock {
+    /**
+     * Creates a new MaxBlock
+     * @param name defines the block name
+     */
+    public constructor(name: string) {
+        super(name, NodeMaterialBlockTargets.Neutral);
+
+        this.registerInput("left", NodeMaterialBlockConnectionPointTypes.AutoDetect);
+        this.registerInput("right", NodeMaterialBlockConnectionPointTypes.AutoDetect);
+        this.registerOutput("output", NodeMaterialBlockConnectionPointTypes.BasedOnInput);
+
+        this._outputs[0]._typeConnectionSource = this._inputs[0];
+        this._linkConnectionTypes(0, 1);
+    }
+
+    /**
+     * Gets the current class name
+     * @returns the class name
+     */
+    public getClassName() {
+        return "MaxBlock";
+    }
+
+    /**
+     * Gets the left operand input component
+     */
+    public get left(): NodeMaterialConnectionPoint {
+        return this._inputs[0];
+    }
+
+    /**
+     * Gets the right operand input component
+     */
+    public get right(): NodeMaterialConnectionPoint {
+        return this._inputs[1];
+    }
+
+    /**
+     * Gets the output component
+     */
+    public get output(): NodeMaterialConnectionPoint {
+        return this._outputs[0];
+    }
+
+    protected _buildBlock(state: NodeMaterialBuildState) {
+        super._buildBlock(state);
+
+        let output = this._outputs[0];
+
+        state.compilationString += this._declareOutput(output, state) + ` = max(${this.left.associatedVariableName}, ${this.right.associatedVariableName});\r\n`;
+
+        return this;
+    }
+}
+
+_TypeStore.RegisteredTypes["BABYLON.MaxBlock"] = MaxBlock;

+ 66 - 0
src/Materials/Node/Blocks/minBlock.ts

@@ -0,0 +1,66 @@
+import { NodeMaterialBlock } from '../nodeMaterialBlock';
+import { NodeMaterialBlockConnectionPointTypes } from '../nodeMaterialBlockConnectionPointTypes';
+import { NodeMaterialBuildState } from '../nodeMaterialBuildState';
+import { NodeMaterialConnectionPoint } from '../nodeMaterialBlockConnectionPoint';
+import { NodeMaterialBlockTargets } from '../nodeMaterialBlockTargets';
+import { _TypeStore } from '../../../Misc/typeStore';
+/**
+ * Block used to get the min of 2 values
+ */
+export class MinBlock extends NodeMaterialBlock {
+    /**
+     * Creates a new MinBlock
+     * @param name defines the block name
+     */
+    public constructor(name: string) {
+        super(name, NodeMaterialBlockTargets.Neutral);
+
+        this.registerInput("left", NodeMaterialBlockConnectionPointTypes.AutoDetect);
+        this.registerInput("right", NodeMaterialBlockConnectionPointTypes.AutoDetect);
+        this.registerOutput("output", NodeMaterialBlockConnectionPointTypes.BasedOnInput);
+
+        this._outputs[0]._typeConnectionSource = this._inputs[0];
+        this._linkConnectionTypes(0, 1);
+    }
+
+    /**
+     * Gets the current class name
+     * @returns the class name
+     */
+    public getClassName() {
+        return "MinBlock";
+    }
+
+    /**
+     * Gets the left operand input component
+     */
+    public get left(): NodeMaterialConnectionPoint {
+        return this._inputs[0];
+    }
+
+    /**
+     * Gets the right operand input component
+     */
+    public get right(): NodeMaterialConnectionPoint {
+        return this._inputs[1];
+    }
+
+    /**
+     * Gets the output component
+     */
+    public get output(): NodeMaterialConnectionPoint {
+        return this._outputs[0];
+    }
+
+    protected _buildBlock(state: NodeMaterialBuildState) {
+        super._buildBlock(state);
+
+        let output = this._outputs[0];
+
+        state.compilationString += this._declareOutput(output, state) + ` = min(${this.left.associatedVariableName}, ${this.right.associatedVariableName});\r\n`;
+
+        return this;
+    }
+}
+
+_TypeStore.RegisteredTypes["BABYLON.MinBlock"] = MinBlock;

+ 1 - 1
src/Materials/Node/Blocks/transformBlock.ts

@@ -25,7 +25,7 @@ export class TransformBlock extends NodeMaterialBlock {
      * @param name defines the block name
      */
     public constructor(name: string) {
-        super(name, NodeMaterialBlockTargets.Neutral);
+        super(name, NodeMaterialBlockTargets.Vertex);
 
         this.registerInput("vector", NodeMaterialBlockConnectionPointTypes.AutoDetect);
         this.registerInput("transform", NodeMaterialBlockConnectionPointTypes.Matrix);

+ 6 - 1
src/Materials/Node/nodeMaterial.ts

@@ -457,6 +457,7 @@ export class NodeMaterial extends PushMaterial {
     private _initializeBlock(node: NodeMaterialBlock, state: NodeMaterialBuildState, nodesToProcessForOtherBuildState: NodeMaterialBlock[]) {
         node.initialize(state);
         node.autoConfigure(this);
+        node._preparationId = this._buildId;
 
         if (this.attachedBlocks.indexOf(node) === -1) {
             this.attachedBlocks.push(node);
@@ -473,7 +474,11 @@ export class NodeMaterial extends PushMaterial {
                 if (block !== node) {
                     if (block.target === NodeMaterialBlockTargets.VertexAndFragment) {
                         nodesToProcessForOtherBuildState.push(block);
-                    }
+                    } else if (state.target ===  NodeMaterialBlockTargets.Fragment
+                        && block.target === NodeMaterialBlockTargets.Vertex
+                        && block._preparationId !== this._buildId) {
+                            nodesToProcessForOtherBuildState.push(block);
+                        }
                     this._initializeBlock(block, state, nodesToProcessForOtherBuildState);
                 }
             }

+ 3 - 0
src/Materials/Node/nodeMaterialBlock.ts

@@ -30,6 +30,9 @@ export class NodeMaterialBlock {
     /** @hidden */
     public _outputs = new Array<NodeMaterialConnectionPoint>();
 
+    /** @hidden */
+    public _preparationId: number;
+
     /**
      * Gets or sets the name of the block
      */

+ 1 - 1
src/Materials/Textures/internalTexture.ts

@@ -155,7 +155,7 @@ export class InternalTexture {
     /** @hidden */
     public _dataSource = InternalTexture.DATASOURCE_UNKNOWN;
     /** @hidden */
-    public _buffer: Nullable<string | ArrayBuffer | HTMLImageElement | Blob> = null;
+    public _buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob> = null;
     /** @hidden */
     public _bufferView: Nullable<ArrayBufferView> = null;
     /** @hidden */

+ 3 - 3
src/Materials/Textures/texture.ts

@@ -213,7 +213,7 @@ export class Texture extends BaseTexture {
     protected _initialSamplingMode = Texture.BILINEAR_SAMPLINGMODE;
 
     /** @hidden */
-    public _buffer: Nullable<string | ArrayBuffer | HTMLImageElement | Blob> = null;
+    public _buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob> = null;
     private _deleteBuffer: boolean = false;
     protected _format: Nullable<number> = null;
     private _delayedOnLoad: Nullable<() => void> = null;
@@ -270,7 +270,7 @@ export class Texture extends BaseTexture {
      * @param deleteBuffer define if the buffer we are loading the texture from should be deleted after load
      * @param format define the format of the texture we are trying to load (Engine.TEXTUREFORMAT_RGBA...)
      */
-    constructor(url: Nullable<string>, sceneOrEngine: Nullable<Scene | Engine>, noMipmap: boolean = false, invertY: boolean = true, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: Nullable<() => void> = null, onError: Nullable<(message?: string, exception?: any) => void> = null, buffer: Nullable<string | ArrayBuffer | HTMLImageElement | Blob> = null, deleteBuffer: boolean = false, format?: number) {
+    constructor(url: Nullable<string>, sceneOrEngine: Nullable<Scene | Engine>, noMipmap: boolean = false, invertY: boolean = true, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: Nullable<() => void> = null, onError: Nullable<(message?: string, exception?: any) => void> = null, buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob> = null, deleteBuffer: boolean = false, format?: number) {
         super((sceneOrEngine && sceneOrEngine.getClassName() === "Scene") ? (sceneOrEngine as Scene) : null);
 
         this.name = url || "";
@@ -361,7 +361,7 @@ export class Texture extends BaseTexture {
      * @param buffer the buffer of the texture (defaults to null)
      * @param onLoad callback called when the texture is loaded  (defaults to null)
      */
-    public updateURL(url: string, buffer: Nullable<string | ArrayBuffer | HTMLImageElement | Blob> = null, onLoad?: () => void): void {
+    public updateURL(url: string, buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob> = null, onLoad?: () => void): void {
         if (this.url) {
             this.releaseInternalTexture();
             this.getScene()!.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);

+ 2 - 2
src/Materials/effect.ts

@@ -548,7 +548,7 @@ export class Effect implements IDisposable {
 
     /** @hidden */
     public _loadVertexShader(vertex: any, callback: (data: any) => void): void {
-        if (DomManagement.IsWindowObjectExist()) {
+        if (typeof(HTMLElement) !== "undefined") {
             // DOM element ?
             if (vertex instanceof HTMLElement) {
                 var vertexCode = DomManagement.GetDOMTextContent(vertex);
@@ -590,7 +590,7 @@ export class Effect implements IDisposable {
 
     /** @hidden */
     public _loadFragmentShader(fragment: any, callback: (data: any) => void): void {
-        if (DomManagement.IsWindowObjectExist()) {
+        if (typeof(HTMLElement) !== "undefined") {
             // DOM element ?
             if (fragment instanceof HTMLElement) {
                 var fragmentCode = DomManagement.GetDOMTextContent(fragment);

+ 8 - 0
src/Misc/domManagement.ts

@@ -12,6 +12,14 @@ export class DomManagement {
     }
 
     /**
+     * Checks if the navigator object exists
+     * @returns true if the navigator object exists
+     */
+    public static IsNavigatorAvailable(): boolean {
+        return (typeof navigator) !== "undefined";
+    }
+
+    /**
      * Extracts text content from a DOM element hierarchy
      * @param element defines the root element
      * @returns a string

+ 32 - 14
src/Misc/environmentTextureTools.ts

@@ -60,7 +60,7 @@ interface BufferImageData {
  * Defines the specular data enclosed in the file.
  * This corresponds to the version 1 of the data.
  */
-interface EnvironmentTextureSpecularInfoV1 {
+export interface EnvironmentTextureSpecularInfoV1 {
     /**
      * Defines where the specular Payload is located. It is a runtime value only not stored in the file.
      */
@@ -323,22 +323,17 @@ export class EnvironmentTextureTools {
     }
 
     /**
-     * Uploads the texture info contained in the env file to the GPU.
-     * @param texture defines the internal texture to upload to
-     * @param arrayBuffer defines the buffer cotaining the data to load
-     * @param info defines the texture info retrieved through the GetEnvInfo method
-     * @returns a promise
+     * Creates the ArrayBufferViews used for initializing environment texture image data.
+     * @param arrayBuffer the underlying ArrayBuffer to which the views refer
+     * @param info parameters that determine what views will be created for accessing the underlying buffer
+     * @return the views described by info providing access to the underlying buffer
      */
-    public static UploadEnvLevelsAsync(texture: InternalTexture, arrayBuffer: any, info: EnvironmentTextureInfo): Promise<void> {
+    public static CreateImageDataArrayBufferViews(arrayBuffer: any, info: EnvironmentTextureInfo): Array<Array<ArrayBufferView>> {
         if (info.version !== 1) {
             throw new Error(`Unsupported babylon environment map version "${info.version}"`);
         }
 
-        let specularInfo = info.specular as EnvironmentTextureSpecularInfoV1;
-        if (!specularInfo) {
-            // Nothing else parsed so far
-            return Promise.resolve();
-        }
+        const specularInfo = info.specular as EnvironmentTextureSpecularInfoV1;
 
         // Double checks the enclosed info
         let mipmapsCount = Scalar.Log2(info.width);
@@ -347,8 +342,6 @@ export class EnvironmentTextureTools {
             throw new Error(`Unsupported specular mipmaps number "${specularInfo.mipmaps.length}"`);
         }
 
-        texture._lodGenerationScale = specularInfo.lodGenerationScale;
-
         const imageData = new Array<Array<ArrayBufferView>>(mipmapsCount);
         for (let i = 0; i < mipmapsCount; i++) {
             imageData[i] = new Array<ArrayBufferView>(6);
@@ -358,6 +351,31 @@ export class EnvironmentTextureTools {
             }
         }
 
+        return imageData;
+    }
+
+    /**
+     * Uploads the texture info contained in the env file to the GPU.
+     * @param texture defines the internal texture to upload to
+     * @param arrayBuffer defines the buffer cotaining the data to load
+     * @param info defines the texture info retrieved through the GetEnvInfo method
+     * @returns a promise
+     */
+    public static UploadEnvLevelsAsync(texture: InternalTexture, arrayBuffer: any, info: EnvironmentTextureInfo): Promise<void> {
+        if (info.version !== 1) {
+            throw new Error(`Unsupported babylon environment map version "${info.version}"`);
+        }
+
+        const specularInfo = info.specular as EnvironmentTextureSpecularInfoV1;
+        if (!specularInfo) {
+            // Nothing else parsed so far
+            return Promise.resolve();
+        }
+
+        texture._lodGenerationScale = specularInfo.lodGenerationScale;
+
+        const imageData = EnvironmentTextureTools.CreateImageDataArrayBufferViews(arrayBuffer, info);
+
         return EnvironmentTextureTools.UploadLevelsAsync(texture, imageData);
     }
 

+ 2 - 2
src/Misc/fileTools.ts

@@ -77,11 +77,11 @@ export class FileTools {
      * @param offlineProvider offline provider for caching
      * @returns the HTMLImageElement of the loaded image
      */
-    public static LoadImage(input: string | ArrayBuffer | Blob, onLoad: (img: HTMLImageElement) => void, onError: (message?: string, exception?: any) => void, offlineProvider: Nullable<IOfflineProvider>): HTMLImageElement {
+    public static LoadImage(input: string | ArrayBuffer | ArrayBufferView | Blob, onLoad: (img: HTMLImageElement) => void, onError: (message?: string, exception?: any) => void, offlineProvider: Nullable<IOfflineProvider>): HTMLImageElement {
         let url: string;
         let usingObjectURL = false;
 
-        if (input instanceof ArrayBuffer) {
+        if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) {
             url = URL.createObjectURL(new Blob([input]));
             usingObjectURL = true;
         }

+ 1 - 1
src/Misc/tools.ts

@@ -315,7 +315,7 @@ export class Tools {
         var eventPrefix = "pointer";
 
         // Check if pointer events are supported
-        if (DomManagement.IsWindowObjectExist() && !window.PointerEvent && !navigator.pointerEnabled) {
+        if (DomManagement.IsWindowObjectExist() && !window.PointerEvent && DomManagement.IsNavigatorAvailable() && !navigator.pointerEnabled) {
             eventPrefix = "mouse";
         }
 

+ 5 - 6
src/Shaders/ShadersInclude/bumpFragmentFunctions.fx

@@ -7,16 +7,15 @@
 		uniform mat4 normalMatrix;
 	#endif
 
-	vec3 perturbNormal(mat3 cotangentFrame, vec2 uv, sampler2D textureSampler, float scale)
+	vec3 perturbNormal(mat3 cotangentFrame, vec3 textureSample, float scale)
 	{
-		vec3 map = texture2D(textureSampler, uv).xyz;
-		map = map * 2.0 - 1.0;
+		textureSample = textureSample * 2.0 - 1.0;
 
 		#ifdef NORMALXYSCALE
-			map = normalize(map * vec3(scale, scale, 1.0));
+			textureSample = normalize(textureSample * vec3(scale, scale, 1.0));
 		#endif
 
-		return normalize(cotangentFrame * map);
+		return normalize(cotangentFrame * textureSample);
 	}
 
 	// Thanks to http://www.thetenthplanet.de/archives/1180
@@ -59,7 +58,7 @@
 
 	vec3 perturbNormal(mat3 cotangentFrame, vec2 uv)
 	{
-		return perturbNormal(cotangentFrame, uv, bumpSampler, vBumpInfos.y);
+		return perturbNormal(cotangentFrame, texture2D(bumpSampler, uv).xyz, vBumpInfos.y);
 	}
 
 	// Thanks to http://www.thetenthplanet.de/archives/1180

+ 2 - 2
src/Shaders/ShadersInclude/pbrBRDFFunctions.fx

@@ -15,12 +15,12 @@
 #endif
 
 #ifdef ENVIRONMENTBRDF
-    vec3 getBRDFLookup(float NdotV, float perceptualRoughness, sampler2D brdfSampler) {
+    vec3 getBRDFLookup(float NdotV, float perceptualRoughness) {
         // Indexed on cos(theta) and roughness
         vec2 UV = vec2(NdotV, perceptualRoughness);
         
         // We can find the scale and offset to apply to the specular value.
-        vec4 brdfLookup = texture2D(brdfSampler, UV);
+        vec4 brdfLookup = texture2D(environmentBrdfSampler, UV);
 
         #ifdef ENVIRONMENTBRDF_RGBD
             brdfLookup.rgb = fromRGBD(brdfLookup.rgba);

+ 1 - 1
src/Shaders/ShadersInclude/pbrHelperFunctions.fx

@@ -7,7 +7,7 @@
 
 float convertRoughnessToAverageSlope(float roughness)
 {
-    // Calculate AlphaG as square of roughness; add epsilon to avoid numerical issues
+    // Calculate AlphaG as square of roughness (add epsilon to avoid numerical issues)
     return square(roughness) + MINIMUMVARIANCE;
 }
 

+ 4 - 4
src/Shaders/pbr.fragment.fx

@@ -16,7 +16,7 @@ precision highp float;
 
 // Forces linear space for image processing
 #ifndef FROMLINEARSPACE
-    #define FROMLINEARSPACE;
+    #define FROMLINEARSPACE
 #endif
 
 // Declaration
@@ -662,7 +662,7 @@ void main(void) {
                 clearCoatNormalW = normalize(texture2D(clearCoatBumpSampler, vClearCoatBumpUV + uvOffset).xyz  * 2.0 - 1.0);
                 clearCoatNormalW = normalize(mat3(normalMatrix) * clearCoatNormalW);
             #else
-                clearCoatNormalW = perturbNormal(TBN, vClearCoatBumpUV + uvOffset, clearCoatBumpSampler, vClearCoatBumpInfos.y);
+                clearCoatNormalW = perturbNormal(TBN, texture2D(clearCoatBumpSampler, vClearCoatBumpUV + uvOffset).xyz, vClearCoatBumpInfos.y);
             #endif
         #endif
 
@@ -768,7 +768,7 @@ void main(void) {
     // _____________________________ IBL BRDF + Energy Cons ________________________________
     #if defined(ENVIRONMENTBRDF)
         // BRDF Lookup
-        vec3 environmentBrdf = getBRDFLookup(NdotV, roughness, environmentBrdfSampler);
+        vec3 environmentBrdf = getBRDFLookup(NdotV, roughness);
 
         #ifdef MS_BRDF_ENERGY_CONSERVATION
             vec3 energyConservationFactor = getEnergyConservationFactor(specularEnvironmentR0, environmentBrdf);
@@ -895,7 +895,7 @@ void main(void) {
     #ifdef CLEARCOAT
         #if defined(ENVIRONMENTBRDF) && !defined(REFLECTIONMAP_SKYBOX)
             // BRDF Lookup
-            vec3 environmentClearCoatBrdf = getBRDFLookup(clearCoatNdotV, clearCoatRoughness, environmentBrdfSampler);
+            vec3 environmentClearCoatBrdf = getBRDFLookup(clearCoatNdotV, clearCoatRoughness);
             vec3 clearCoatEnvironmentReflectance = getReflectanceFromBRDFLookup(vec3(vClearCoatRefractionParams.x), environmentClearCoatBrdf);
 
             #ifdef RADIANCEOCCLUSION