Prechádzať zdrojové kódy

Merge pull request #6177 from BabylonJS/master

nightly
David Catuhe 6 rokov pred
rodič
commit
38725fde90
42 zmenil súbory, kde vykonal 1862 pridanie a 1080 odobranie
  1. 151 94
      Playground/babylon.d.txt
  2. 152 93
      dist/preview release/babylon.d.ts
  3. 2 2
      dist/preview release/babylon.js
  4. 444 230
      dist/preview release/babylon.max.js
  5. 1 1
      dist/preview release/babylon.max.js.map
  6. 329 190
      dist/preview release/babylon.module.d.ts
  7. 1 1
      dist/preview release/packagesSizeBaseLine.json
  8. 329 190
      dist/preview release/viewer/babylon.module.d.ts
  9. 50 34
      dist/preview release/viewer/babylon.viewer.js
  10. 1 1
      dist/preview release/viewer/babylon.viewer.max.js
  11. 14 0
      src/Engines/IPipelineContext.ts
  12. 27 0
      src/Engines/WebGL/webGLPipelineContext.ts
  13. 155 107
      src/Engines/engine.ts
  14. 3 1
      src/Engines/index.ts
  15. 20 27
      src/Engines/nullEngine.ts
  16. 2 1
      src/Layers/effectLayer.ts
  17. 2 1
      src/Layers/layer.ts
  18. 2 1
      src/LensFlares/lensFlareSystem.ts
  19. 0 16
      src/LibDeclarations/webgl.d.ts
  20. 2 1
      src/Materials/Textures/Procedurals/proceduralTexture.ts
  21. 32 39
      src/Materials/effect.ts
  22. 3 2
      src/Materials/uniformBuffer.ts
  23. 16 0
      src/Meshes/WebGL/webGLDataBuffer.ts
  24. 4 0
      src/Meshes/abstractMesh.ts
  25. 4 3
      src/Meshes/buffer.ts
  26. 22 0
      src/Meshes/dataBuffer.ts
  27. 5 4
      src/Meshes/geometry.ts
  28. 4 1
      src/Meshes/index.ts
  29. 15 1
      src/Meshes/instancedMesh.ts
  30. 4 19
      src/Meshes/mesh.ts
  31. 20 0
      src/Meshes/meshLODLevel.ts
  32. 3 2
      src/Meshes/subMesh.ts
  33. 2 1
      src/Particles/particleSystem.ts
  34. 1 1
      src/PostProcesses/RenderPipeline/postProcessRenderEffect.ts
  35. 8 0
      src/PostProcesses/depthOfFieldEffect.ts
  36. 3 2
      src/PostProcesses/postProcessManager.ts
  37. 2 1
      src/Rendering/boundingBoxRenderer.ts
  38. 2 1
      src/Rendering/edgesRenderer.ts
  39. 14 4
      src/Rendering/geometryBufferRenderer.ts
  40. 7 5
      src/Shaders/geometry.vertex.fx
  41. 2 1
      src/Sprites/spriteManager.ts
  42. 2 2
      src/scene.ts

+ 151 - 94
Playground/babylon.d.txt

@@ -5213,6 +5213,42 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Class used to store and describe the pipeline context associated with an effect
+     */
+    export interface IPipelineContext {
+        /**
+         * Gets a boolean indicating that this pipeline context is supporting asynchronous creating
+         */
+        isAsync: boolean;
+        /**
+         * Gets a boolean indicating that the context is ready to be used (like shaders / pipelines are compiled and ready for instance)
+         */
+        isReady: boolean;
+    }
+}
+declare module BABYLON {
+    /**
+     * Class used to store gfx data (like WebGLBuffer)
+     */
+    export class DataBuffer {
+        /**
+         * Gets or sets the number of objects referencing this buffer
+         */
+        references: number;
+        /** Gets or sets the size of the underlying buffer */
+        capacity: number;
+        /**
+         * Gets or sets a boolean indicating if the buffer contains 32bits indices
+         */
+        is32Bits: boolean;
+        /**
+         * Gets the underlying buffer
+         */
+        readonly underlyingResource: any;
+    }
+}
+declare module BABYLON {
+    /**
      * Performance monitor tracks rolling average frame-time and frame-time variance over a user defined sliding-window
      */
     export class PerformanceMonitor {
@@ -5478,7 +5514,7 @@ declare module BABYLON {
          * Gets underlying native buffer
          * @returns underlying native buffer
          */
-        getBuffer(): Nullable<WebGLBuffer>;
+        getBuffer(): Nullable<DataBuffer>;
         /**
          * Gets the stride in float32 units (i.e. byte stride / 4).
          * May not be an integer if the byte stride is not divisible by 4.
@@ -5604,7 +5640,7 @@ declare module BABYLON {
          * Gets underlying native buffer
          * @returns underlying native buffer
          */
-        getBuffer(): Nullable<WebGLBuffer>;
+        getBuffer(): Nullable<DataBuffer>;
         /**
          * Gets the stride in float32 units (i.e. byte stride / 4).
          * May not be an integer if the byte stride is not divisible by 4.
@@ -16476,6 +16512,7 @@ declare module BABYLON {
         refreshBoundingInfo(applySkeleton?: boolean): InstancedMesh;
         /** @hidden */
preActivate(): InstancedMesh;
         /** @hidden */
activate(renderId: number): boolean;
+        getWorldMatrix(): Matrix;
         /**
          * Returns the current associated LOD AbstractMesh.
          */
@@ -16986,7 +17023,7 @@ declare module BABYLON {
         protected _epsilon: number;
         protected _indicesCount: number;
         protected _lineShader: ShaderMaterial;
-        protected _ib: WebGLBuffer;
+        protected _ib: DataBuffer;
         protected _buffers: {
             [key: string]: Nullable<VertexBuffer>;
         };
@@ -19144,6 +19181,28 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Class used to represent a specific level of detail of a mesh
+     * @see http://doc.babylonjs.com/how_to/how_to_use_lod
+     */
+    export class MeshLODLevel {
+        /** Defines the distance where this level should star being displayed */
+        distance: number;
+        /** Defines the mesh to use to render this level */
+        mesh: Nullable<Mesh>;
+        /**
+         * Creates a new LOD level
+         * @param distance defines the distance where this level should star being displayed
+         * @param mesh defines the mesh to use to render this level
+         */
+        constructor(
+        /** Defines the distance where this level should star being displayed */
+        distance: number, 
+        /** Defines the mesh to use to render this level */
+        mesh: Nullable<Mesh>);
+    }
+}
+declare module BABYLON {
+    /**
      * Mesh representing the gorund
      */
     export class GroundMesh extends Mesh {
@@ -20343,26 +20402,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Class used to represent a specific level of detail of a mesh
-     * @see http://doc.babylonjs.com/how_to/how_to_use_lod
-     */
-    export class MeshLODLevel {
-        /** Defines the distance where this level should star being displayed */
-        distance: number;
-        /** Defines the mesh to use to render this level */
-        mesh: Nullable<Mesh>;
-        /**
-         * Creates a new LOD level
-         * @param distance defines the distance where this level should star being displayed
-         * @param mesh defines the mesh to use to render this level
-         */
-        constructor(
-        /** Defines the distance where this level should star being displayed */
-        distance: number, 
-        /** Defines the mesh to use to render this level */
-        mesh: Nullable<Mesh>);
-    }
-    /**
      * @hidden
      **/
     export class _CreationDataStorage {
@@ -22170,7 +22209,7 @@ declare module BABYLON {
         render(enableAlphaMode: boolean): SubMesh;
         /**
          * @hidden
-         */
getLinesIndexBuffer(indices: IndicesArray, engine: Engine): WebGLBuffer;
+         */
getLinesIndexBuffer(indices: IndicesArray, engine: Engine): DataBuffer;
         /**
          * Checks if the submesh intersects with a ray
          * @param ray defines the ray to test
@@ -22341,7 +22380,7 @@ declare module BABYLON {
         setVerticesBuffer(buffer: VertexBuffer, totalVertices?: Nullable<number>): void;
         /**
          * Update a specific vertex buffer
-         * This function will directly update the underlying WebGLBuffer according to the passed numeric array or Float32Array
+         * This function will directly update the underlying DataBuffer according to the passed numeric array or Float32Array
          * It will do nothing if the buffer is not updatable
          * @param kind defines the data kind (Position, normal, etc...)
          * @param data defines the data to use
@@ -22358,7 +22397,7 @@ declare module BABYLON {
          */
         updateVerticesData(kind: string, data: FloatArray, updateExtends?: boolean): void;
         private _updateBoundingInfo;
-        /** @hidden */
bind(effect: Nullable<Effect>, indexToBind?: Nullable<WebGLBuffer>): void;
+        /** @hidden */
bind(effect: Nullable<Effect>, indexToBind?: Nullable<DataBuffer>): void;
         /**
          * Gets total number of vertices
          * @returns the total number of vertices
@@ -22432,7 +22471,7 @@ declare module BABYLON {
          * Gets the index buffer
          * @return the index buffer
          */
-        getIndexBuffer(): Nullable<WebGLBuffer>;
+        getIndexBuffer(): Nullable<DataBuffer>;
         /** @hidden */
releaseVertexArrayObject(effect?: Nullable<Effect>): void;
         /**
          * Release the associated resources for a specific mesh
@@ -23829,6 +23868,7 @@ declare module BABYLON {
         /** @hidden */
occlusionQuery: Nullable<WebGLQuery>;
         private _visibility;
         /** @hidden */
isActive: boolean;
+        /** @hidden */
onlyForInstances: boolean;
         /** @hidden */
renderingGroup: Nullable<RenderingGroup>;
         /**
          * Gets or sets mesh visibility between 0 and 1 (default is 1)
@@ -25799,7 +25839,7 @@ declare module BABYLON {
          * The underlying WebGL Uniform buffer.
          * @returns the webgl buffer
          */
-        getBuffer(): Nullable<WebGLBuffer>;
+        getBuffer(): Nullable<DataBuffer>;
         /**
          * std140 layout specifies how to align data within an UBO structure.
          * See https://khronos.org/registry/OpenGL/specs/gl/glspec45.core.pdf#page=159
@@ -26248,6 +26288,29 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
+    /** @hidden */
+    export class WebGLPipelineContext implements IPipelineContext {
+        engine: Engine;
+        program: Nullable<WebGLProgram>;
+        context?: WebGLRenderingContext;
+        vertexShader?: WebGLShader;
+        fragmentShader?: WebGLShader;
+        isParallelCompiled: boolean;
+        onCompiled?: () => void;
+        transformFeedback?: WebGLTransformFeedback | null;
+        readonly isAsync: boolean;
+        readonly isReady: boolean;
+    }
+}
+declare module BABYLON {
+    /** @hidden */
+    export class WebGLDataBuffer extends DataBuffer {
+        private _buffer;
+        constructor(resource: WebGLBuffer);
+        readonly underlyingResource: any;
+    }
+}
+declare module BABYLON {
     /**
      * Settings for finer control over video usage
      */
@@ -27039,7 +27102,7 @@ declare module BABYLON {
         /** @hidden */
         protected _cachedVertexBuffers: any;
         /** @hidden */
-        protected _cachedIndexBuffer: Nullable<WebGLBuffer>;
+        protected _cachedIndexBuffer: Nullable<DataBuffer>;
         /** @hidden */
         protected _cachedEffectForVertexBuffers: Nullable<Effect>;
         /** @hidden */
currentRenderTarget: Nullable<InternalTexture>;
@@ -27501,14 +27564,14 @@ declare module BABYLON {
          * @param elements defines the content of the uniform buffer
          * @returns the webGL uniform buffer
          */
-        createUniformBuffer(elements: FloatArray): WebGLBuffer;
+        createUniformBuffer(elements: FloatArray): DataBuffer;
         /**
          * Create a dynamic uniform buffer
          * @see http://doc.babylonjs.com/features/webgl2#uniform-buffer-objets
          * @param elements defines the content of the uniform buffer
          * @returns the webGL uniform buffer
          */
-        createDynamicUniformBuffer(elements: FloatArray): WebGLBuffer;
+        createDynamicUniformBuffer(elements: FloatArray): DataBuffer;
         /**
          * Update an existing uniform buffer
          * @see http://doc.babylonjs.com/features/webgl2#uniform-buffer-objets
@@ -27517,27 +27580,27 @@ declare module BABYLON {
          * @param offset defines the offset in the uniform buffer where update should start
          * @param count defines the size of the data to update
          */
-        updateUniformBuffer(uniformBuffer: WebGLBuffer, elements: FloatArray, offset?: number, count?: number): void;
+        updateUniformBuffer(uniformBuffer: DataBuffer, elements: FloatArray, offset?: number, count?: number): void;
         private _resetVertexBufferBinding;
         /**
          * Creates a vertex buffer
          * @param data the data for the vertex buffer
          * @returns the new WebGL static buffer
          */
-        createVertexBuffer(data: DataArray): WebGLBuffer;
+        createVertexBuffer(data: DataArray): DataBuffer;
         /**
          * Creates a dynamic vertex buffer
          * @param data the data for the dynamic vertex buffer
          * @returns the new WebGL dynamic buffer
          */
-        createDynamicVertexBuffer(data: DataArray): WebGLBuffer;
+        createDynamicVertexBuffer(data: DataArray): DataBuffer;
         /**
          * Update a dynamic index buffer
          * @param indexBuffer defines the target index buffer
          * @param indices defines the data to update
          * @param offset defines the offset in the target index buffer where update should start
          */
-        updateDynamicIndexBuffer(indexBuffer: WebGLBuffer, indices: IndicesArray, offset?: number): void;
+        updateDynamicIndexBuffer(indexBuffer: DataBuffer, indices: IndicesArray, offset?: number): void;
         /**
          * Updates a dynamic vertex buffer.
          * @param vertexBuffer the vertex buffer to update
@@ -27545,7 +27608,7 @@ declare module BABYLON {
          * @param byteOffset the byte offset of the data
          * @param byteLength the byte length of the data
          */
-        updateDynamicVertexBuffer(vertexBuffer: WebGLBuffer, data: DataArray, byteOffset?: number, byteLength?: number): void;
+        updateDynamicVertexBuffer(vertexBuffer: DataBuffer, data: DataArray, byteOffset?: number, byteLength?: number): void;
         private _resetIndexBufferBinding;
         /**
          * Creates a new index buffer
@@ -27553,30 +27616,30 @@ declare module BABYLON {
          * @param updatable defines if the index buffer must be updatable
          * @returns a new webGL buffer
          */
-        createIndexBuffer(indices: IndicesArray, updatable?: boolean): WebGLBuffer;
+        createIndexBuffer(indices: IndicesArray, updatable?: boolean): DataBuffer;
         /**
          * Bind a webGL buffer to the webGL context
          * @param buffer defines the buffer to bind
          */
-        bindArrayBuffer(buffer: Nullable<WebGLBuffer>): void;
+        bindArrayBuffer(buffer: Nullable<DataBuffer>): void;
         /**
          * Bind an uniform buffer to the current webGL context
          * @param buffer defines the buffer to bind
          */
-        bindUniformBuffer(buffer: Nullable<WebGLBuffer>): void;
+        bindUniformBuffer(buffer: Nullable<DataBuffer>): void;
         /**
          * Bind a buffer to the current webGL context at a given location
          * @param buffer defines the buffer to bind
          * @param location defines the index where to bind the buffer
          */
-        bindUniformBufferBase(buffer: WebGLBuffer, location: number): void;
+        bindUniformBufferBase(buffer: DataBuffer, location: number): void;
         /**
          * Bind a specific block at a given index in a specific shader program
-         * @param shaderProgram defines the shader program
+         * @param pipelineContext defines the pipeline context to use
          * @param blockName defines the block name
          * @param index defines the index where to bind the block
          */
-        bindUniformBlock(shaderProgram: WebGLProgram, blockName: string, index: number): void;
+        bindUniformBlock(pipelineContext: IPipelineContext, blockName: string, index: number): void;
         private bindIndexBuffer;
         private bindBuffer;
         /**
@@ -27597,14 +27660,14 @@ declare module BABYLON {
          */
         recordVertexArrayObject(vertexBuffers: {
             [key: string]: VertexBuffer;
-        }, indexBuffer: Nullable<WebGLBuffer>, effect: Effect): WebGLVertexArrayObject;
+        }, indexBuffer: Nullable<DataBuffer>, effect: Effect): WebGLVertexArrayObject;
         /**
          * Bind a specific vertex array object
          * @see http://doc.babylonjs.com/features/webgl2#vertex-array-objects
          * @param vertexArrayObject defines the vertex array object to bind
          * @param indexBuffer defines the index buffer to bind
          */
-        bindVertexArrayObject(vertexArrayObject: WebGLVertexArrayObject, indexBuffer: Nullable<WebGLBuffer>): void;
+        bindVertexArrayObject(vertexArrayObject: WebGLVertexArrayObject, indexBuffer: Nullable<DataBuffer>): void;
         /**
          * Bind webGl buffers directly to the webGL context
          * @param vertexBuffer defines the vertex buffer to bind
@@ -27613,7 +27676,7 @@ declare module BABYLON {
          * @param vertexStrideSize defines the vertex stride of the vertex buffer
          * @param effect defines the effect associated with the vertex buffer
          */
-        bindBuffersDirectly(vertexBuffer: WebGLBuffer, indexBuffer: WebGLBuffer, vertexDeclaration: number[], vertexStrideSize: number, effect: Effect): void;
+        bindBuffersDirectly(vertexBuffer: DataBuffer, indexBuffer: DataBuffer, vertexDeclaration: number[], vertexStrideSize: number, effect: Effect): void;
         private _unbindVertexArrayObject;
         /**
          * Bind a list of vertex buffers to the webGL context
@@ -27623,7 +27686,7 @@ declare module BABYLON {
          */
         bindBuffers(vertexBuffers: {
             [key: string]: Nullable<VertexBuffer>;
-        }, indexBuffer: Nullable<WebGLBuffer>, effect: Effect): void;
+        }, indexBuffer: Nullable<DataBuffer>, effect: Effect): void;
         /**
          * Unbind all instance attributes
          */
@@ -27633,13 +27696,13 @@ declare module BABYLON {
          * @param vao defines the vertex array object to delete
          */
         releaseVertexArrayObject(vao: WebGLVertexArrayObject): void;
-        /** @hidden */
releaseBuffer(buffer: WebGLBuffer): boolean;
+        /** @hidden */
releaseBuffer(buffer: DataBuffer): boolean;
         /**
          * Creates a webGL buffer to use with instanciation
          * @param capacity defines the size of the buffer
          * @returns the webGL buffer
          */
-        createInstancesBuffer(capacity: number): WebGLBuffer;
+        createInstancesBuffer(capacity: number): DataBuffer;
         /**
          * Delete a webGL buffer used with instanciation
          * @param buffer defines the webGL buffer to delete
@@ -27651,7 +27714,7 @@ declare module BABYLON {
          * @param data defines the data to store in the buffer
          * @param offsetLocations defines the offsets or attributes information used to determine where data must be stored in the buffer
          */
-        updateAndBindInstancesBuffer(instancesBuffer: WebGLBuffer, data: Float32Array, offsetLocations: number[] | InstancingAttributeInfo[]): void;
+        updateAndBindInstancesBuffer(instancesBuffer: DataBuffer, data: Float32Array, offsetLocations: number[] | InstancingAttributeInfo[]): void;
         /**
          * Apply all cached states (depth, culling, stencil and alpha)
          */
@@ -27697,7 +27760,7 @@ declare module BABYLON {
         drawArraysType(fillMode: number, verticesStart: number, verticesCount: number, instancesCount?: number): void;
         private _drawMode;
         /** @hidden */
releaseEffect(effect: Effect): void;
-        /** @hidden */
deleteProgram(program: WebGLProgram): void;
+        /** @hidden */
deletePipelineContext(pipelineContext: IPipelineContext): void;
         /**
          * Create a new effect (used to store vertex/fragment shaders)
          * @param baseName defines the base name of the effect (The name of file without .fragment.fx or .vertex.fx)
@@ -27716,15 +27779,17 @@ declare module BABYLON {
         private _compileRawShader;
         /**
          * Directly creates a webGL program
+         * @param pipelineContext  defines the pipeline context to attach to
          * @param vertexCode defines the vertex shader code to use
          * @param fragmentCode defines the fragment shader code to use
          * @param context defines the webGL context to use (if not set, the current one will be used)
          * @param transformFeedbackVaryings defines the list of transform feedback varyings to use
          * @returns the new webGL program
          */
-        createRawShaderProgram(vertexCode: string, fragmentCode: string, context?: WebGLRenderingContext, transformFeedbackVaryings?: Nullable<string[]>): WebGLProgram;
+        createRawShaderProgram(pipelineContext: IPipelineContext, vertexCode: string, fragmentCode: string, context?: WebGLRenderingContext, transformFeedbackVaryings?: Nullable<string[]>): WebGLProgram;
         /**
          * Creates a webGL program
+         * @param pipelineContext  defines the pipeline context to attach to
          * @param vertexCode  defines the vertex shader code to use
          * @param fragmentCode defines the fragment shader code to use
          * @param defines defines the string containing the defines to use to compile the shaders
@@ -27732,25 +27797,31 @@ declare module BABYLON {
          * @param transformFeedbackVaryings defines the list of transform feedback varyings to use
          * @returns the new webGL program
          */
-        createShaderProgram(vertexCode: string, fragmentCode: string, defines: Nullable<string>, context?: WebGLRenderingContext, transformFeedbackVaryings?: Nullable<string[]>): WebGLProgram;
+        createShaderProgram(pipelineContext: IPipelineContext, vertexCode: string, fragmentCode: string, defines: Nullable<string>, context?: WebGLRenderingContext, transformFeedbackVaryings?: Nullable<string[]>): WebGLProgram;
+        /**
+         * Creates a new pipeline context
+         * @returns the new pipeline
+         */
+        createPipelineContext(): WebGLPipelineContext;
         private _createShaderProgram;
-        private _finalizeProgram;
-        /** @hidden */
isProgramCompiled(shaderProgram: WebGLProgram): boolean;
-        /** @hidden */
executeWhenProgramIsCompiled(shaderProgram: WebGLProgram, action: () => void): void;
+        private _finalizePipelineContext;
+        /** @hidden */
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;
         /**
          * Gets the list of webGL uniform locations associated with a specific program based on a list of uniform names
-         * @param shaderProgram defines the webGL program to use
+         * @param pipelineContext defines the pipeline context to use
          * @param uniformsNames defines the list of uniform names
          * @returns an array of webGL uniform locations
          */
-        getUniforms(shaderProgram: WebGLProgram, uniformsNames: string[]): Nullable<WebGLUniformLocation>[];
+        getUniforms(pipelineContext: IPipelineContext, uniformsNames: string[]): Nullable<WebGLUniformLocation>[];
         /**
          * Gets the lsit of active attributes for a given webGL program
-         * @param shaderProgram defines the webGL program to use
+         * @param pipelineContext defines the pipeline context to use
          * @param attributesNames defines the list of attribute names to get
          * @returns an array of indices indicating the offset of each attribute
          */
-        getAttributes(shaderProgram: WebGLProgram, attributesNames: string[]): number[];
+        getAttributes(pipelineContext: IPipelineContext, attributesNames: string[]): number[];
         /**
          * Activates an effect, mkaing it the current one (ie. the one used for rendering)
          * @param effect defines the effect to activate
@@ -28491,7 +28562,7 @@ declare module BABYLON {
         /**
          * Compiled shader to webGL program.
          * @hidden
-         */
program: WebGLProgram;
+         */
pipelineContext: IPipelineContext;
         private _valueCache;
         private static _baseCache;
         /**
@@ -28524,10 +28595,10 @@ declare module BABYLON {
          */
         getEngine(): Engine;
         /**
-         * The compiled webGL program for the effect
-         * @returns the webGL program.
+         * The pipeline context for this effect
+         * @returns the associated pipeline context
          */
-        getProgram(): WebGLProgram;
+        getPipelineContext(): IPipelineContext;
         /**
          * The set of names of attribute variables for the shader.
          * @returns An array of attribute names.
@@ -28591,13 +28662,7 @@ declare module BABYLON {
          * @param onCompiled Callback called when completed.
          * @param onError Callback called on error.
          * @hidden
-         */
rebuildProgram(vertexSourceCode: string, fragmentSourceCode: string, onCompiled: (program: WebGLProgram) => void, onError: (message: string) => void): void;
-        /**
-         * Gets the uniform locations of the the specified variable names
-         * @param names THe names of the variables to lookup.
-         * @returns Array of locations in the same order as variable names.
-         */
-        getSpecificUniformLocations(names: string[]): Nullable<WebGLUniformLocation>[];
+         */
rebuildProgram(vertexSourceCode: string, fragmentSourceCode: string, onCompiled: (pipelineContext: IPipelineContext) => void, onError: (message: string) => void): void;
         /**
          * Prepares the effect
          * @hidden
@@ -28652,7 +28717,7 @@ declare module BABYLON {
          * @param buffer Buffer to bind.
          * @param name Name of the uniform variable to bind to.
          */
-        bindUniformBuffer(buffer: WebGLBuffer, name: string): void;
+        bindUniformBuffer(buffer: DataBuffer, name: string): void;
         /**
          * Binds block to a uniform.
          * @param blockName Name of the block to bind.
@@ -40467,15 +40532,15 @@ declare module BABYLON {
          */
         getHardwareScalingLevel(): number;
         constructor(options?: NullEngineOptions);
-        createVertexBuffer(vertices: FloatArray): WebGLBuffer;
-        createIndexBuffer(indices: IndicesArray): WebGLBuffer;
+        createVertexBuffer(vertices: FloatArray): DataBuffer;
+        createIndexBuffer(indices: IndicesArray): DataBuffer;
         clear(color: Color4, backBuffer: boolean, depth: boolean, stencil?: boolean): void;
         getRenderWidth(useScreen?: boolean): number;
         getRenderHeight(useScreen?: boolean): number;
         setViewport(viewport: Viewport, requiredWidth?: number, requiredHeight?: number): void;
-        createShaderProgram(vertexCode: string, fragmentCode: string, defines: string, context?: WebGLRenderingContext): WebGLProgram;
-        getUniforms(shaderProgram: WebGLProgram, uniformsNames: string[]): WebGLUniformLocation[];
-        getAttributes(shaderProgram: WebGLProgram, attributesNames: string[]): number[];
+        createShaderProgram(pipelineContext: IPipelineContext, vertexCode: string, fragmentCode: string, defines: string, context?: WebGLRenderingContext): WebGLProgram;
+        getUniforms(pipelineContext: IPipelineContext, uniformsNames: string[]): Nullable<WebGLUniformLocation>[];
+        getAttributes(pipelineContext: IPipelineContext, attributesNames: string[]): number[];
         bindSamplers(effect: Effect): void;
         enableEffect(effect: Effect): void;
         setState(culling: boolean, zOffset?: number, force?: boolean, reverseSide?: boolean): void;
@@ -40505,7 +40570,7 @@ declare module BABYLON {
         setAlphaMode(mode: number, noDepthWriteChange?: boolean): void;
         bindBuffers(vertexBuffers: {
             [key: string]: VertexBuffer;
-        }, indexBuffer: WebGLBuffer, effect: Effect): void;
+        }, indexBuffer: DataBuffer, effect: Effect): void;
         wipeCaches(bruteForce?: boolean): void;
         draw(useTriangles: boolean, indexStart: number, indexCount: number, instancesCount?: number): void;
         drawElementsType(fillMode: number, indexStart: number, indexCount: number, instancesCount?: number): void;
@@ -40517,7 +40582,7 @@ declare module BABYLON {
         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(vertices: FloatArray): WebGLBuffer;
+        createDynamicVertexBuffer(vertices: FloatArray): DataBuffer;
         updateDynamicTexture(texture: Nullable<InternalTexture>, canvas: HTMLCanvasElement, invertY: boolean, premulAlpha?: boolean, format?: number): void;
         areAllEffectsReady(): boolean;
         /**
@@ -40539,7 +40604,7 @@ declare module BABYLON {
          */
         updateDynamicVertexBuffer(vertexBuffer: WebGLBuffer, vertices: FloatArray, byteOffset?: number, byteLength?: number): void;
bindTextureDirectly(target: number, texture: InternalTexture): boolean;
         /** @hidden */
bindTexture(channel: number, texture: InternalTexture): void;
-        /** @hidden */
releaseBuffer(buffer: WebGLBuffer): boolean;
+        /** @hidden */
releaseBuffer(buffer: DataBuffer): boolean;
         releaseEffects(): void;
         displayLoadingUI(): void;
         hideLoadingUI(): void;
@@ -51361,7 +51426,7 @@ declare module BABYLON {
          * @hidden
          */
attachCameras(cameras: Camera[]): void;
         /**
-         * Detatches the effect on cameras
+         * Detaches the effect on cameras
          * @param cameras The camera to detatch from.
          * @hidden
          */
detachCameras(cameras: Camera): void;
@@ -51830,6 +51895,11 @@ declare module BABYLON {
          */
         constructor(scene: Scene, depthTexture: Nullable<RenderTargetTexture>, blurLevel?: DepthOfFieldEffectBlurLevel, pipelineTextureType?: number, blockCompilation?: boolean);
         /**
+        * Get the current class name of the current effet
+        * @returns "DepthOfFieldEffect"
+        */
+        getClassName(): string;
+        /**
          * Depth texture to be used to compute the circle of confusion. This must be set here or in the constructor in order for the post process to function.
          */
         depthTexture: RenderTargetTexture;
@@ -55639,13 +55709,6 @@ interface Math {
     fround(x: number): number;
     imul(a: number, b: number): number;
 }
-interface WebGLProgram {
-    context?: WebGLRenderingContext;
-    vertexShader?: WebGLShader;
-    fragmentShader?: WebGLShader;
-    isParallelCompiled: boolean;
-    onCompiled?: () => void;
-}
 interface WebGLRenderingContext {
     drawArraysInstanced(mode: number, first: number, count: number, primcount: number): void;
     drawElementsInstanced(mode: number, count: number, type: number, offset: number, primcount: number): void;
@@ -55698,13 +55761,7 @@ interface WebGLRenderingContext {
     QUERY_RESULT_AVAILABLE: number;
     QUERY_RESULT: number;
 }
-interface WebGLBuffer {
-    references: number;
-    capacity: number;
-    is32Bits: boolean;
-}
-interface WebGLProgram {
-    transformFeedback?: WebGLTransformFeedback | null;
private _SPECTOR_rebuildProgram?: ((vertexSourceCode: string, fragmentSourceCode: string, onCompiled: (program: WebGLProgram) => void, onError: (message: string) => void) => void) | null;
+interface WebGLProgram {
private _SPECTOR_rebuildProgram?: ((vertexSourceCode: string, fragmentSourceCode: string, onCompiled: (program: WebGLProgram) => void, onError: (message: string) => void) => void) | null;
 }
 interface EXT_disjoint_timer_query {
     QUERY_COUNTER_BITS_EXT: number;

+ 152 - 93
dist/preview release/babylon.d.ts

@@ -5229,6 +5229,42 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Class used to store and describe the pipeline context associated with an effect
+     */
+    export interface IPipelineContext {
+        /**
+         * Gets a boolean indicating that this pipeline context is supporting asynchronous creating
+         */
+        isAsync: boolean;
+        /**
+         * Gets a boolean indicating that the context is ready to be used (like shaders / pipelines are compiled and ready for instance)
+         */
+        isReady: boolean;
+    }
+}
+declare module BABYLON {
+    /**
+     * Class used to store gfx data (like WebGLBuffer)
+     */
+    export class DataBuffer {
+        /**
+         * Gets or sets the number of objects referencing this buffer
+         */
+        references: number;
+        /** Gets or sets the size of the underlying buffer */
+        capacity: number;
+        /**
+         * Gets or sets a boolean indicating if the buffer contains 32bits indices
+         */
+        is32Bits: boolean;
+        /**
+         * Gets the underlying buffer
+         */
+        readonly underlyingResource: any;
+    }
+}
+declare module BABYLON {
+    /**
      * Performance monitor tracks rolling average frame-time and frame-time variance over a user defined sliding-window
      */
     export class PerformanceMonitor {
@@ -5495,7 +5531,7 @@ declare module BABYLON {
          * Gets underlying native buffer
          * @returns underlying native buffer
          */
-        getBuffer(): Nullable<WebGLBuffer>;
+        getBuffer(): Nullable<DataBuffer>;
         /**
          * Gets the stride in float32 units (i.e. byte stride / 4).
          * May not be an integer if the byte stride is not divisible by 4.
@@ -5624,7 +5660,7 @@ declare module BABYLON {
          * Gets underlying native buffer
          * @returns underlying native buffer
          */
-        getBuffer(): Nullable<WebGLBuffer>;
+        getBuffer(): Nullable<DataBuffer>;
         /**
          * Gets the stride in float32 units (i.e. byte stride / 4).
          * May not be an integer if the byte stride is not divisible by 4.
@@ -16737,6 +16773,7 @@ declare module BABYLON {
         _preActivate(): InstancedMesh;
         /** @hidden */
         _activate(renderId: number): boolean;
+        getWorldMatrix(): Matrix;
         /**
          * Returns the current associated LOD AbstractMesh.
          */
@@ -17251,7 +17288,7 @@ declare module BABYLON {
         protected _epsilon: number;
         protected _indicesCount: number;
         protected _lineShader: ShaderMaterial;
-        protected _ib: WebGLBuffer;
+        protected _ib: DataBuffer;
         protected _buffers: {
             [key: string]: Nullable<VertexBuffer>;
         };
@@ -19437,6 +19474,28 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Class used to represent a specific level of detail of a mesh
+     * @see http://doc.babylonjs.com/how_to/how_to_use_lod
+     */
+    export class MeshLODLevel {
+        /** Defines the distance where this level should star being displayed */
+        distance: number;
+        /** Defines the mesh to use to render this level */
+        mesh: Nullable<Mesh>;
+        /**
+         * Creates a new LOD level
+         * @param distance defines the distance where this level should star being displayed
+         * @param mesh defines the mesh to use to render this level
+         */
+        constructor(
+        /** Defines the distance where this level should star being displayed */
+        distance: number, 
+        /** Defines the mesh to use to render this level */
+        mesh: Nullable<Mesh>);
+    }
+}
+declare module BABYLON {
+    /**
      * Mesh representing the gorund
      */
     export class GroundMesh extends Mesh {
@@ -20649,26 +20708,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Class used to represent a specific level of detail of a mesh
-     * @see http://doc.babylonjs.com/how_to/how_to_use_lod
-     */
-    export class MeshLODLevel {
-        /** Defines the distance where this level should star being displayed */
-        distance: number;
-        /** Defines the mesh to use to render this level */
-        mesh: Nullable<Mesh>;
-        /**
-         * Creates a new LOD level
-         * @param distance defines the distance where this level should star being displayed
-         * @param mesh defines the mesh to use to render this level
-         */
-        constructor(
-        /** Defines the distance where this level should star being displayed */
-        distance: number, 
-        /** Defines the mesh to use to render this level */
-        mesh: Nullable<Mesh>);
-    }
-    /**
      * @hidden
      **/
     export class _CreationDataStorage {
@@ -22524,7 +22563,7 @@ declare module BABYLON {
         /**
          * @hidden
          */
-        _getLinesIndexBuffer(indices: IndicesArray, engine: Engine): WebGLBuffer;
+        _getLinesIndexBuffer(indices: IndicesArray, engine: Engine): DataBuffer;
         /**
          * Checks if the submesh intersects with a ray
          * @param ray defines the ray to test
@@ -22704,7 +22743,7 @@ declare module BABYLON {
         setVerticesBuffer(buffer: VertexBuffer, totalVertices?: Nullable<number>): void;
         /**
          * Update a specific vertex buffer
-         * This function will directly update the underlying WebGLBuffer according to the passed numeric array or Float32Array
+         * This function will directly update the underlying DataBuffer according to the passed numeric array or Float32Array
          * It will do nothing if the buffer is not updatable
          * @param kind defines the data kind (Position, normal, etc...)
          * @param data defines the data to use
@@ -22722,7 +22761,7 @@ declare module BABYLON {
         updateVerticesData(kind: string, data: FloatArray, updateExtends?: boolean): void;
         private _updateBoundingInfo;
         /** @hidden */
-        _bind(effect: Nullable<Effect>, indexToBind?: Nullable<WebGLBuffer>): void;
+        _bind(effect: Nullable<Effect>, indexToBind?: Nullable<DataBuffer>): void;
         /**
          * Gets total number of vertices
          * @returns the total number of vertices
@@ -22796,7 +22835,7 @@ declare module BABYLON {
          * Gets the index buffer
          * @return the index buffer
          */
-        getIndexBuffer(): Nullable<WebGLBuffer>;
+        getIndexBuffer(): Nullable<DataBuffer>;
         /** @hidden */
         _releaseVertexArrayObject(effect?: Nullable<Effect>): void;
         /**
@@ -24218,6 +24257,8 @@ declare module BABYLON {
         /** @hidden */
         _isActive: boolean;
         /** @hidden */
+        _onlyForInstances: boolean;
+        /** @hidden */
         _renderingGroup: Nullable<RenderingGroup>;
         /**
          * Gets or sets mesh visibility between 0 and 1 (default is 1)
@@ -26254,7 +26295,7 @@ declare module BABYLON {
          * The underlying WebGL Uniform buffer.
          * @returns the webgl buffer
          */
-        getBuffer(): Nullable<WebGLBuffer>;
+        getBuffer(): Nullable<DataBuffer>;
         /**
          * std140 layout specifies how to align data within an UBO structure.
          * See https://khronos.org/registry/OpenGL/specs/gl/glspec45.core.pdf#page=159
@@ -26704,6 +26745,29 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
+    /** @hidden */
+    export class WebGLPipelineContext implements IPipelineContext {
+        engine: Engine;
+        program: Nullable<WebGLProgram>;
+        context?: WebGLRenderingContext;
+        vertexShader?: WebGLShader;
+        fragmentShader?: WebGLShader;
+        isParallelCompiled: boolean;
+        onCompiled?: () => void;
+        transformFeedback?: WebGLTransformFeedback | null;
+        readonly isAsync: boolean;
+        readonly isReady: boolean;
+    }
+}
+declare module BABYLON {
+    /** @hidden */
+    export class WebGLDataBuffer extends DataBuffer {
+        private _buffer;
+        constructor(resource: WebGLBuffer);
+        readonly underlyingResource: any;
+    }
+}
+declare module BABYLON {
     /**
      * Settings for finer control over video usage
      */
@@ -27507,7 +27571,7 @@ declare module BABYLON {
         /** @hidden */
         protected _cachedVertexBuffers: any;
         /** @hidden */
-        protected _cachedIndexBuffer: Nullable<WebGLBuffer>;
+        protected _cachedIndexBuffer: Nullable<DataBuffer>;
         /** @hidden */
         protected _cachedEffectForVertexBuffers: Nullable<Effect>;
         /** @hidden */
@@ -27978,14 +28042,14 @@ declare module BABYLON {
          * @param elements defines the content of the uniform buffer
          * @returns the webGL uniform buffer
          */
-        createUniformBuffer(elements: FloatArray): WebGLBuffer;
+        createUniformBuffer(elements: FloatArray): DataBuffer;
         /**
          * Create a dynamic uniform buffer
          * @see http://doc.babylonjs.com/features/webgl2#uniform-buffer-objets
          * @param elements defines the content of the uniform buffer
          * @returns the webGL uniform buffer
          */
-        createDynamicUniformBuffer(elements: FloatArray): WebGLBuffer;
+        createDynamicUniformBuffer(elements: FloatArray): DataBuffer;
         /**
          * Update an existing uniform buffer
          * @see http://doc.babylonjs.com/features/webgl2#uniform-buffer-objets
@@ -27994,27 +28058,27 @@ declare module BABYLON {
          * @param offset defines the offset in the uniform buffer where update should start
          * @param count defines the size of the data to update
          */
-        updateUniformBuffer(uniformBuffer: WebGLBuffer, elements: FloatArray, offset?: number, count?: number): void;
+        updateUniformBuffer(uniformBuffer: DataBuffer, elements: FloatArray, offset?: number, count?: number): void;
         private _resetVertexBufferBinding;
         /**
          * Creates a vertex buffer
          * @param data the data for the vertex buffer
          * @returns the new WebGL static buffer
          */
-        createVertexBuffer(data: DataArray): WebGLBuffer;
+        createVertexBuffer(data: DataArray): DataBuffer;
         /**
          * Creates a dynamic vertex buffer
          * @param data the data for the dynamic vertex buffer
          * @returns the new WebGL dynamic buffer
          */
-        createDynamicVertexBuffer(data: DataArray): WebGLBuffer;
+        createDynamicVertexBuffer(data: DataArray): DataBuffer;
         /**
          * Update a dynamic index buffer
          * @param indexBuffer defines the target index buffer
          * @param indices defines the data to update
          * @param offset defines the offset in the target index buffer where update should start
          */
-        updateDynamicIndexBuffer(indexBuffer: WebGLBuffer, indices: IndicesArray, offset?: number): void;
+        updateDynamicIndexBuffer(indexBuffer: DataBuffer, indices: IndicesArray, offset?: number): void;
         /**
          * Updates a dynamic vertex buffer.
          * @param vertexBuffer the vertex buffer to update
@@ -28022,7 +28086,7 @@ declare module BABYLON {
          * @param byteOffset the byte offset of the data
          * @param byteLength the byte length of the data
          */
-        updateDynamicVertexBuffer(vertexBuffer: WebGLBuffer, data: DataArray, byteOffset?: number, byteLength?: number): void;
+        updateDynamicVertexBuffer(vertexBuffer: DataBuffer, data: DataArray, byteOffset?: number, byteLength?: number): void;
         private _resetIndexBufferBinding;
         /**
          * Creates a new index buffer
@@ -28030,30 +28094,30 @@ declare module BABYLON {
          * @param updatable defines if the index buffer must be updatable
          * @returns a new webGL buffer
          */
-        createIndexBuffer(indices: IndicesArray, updatable?: boolean): WebGLBuffer;
+        createIndexBuffer(indices: IndicesArray, updatable?: boolean): DataBuffer;
         /**
          * Bind a webGL buffer to the webGL context
          * @param buffer defines the buffer to bind
          */
-        bindArrayBuffer(buffer: Nullable<WebGLBuffer>): void;
+        bindArrayBuffer(buffer: Nullable<DataBuffer>): void;
         /**
          * Bind an uniform buffer to the current webGL context
          * @param buffer defines the buffer to bind
          */
-        bindUniformBuffer(buffer: Nullable<WebGLBuffer>): void;
+        bindUniformBuffer(buffer: Nullable<DataBuffer>): void;
         /**
          * Bind a buffer to the current webGL context at a given location
          * @param buffer defines the buffer to bind
          * @param location defines the index where to bind the buffer
          */
-        bindUniformBufferBase(buffer: WebGLBuffer, location: number): void;
+        bindUniformBufferBase(buffer: DataBuffer, location: number): void;
         /**
          * Bind a specific block at a given index in a specific shader program
-         * @param shaderProgram defines the shader program
+         * @param pipelineContext defines the pipeline context to use
          * @param blockName defines the block name
          * @param index defines the index where to bind the block
          */
-        bindUniformBlock(shaderProgram: WebGLProgram, blockName: string, index: number): void;
+        bindUniformBlock(pipelineContext: IPipelineContext, blockName: string, index: number): void;
         private bindIndexBuffer;
         private bindBuffer;
         /**
@@ -28074,14 +28138,14 @@ declare module BABYLON {
          */
         recordVertexArrayObject(vertexBuffers: {
             [key: string]: VertexBuffer;
-        }, indexBuffer: Nullable<WebGLBuffer>, effect: Effect): WebGLVertexArrayObject;
+        }, indexBuffer: Nullable<DataBuffer>, effect: Effect): WebGLVertexArrayObject;
         /**
          * Bind a specific vertex array object
          * @see http://doc.babylonjs.com/features/webgl2#vertex-array-objects
          * @param vertexArrayObject defines the vertex array object to bind
          * @param indexBuffer defines the index buffer to bind
          */
-        bindVertexArrayObject(vertexArrayObject: WebGLVertexArrayObject, indexBuffer: Nullable<WebGLBuffer>): void;
+        bindVertexArrayObject(vertexArrayObject: WebGLVertexArrayObject, indexBuffer: Nullable<DataBuffer>): void;
         /**
          * Bind webGl buffers directly to the webGL context
          * @param vertexBuffer defines the vertex buffer to bind
@@ -28090,7 +28154,7 @@ declare module BABYLON {
          * @param vertexStrideSize defines the vertex stride of the vertex buffer
          * @param effect defines the effect associated with the vertex buffer
          */
-        bindBuffersDirectly(vertexBuffer: WebGLBuffer, indexBuffer: WebGLBuffer, vertexDeclaration: number[], vertexStrideSize: number, effect: Effect): void;
+        bindBuffersDirectly(vertexBuffer: DataBuffer, indexBuffer: DataBuffer, vertexDeclaration: number[], vertexStrideSize: number, effect: Effect): void;
         private _unbindVertexArrayObject;
         /**
          * Bind a list of vertex buffers to the webGL context
@@ -28100,7 +28164,7 @@ declare module BABYLON {
          */
         bindBuffers(vertexBuffers: {
             [key: string]: Nullable<VertexBuffer>;
-        }, indexBuffer: Nullable<WebGLBuffer>, effect: Effect): void;
+        }, indexBuffer: Nullable<DataBuffer>, effect: Effect): void;
         /**
          * Unbind all instance attributes
          */
@@ -28111,13 +28175,13 @@ declare module BABYLON {
          */
         releaseVertexArrayObject(vao: WebGLVertexArrayObject): void;
         /** @hidden */
-        _releaseBuffer(buffer: WebGLBuffer): boolean;
+        _releaseBuffer(buffer: DataBuffer): boolean;
         /**
          * Creates a webGL buffer to use with instanciation
          * @param capacity defines the size of the buffer
          * @returns the webGL buffer
          */
-        createInstancesBuffer(capacity: number): WebGLBuffer;
+        createInstancesBuffer(capacity: number): DataBuffer;
         /**
          * Delete a webGL buffer used with instanciation
          * @param buffer defines the webGL buffer to delete
@@ -28129,7 +28193,7 @@ declare module BABYLON {
          * @param data defines the data to store in the buffer
          * @param offsetLocations defines the offsets or attributes information used to determine where data must be stored in the buffer
          */
-        updateAndBindInstancesBuffer(instancesBuffer: WebGLBuffer, data: Float32Array, offsetLocations: number[] | InstancingAttributeInfo[]): void;
+        updateAndBindInstancesBuffer(instancesBuffer: DataBuffer, data: Float32Array, offsetLocations: number[] | InstancingAttributeInfo[]): void;
         /**
          * Apply all cached states (depth, culling, stencil and alpha)
          */
@@ -28177,7 +28241,7 @@ declare module BABYLON {
         /** @hidden */
         _releaseEffect(effect: Effect): void;
         /** @hidden */
-        _deleteProgram(program: WebGLProgram): void;
+        _deletePipelineContext(pipelineContext: IPipelineContext): void;
         /**
          * Create a new effect (used to store vertex/fragment shaders)
          * @param baseName defines the base name of the effect (The name of file without .fragment.fx or .vertex.fx)
@@ -28196,15 +28260,17 @@ declare module BABYLON {
         private _compileRawShader;
         /**
          * Directly creates a webGL program
+         * @param pipelineContext  defines the pipeline context to attach to
          * @param vertexCode defines the vertex shader code to use
          * @param fragmentCode defines the fragment shader code to use
          * @param context defines the webGL context to use (if not set, the current one will be used)
          * @param transformFeedbackVaryings defines the list of transform feedback varyings to use
          * @returns the new webGL program
          */
-        createRawShaderProgram(vertexCode: string, fragmentCode: string, context?: WebGLRenderingContext, transformFeedbackVaryings?: Nullable<string[]>): WebGLProgram;
+        createRawShaderProgram(pipelineContext: IPipelineContext, vertexCode: string, fragmentCode: string, context?: WebGLRenderingContext, transformFeedbackVaryings?: Nullable<string[]>): WebGLProgram;
         /**
          * Creates a webGL program
+         * @param pipelineContext  defines the pipeline context to attach to
          * @param vertexCode  defines the vertex shader code to use
          * @param fragmentCode defines the fragment shader code to use
          * @param defines defines the string containing the defines to use to compile the shaders
@@ -28212,27 +28278,34 @@ declare module BABYLON {
          * @param transformFeedbackVaryings defines the list of transform feedback varyings to use
          * @returns the new webGL program
          */
-        createShaderProgram(vertexCode: string, fragmentCode: string, defines: Nullable<string>, context?: WebGLRenderingContext, transformFeedbackVaryings?: Nullable<string[]>): WebGLProgram;
+        createShaderProgram(pipelineContext: IPipelineContext, vertexCode: string, fragmentCode: string, defines: Nullable<string>, context?: WebGLRenderingContext, transformFeedbackVaryings?: Nullable<string[]>): WebGLProgram;
+        /**
+         * Creates a new pipeline context
+         * @returns the new pipeline
+         */
+        createPipelineContext(): WebGLPipelineContext;
         private _createShaderProgram;
-        private _finalizeProgram;
+        private _finalizePipelineContext;
+        /** @hidden */
+        _preparePipelineContext(pipelineContext: IPipelineContext, vertexSourceCode: string, fragmentSourceCode: string, createAsRaw: boolean, rebuildRebind: any, defines: Nullable<string>, transformFeedbackVaryings: Nullable<string[]>): void;
         /** @hidden */
-        _isProgramCompiled(shaderProgram: WebGLProgram): boolean;
+        _isRenderingStateCompiled(pipelineContext: IPipelineContext): boolean;
         /** @hidden */
-        _executeWhenProgramIsCompiled(shaderProgram: WebGLProgram, action: () => void): void;
+        _executeWhenRenderingStateIsCompiled(pipelineContext: IPipelineContext, action: () => void): void;
         /**
          * Gets the list of webGL uniform locations associated with a specific program based on a list of uniform names
-         * @param shaderProgram defines the webGL program to use
+         * @param pipelineContext defines the pipeline context to use
          * @param uniformsNames defines the list of uniform names
          * @returns an array of webGL uniform locations
          */
-        getUniforms(shaderProgram: WebGLProgram, uniformsNames: string[]): Nullable<WebGLUniformLocation>[];
+        getUniforms(pipelineContext: IPipelineContext, uniformsNames: string[]): Nullable<WebGLUniformLocation>[];
         /**
          * Gets the lsit of active attributes for a given webGL program
-         * @param shaderProgram defines the webGL program to use
+         * @param pipelineContext defines the pipeline context to use
          * @param attributesNames defines the list of attribute names to get
          * @returns an array of indices indicating the offset of each attribute
          */
-        getAttributes(shaderProgram: WebGLProgram, attributesNames: string[]): number[];
+        getAttributes(pipelineContext: IPipelineContext, attributesNames: string[]): number[];
         /**
          * Activates an effect, mkaing it the current one (ie. the one used for rendering)
          * @param effect defines the effect to activate
@@ -29001,7 +29074,7 @@ declare module BABYLON {
          * Compiled shader to webGL program.
          * @hidden
          */
-        _program: WebGLProgram;
+        _pipelineContext: IPipelineContext;
         private _valueCache;
         private static _baseCache;
         /**
@@ -29034,10 +29107,10 @@ declare module BABYLON {
          */
         getEngine(): Engine;
         /**
-         * The compiled webGL program for the effect
-         * @returns the webGL program.
+         * The pipeline context for this effect
+         * @returns the associated pipeline context
          */
-        getProgram(): WebGLProgram;
+        getPipelineContext(): IPipelineContext;
         /**
          * The set of names of attribute variables for the shader.
          * @returns An array of attribute names.
@@ -29105,13 +29178,7 @@ declare module BABYLON {
          * @param onError Callback called on error.
          * @hidden
          */
-        _rebuildProgram(vertexSourceCode: string, fragmentSourceCode: string, onCompiled: (program: WebGLProgram) => void, onError: (message: string) => void): void;
-        /**
-         * Gets the uniform locations of the the specified variable names
-         * @param names THe names of the variables to lookup.
-         * @returns Array of locations in the same order as variable names.
-         */
-        getSpecificUniformLocations(names: string[]): Nullable<WebGLUniformLocation>[];
+        _rebuildProgram(vertexSourceCode: string, fragmentSourceCode: string, onCompiled: (pipelineContext: IPipelineContext) => void, onError: (message: string) => void): void;
         /**
          * Prepares the effect
          * @hidden
@@ -29172,7 +29239,7 @@ declare module BABYLON {
          * @param buffer Buffer to bind.
          * @param name Name of the uniform variable to bind to.
          */
-        bindUniformBuffer(buffer: WebGLBuffer, name: string): void;
+        bindUniformBuffer(buffer: DataBuffer, name: string): void;
         /**
          * Binds block to a uniform.
          * @param blockName Name of the block to bind.
@@ -41137,15 +41204,15 @@ declare module BABYLON {
          */
         getHardwareScalingLevel(): number;
         constructor(options?: NullEngineOptions);
-        createVertexBuffer(vertices: FloatArray): WebGLBuffer;
-        createIndexBuffer(indices: IndicesArray): WebGLBuffer;
+        createVertexBuffer(vertices: FloatArray): DataBuffer;
+        createIndexBuffer(indices: IndicesArray): DataBuffer;
         clear(color: Color4, backBuffer: boolean, depth: boolean, stencil?: boolean): void;
         getRenderWidth(useScreen?: boolean): number;
         getRenderHeight(useScreen?: boolean): number;
         setViewport(viewport: Viewport, requiredWidth?: number, requiredHeight?: number): void;
-        createShaderProgram(vertexCode: string, fragmentCode: string, defines: string, context?: WebGLRenderingContext): WebGLProgram;
-        getUniforms(shaderProgram: WebGLProgram, uniformsNames: string[]): WebGLUniformLocation[];
-        getAttributes(shaderProgram: WebGLProgram, attributesNames: string[]): number[];
+        createShaderProgram(pipelineContext: IPipelineContext, vertexCode: string, fragmentCode: string, defines: string, context?: WebGLRenderingContext): WebGLProgram;
+        getUniforms(pipelineContext: IPipelineContext, uniformsNames: string[]): Nullable<WebGLUniformLocation>[];
+        getAttributes(pipelineContext: IPipelineContext, attributesNames: string[]): number[];
         bindSamplers(effect: Effect): void;
         enableEffect(effect: Effect): void;
         setState(culling: boolean, zOffset?: number, force?: boolean, reverseSide?: boolean): void;
@@ -41175,7 +41242,7 @@ declare module BABYLON {
         setAlphaMode(mode: number, noDepthWriteChange?: boolean): void;
         bindBuffers(vertexBuffers: {
             [key: string]: VertexBuffer;
-        }, indexBuffer: WebGLBuffer, effect: Effect): void;
+        }, indexBuffer: DataBuffer, effect: Effect): void;
         wipeCaches(bruteForce?: boolean): void;
         draw(useTriangles: boolean, indexStart: number, indexCount: number, instancesCount?: number): void;
         drawElementsType(fillMode: number, indexStart: number, indexCount: number, instancesCount?: number): void;
@@ -41189,7 +41256,7 @@ declare module BABYLON {
         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(vertices: FloatArray): WebGLBuffer;
+        createDynamicVertexBuffer(vertices: FloatArray): DataBuffer;
         updateDynamicTexture(texture: Nullable<InternalTexture>, canvas: HTMLCanvasElement, invertY: boolean, premulAlpha?: boolean, format?: number): void;
         areAllEffectsReady(): boolean;
         /**
@@ -41216,7 +41283,7 @@ declare module BABYLON {
         /** @hidden */
         _bindTexture(channel: number, texture: InternalTexture): void;
         /** @hidden */
-        _releaseBuffer(buffer: WebGLBuffer): boolean;
+        _releaseBuffer(buffer: DataBuffer): boolean;
         releaseEffects(): void;
         displayLoadingUI(): void;
         hideLoadingUI(): void;
@@ -52088,7 +52155,7 @@ declare module BABYLON {
          */
         _attachCameras(cameras: Camera[]): void;
         /**
-         * Detatches the effect on cameras
+         * Detaches the effect on cameras
          * @param cameras The camera to detatch from.
          * @hidden
          */
@@ -52571,6 +52638,11 @@ declare module BABYLON {
          */
         constructor(scene: Scene, depthTexture: Nullable<RenderTargetTexture>, blurLevel?: DepthOfFieldEffectBlurLevel, pipelineTextureType?: number, blockCompilation?: boolean);
         /**
+        * Get the current class name of the current effet
+        * @returns "DepthOfFieldEffect"
+        */
+        getClassName(): string;
+        /**
          * Depth texture to be used to compute the circle of confusion. This must be set here or in the constructor in order for the post process to function.
          */
         depthTexture: RenderTargetTexture;
@@ -56410,13 +56482,6 @@ interface Math {
     fround(x: number): number;
     imul(a: number, b: number): number;
 }
-interface WebGLProgram {
-    context?: WebGLRenderingContext;
-    vertexShader?: WebGLShader;
-    fragmentShader?: WebGLShader;
-    isParallelCompiled: boolean;
-    onCompiled?: () => void;
-}
 interface WebGLRenderingContext {
     drawArraysInstanced(mode: number, first: number, count: number, primcount: number): void;
     drawElementsInstanced(mode: number, count: number, type: number, offset: number, primcount: number): void;
@@ -56469,13 +56534,7 @@ interface WebGLRenderingContext {
     QUERY_RESULT_AVAILABLE: number;
     QUERY_RESULT: number;
 }
-interface WebGLBuffer {
-    references: number;
-    capacity: number;
-    is32Bits: boolean;
-}
 interface WebGLProgram {
-    transformFeedback?: WebGLTransformFeedback | null;
     __SPECTOR_rebuildProgram?: ((vertexSourceCode: string, fragmentSourceCode: string, onCompiled: (program: WebGLProgram) => void, onError: (message: string) => void) => void) | null;
 }
 interface EXT_disjoint_timer_query {

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 2 - 2
dist/preview release/babylon.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 444 - 230
dist/preview release/babylon.max.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
dist/preview release/babylon.max.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 329 - 190
dist/preview release/babylon.module.d.ts


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

@@ -1 +1 @@
-{"engineOnly":291196,"sceneOnly":495442,"minGridMaterial":620437,"minStandardMaterial":743533}
+{"engineOnly":292624,"sceneOnly":496901,"minGridMaterial":621922,"minStandardMaterial":745018}

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 329 - 190
dist/preview release/viewer/babylon.module.d.ts


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 50 - 34
dist/preview release/viewer/babylon.viewer.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


+ 14 - 0
src/Engines/IPipelineContext.ts

@@ -0,0 +1,14 @@
+
+/**
+ * Class used to store and describe the pipeline context associated with an effect
+ */
+export interface IPipelineContext {
+    /**
+     * Gets a boolean indicating that this pipeline context is supporting asynchronous creating
+     */
+    isAsync: boolean;
+    /**
+     * Gets a boolean indicating that the context is ready to be used (like shaders / pipelines are compiled and ready for instance)
+     */
+    isReady: boolean;
+}

+ 27 - 0
src/Engines/WebGL/webGLPipelineContext.ts

@@ -0,0 +1,27 @@
+import { IPipelineContext } from '../IPipelineContext';
+import { Engine } from '../engine';
+import { Nullable } from '../../types';
+
+/** @hidden */
+export class WebGLPipelineContext implements IPipelineContext {
+    public engine: Engine;
+    public program: Nullable<WebGLProgram>;
+    public context?: WebGLRenderingContext;
+    public vertexShader?: WebGLShader;
+    public fragmentShader?: WebGLShader;
+    public isParallelCompiled: boolean;
+    public onCompiled?: () => void;
+    public transformFeedback?: WebGLTransformFeedback | null;
+
+    public get isAsync() {
+        return this.isParallelCompiled;
+    }
+
+    public get isReady(): boolean {
+        if (this.program && this.isParallelCompiled) {
+            return this.engine._isRenderingStateCompiled(this);
+        }
+
+        return true;
+    }
+}

+ 155 - 107
src/Engines/engine.ts

@@ -28,6 +28,10 @@ import { EngineStore } from "./engineStore";
 import { RenderTargetCreationOptions } from "../Materials/Textures/renderTargetCreationOptions";
 import { _DevTools } from '../Misc/devTools';
 import { WebRequest } from '../Misc/webRequest';
+import { WebGLPipelineContext } from './WebGL/webGLPipelineContext';
+import { IPipelineContext } from './IPipelineContext';
+import { DataBuffer } from '../Meshes/dataBuffer';
+import { WebGLDataBuffer } from '../Meshes/WebGL/webGLDataBuffer';
 
 declare type PostProcess = import("../PostProcesses/postProcess").PostProcess;
 declare type Texture = import("../Materials/Textures/texture").Texture;
@@ -884,7 +888,7 @@ export class Engine {
     /** @hidden */
     protected _cachedVertexBuffers: any;
     /** @hidden */
-    protected _cachedIndexBuffer: Nullable<WebGLBuffer>;
+    protected _cachedIndexBuffer: Nullable<DataBuffer>;
     /** @hidden */
     protected _cachedEffectForVertexBuffers: Nullable<Effect>;
     /** @hidden */
@@ -895,7 +899,7 @@ export class Engine {
     protected _currentFramebuffer: Nullable<WebGLFramebuffer> = null;
     private _currentBufferPointers = new Array<BufferPointer>();
     private _currentInstanceLocations = new Array<number>();
-    private _currentInstanceBuffers = new Array<WebGLBuffer>();
+    private _currentInstanceBuffers = new Array<DataBuffer>();
     private _textureUnits: Int32Array;
 
     /** @hidden */
@@ -2536,14 +2540,15 @@ export class Engine {
      * @param elements defines the content of the uniform buffer
      * @returns the webGL uniform buffer
      */
-    public createUniformBuffer(elements: FloatArray): WebGLBuffer {
+    public createUniformBuffer(elements: FloatArray): DataBuffer {
         var ubo = this._gl.createBuffer();
 
         if (!ubo) {
             throw new Error("Unable to create uniform buffer");
         }
+        let result = new WebGLDataBuffer(ubo);
 
-        this.bindUniformBuffer(ubo);
+        this.bindUniformBuffer(result);
 
         if (elements instanceof Float32Array) {
             this._gl.bufferData(this._gl.UNIFORM_BUFFER, <Float32Array>elements, this._gl.STATIC_DRAW);
@@ -2553,8 +2558,8 @@ export class Engine {
 
         this.bindUniformBuffer(null);
 
-        ubo.references = 1;
-        return ubo;
+        result.references = 1;
+        return result;
     }
 
     /**
@@ -2563,14 +2568,15 @@ export class Engine {
      * @param elements defines the content of the uniform buffer
      * @returns the webGL uniform buffer
      */
-    public createDynamicUniformBuffer(elements: FloatArray): WebGLBuffer {
+    public createDynamicUniformBuffer(elements: FloatArray): DataBuffer {
         var ubo = this._gl.createBuffer();
 
         if (!ubo) {
             throw new Error("Unable to create dynamic uniform buffer");
         }
 
-        this.bindUniformBuffer(ubo);
+        let result = new WebGLDataBuffer(ubo);
+        this.bindUniformBuffer(result);
 
         if (elements instanceof Float32Array) {
             this._gl.bufferData(this._gl.UNIFORM_BUFFER, <Float32Array>elements, this._gl.DYNAMIC_DRAW);
@@ -2580,8 +2586,8 @@ export class Engine {
 
         this.bindUniformBuffer(null);
 
-        ubo.references = 1;
-        return ubo;
+        result.references = 1;
+        return result;
     }
 
     /**
@@ -2592,7 +2598,7 @@ export class Engine {
      * @param offset defines the offset in the uniform buffer where update should start
      * @param count defines the size of the data to update
      */
-    public updateUniformBuffer(uniformBuffer: WebGLBuffer, elements: FloatArray, offset?: number, count?: number): void {
+    public updateUniformBuffer(uniformBuffer: DataBuffer, elements: FloatArray, offset?: number, count?: number): void {
         this.bindUniformBuffer(uniformBuffer);
 
         if (offset === undefined) {
@@ -2627,14 +2633,15 @@ export class Engine {
      * @param data the data for the vertex buffer
      * @returns the new WebGL static buffer
      */
-    public createVertexBuffer(data: DataArray): WebGLBuffer {
+    public createVertexBuffer(data: DataArray): DataBuffer {
         var vbo = this._gl.createBuffer();
 
         if (!vbo) {
             throw new Error("Unable to create vertex buffer");
         }
 
-        this.bindArrayBuffer(vbo);
+        let dataBuffer = new WebGLDataBuffer(vbo);
+        this.bindArrayBuffer(dataBuffer);
 
         if (data instanceof Array) {
             this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(data), this._gl.STATIC_DRAW);
@@ -2643,8 +2650,9 @@ export class Engine {
         }
 
         this._resetVertexBufferBinding();
-        vbo.references = 1;
-        return vbo;
+
+        dataBuffer.references = 1;
+        return dataBuffer;
     }
 
     /**
@@ -2652,14 +2660,15 @@ export class Engine {
      * @param data the data for the dynamic vertex buffer
      * @returns the new WebGL dynamic buffer
      */
-    public createDynamicVertexBuffer(data: DataArray): WebGLBuffer {
+    public createDynamicVertexBuffer(data: DataArray): DataBuffer {
         var vbo = this._gl.createBuffer();
 
         if (!vbo) {
             throw new Error("Unable to create dynamic vertex buffer");
         }
 
-        this.bindArrayBuffer(vbo);
+        let result = new WebGLDataBuffer(vbo);
+        this.bindArrayBuffer(result);
 
         if (data instanceof Array) {
             this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(data), this._gl.DYNAMIC_DRAW);
@@ -2668,8 +2677,8 @@ export class Engine {
         }
 
         this._resetVertexBufferBinding();
-        vbo.references = 1;
-        return vbo;
+        result.references = 1;
+        return result;
     }
 
     /**
@@ -2678,7 +2687,7 @@ export class Engine {
      * @param indices defines the data to update
      * @param offset defines the offset in the target index buffer where update should start
      */
-    public updateDynamicIndexBuffer(indexBuffer: WebGLBuffer, indices: IndicesArray, offset: number = 0): void {
+    public updateDynamicIndexBuffer(indexBuffer: DataBuffer, indices: IndicesArray, offset: number = 0): void {
         // Force cache update
         this._currentBoundBuffer[this._gl.ELEMENT_ARRAY_BUFFER] = null;
         this.bindIndexBuffer(indexBuffer);
@@ -2702,7 +2711,7 @@ export class Engine {
      * @param byteOffset the byte offset of the data
      * @param byteLength the byte length of the data
      */
-    public updateDynamicVertexBuffer(vertexBuffer: WebGLBuffer, data: DataArray, byteOffset?: number, byteLength?: number): void {
+    public updateDynamicVertexBuffer(vertexBuffer: DataBuffer, data: DataArray, byteOffset?: number, byteLength?: number): void {
         this.bindArrayBuffer(vertexBuffer);
 
         if (byteOffset === undefined) {
@@ -2747,14 +2756,15 @@ export class Engine {
      * @param updatable defines if the index buffer must be updatable
      * @returns a new webGL buffer
      */
-    public createIndexBuffer(indices: IndicesArray, updatable?: boolean): WebGLBuffer {
+    public createIndexBuffer(indices: IndicesArray, updatable?: boolean): DataBuffer {
         var vbo = this._gl.createBuffer();
+        let dataBuffer = new WebGLDataBuffer(vbo!);
 
         if (!vbo) {
             throw new Error("Unable to create index buffer");
         }
 
-        this.bindIndexBuffer(vbo);
+        this.bindIndexBuffer(dataBuffer);
 
         // Check for 32 bits indices
         var arrayBuffer;
@@ -2787,16 +2797,16 @@ export class Engine {
 
         this._gl.bufferData(this._gl.ELEMENT_ARRAY_BUFFER, arrayBuffer, updatable ? this._gl.DYNAMIC_DRAW : this._gl.STATIC_DRAW);
         this._resetIndexBufferBinding();
-        vbo.references = 1;
-        vbo.is32Bits = need32Bits;
-        return vbo;
+        dataBuffer.references = 1;
+        dataBuffer.is32Bits = need32Bits;
+        return dataBuffer;
     }
 
     /**
      * Bind a webGL buffer to the webGL context
      * @param buffer defines the buffer to bind
      */
-    public bindArrayBuffer(buffer: Nullable<WebGLBuffer>): void {
+    public bindArrayBuffer(buffer: Nullable<DataBuffer>): void {
         if (!this._vaoRecordInProgress) {
             this._unbindVertexArrayObject();
         }
@@ -2807,8 +2817,8 @@ export class Engine {
      * Bind an uniform buffer to the current webGL context
      * @param buffer defines the buffer to bind
      */
-    public bindUniformBuffer(buffer: Nullable<WebGLBuffer>): void {
-        this._gl.bindBuffer(this._gl.UNIFORM_BUFFER, buffer);
+    public bindUniformBuffer(buffer: Nullable<DataBuffer>): void {
+        this._gl.bindBuffer(this._gl.UNIFORM_BUFFER, buffer ? buffer.underlyingResource : null);
     }
 
     /**
@@ -2816,32 +2826,34 @@ export class Engine {
      * @param buffer defines the buffer to bind
      * @param location defines the index where to bind the buffer
      */
-    public bindUniformBufferBase(buffer: WebGLBuffer, location: number): void {
-        this._gl.bindBufferBase(this._gl.UNIFORM_BUFFER, location, buffer);
+    public bindUniformBufferBase(buffer: DataBuffer, location: number): void {
+        this._gl.bindBufferBase(this._gl.UNIFORM_BUFFER, location, buffer ? buffer.underlyingResource : null);
     }
 
     /**
      * Bind a specific block at a given index in a specific shader program
-     * @param shaderProgram defines the shader program
+     * @param pipelineContext defines the pipeline context to use
      * @param blockName defines the block name
      * @param index defines the index where to bind the block
      */
-    public bindUniformBlock(shaderProgram: WebGLProgram, blockName: string, index: number): void {
-        var uniformLocation = this._gl.getUniformBlockIndex(shaderProgram, blockName);
+    public bindUniformBlock(pipelineContext: IPipelineContext, blockName: string, index: number): void {
+        let program = (pipelineContext as WebGLPipelineContext).program!;
+
+        var uniformLocation = this._gl.getUniformBlockIndex(program, blockName);
 
-        this._gl.uniformBlockBinding(shaderProgram, uniformLocation, index);
+        this._gl.uniformBlockBinding(program, uniformLocation, index);
     }
 
-    private bindIndexBuffer(buffer: Nullable<WebGLBuffer>): void {
+    private bindIndexBuffer(buffer: Nullable<DataBuffer>): void {
         if (!this._vaoRecordInProgress) {
             this._unbindVertexArrayObject();
         }
         this.bindBuffer(buffer, this._gl.ELEMENT_ARRAY_BUFFER);
     }
 
-    private bindBuffer(buffer: Nullable<WebGLBuffer>, target: number): void {
+    private bindBuffer(buffer: Nullable<DataBuffer>, target: number): void {
         if (this._vaoRecordInProgress || this._currentBoundBuffer[target] !== buffer) {
-            this._gl.bindBuffer(target, buffer);
+            this._gl.bindBuffer(target, buffer ? buffer.underlyingResource : null);
             this._currentBoundBuffer[target] = buffer;
         }
     }
@@ -2854,7 +2866,7 @@ export class Engine {
         this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, data);
     }
 
-    private _vertexAttribPointer(buffer: WebGLBuffer, indx: number, size: number, type: number, normalized: boolean, stride: number, offset: number): void {
+    private _vertexAttribPointer(buffer: DataBuffer, indx: number, size: number, type: number, normalized: boolean, stride: number, offset: number): void {
         var pointer = this._currentBufferPointers[indx];
 
         var changed = false;
@@ -2883,7 +2895,7 @@ export class Engine {
         }
     }
 
-    private _bindIndexBufferWithCache(indexBuffer: Nullable<WebGLBuffer>): void {
+    private _bindIndexBufferWithCache(indexBuffer: Nullable<DataBuffer>): void {
         if (indexBuffer == null) {
             return;
         }
@@ -2942,7 +2954,7 @@ export class Engine {
      * @param effect defines the effect to store
      * @returns the new vertex array object
      */
-    public recordVertexArrayObject(vertexBuffers: { [key: string]: VertexBuffer; }, indexBuffer: Nullable<WebGLBuffer>, effect: Effect): WebGLVertexArrayObject {
+    public recordVertexArrayObject(vertexBuffers: { [key: string]: VertexBuffer; }, indexBuffer: Nullable<DataBuffer>, effect: Effect): WebGLVertexArrayObject {
         var vao = this._gl.createVertexArray();
 
         this._vaoRecordInProgress = true;
@@ -2966,7 +2978,7 @@ export class Engine {
      * @param vertexArrayObject defines the vertex array object to bind
      * @param indexBuffer defines the index buffer to bind
      */
-    public bindVertexArrayObject(vertexArrayObject: WebGLVertexArrayObject, indexBuffer: Nullable<WebGLBuffer>): void {
+    public bindVertexArrayObject(vertexArrayObject: WebGLVertexArrayObject, indexBuffer: Nullable<DataBuffer>): void {
         if (this._cachedVertexArrayObject !== vertexArrayObject) {
             this._cachedVertexArrayObject = vertexArrayObject;
 
@@ -2987,7 +2999,7 @@ export class Engine {
      * @param vertexStrideSize defines the vertex stride of the vertex buffer
      * @param effect defines the effect associated with the vertex buffer
      */
-    public bindBuffersDirectly(vertexBuffer: WebGLBuffer, indexBuffer: WebGLBuffer, vertexDeclaration: number[], vertexStrideSize: number, effect: Effect): void {
+    public bindBuffersDirectly(vertexBuffer: DataBuffer, indexBuffer: DataBuffer, vertexDeclaration: number[], vertexStrideSize: number, effect: Effect): void {
         if (this._cachedVertexBuffers !== vertexBuffer || this._cachedEffectForVertexBuffers !== effect) {
             this._cachedVertexBuffers = vertexBuffer;
             this._cachedEffectForVertexBuffers = effect;
@@ -3033,7 +3045,7 @@ export class Engine {
      * @param indexBuffer defines the index buffer to bind
      * @param effect defines the effect associated with the vertex buffers
      */
-    public bindBuffers(vertexBuffers: { [key: string]: Nullable<VertexBuffer> }, indexBuffer: Nullable<WebGLBuffer>, effect: Effect): void {
+    public bindBuffers(vertexBuffers: { [key: string]: Nullable<VertexBuffer> }, indexBuffer: Nullable<DataBuffer>, effect: Effect): void {
         if (this._cachedVertexBuffers !== vertexBuffers || this._cachedEffectForVertexBuffers !== effect) {
             this._cachedVertexBuffers = vertexBuffers;
             this._cachedEffectForVertexBuffers = effect;
@@ -3071,11 +3083,11 @@ export class Engine {
     }
 
     /** @hidden */
-    public _releaseBuffer(buffer: WebGLBuffer): boolean {
+    public _releaseBuffer(buffer: DataBuffer): boolean {
         buffer.references--;
 
         if (buffer.references === 0) {
-            this._gl.deleteBuffer(buffer);
+            this._gl.deleteBuffer(buffer.underlyingResource);
             return true;
         }
 
@@ -3087,18 +3099,19 @@ export class Engine {
      * @param capacity defines the size of the buffer
      * @returns the webGL buffer
      */
-    public createInstancesBuffer(capacity: number): WebGLBuffer {
+    public createInstancesBuffer(capacity: number): DataBuffer {
         var buffer = this._gl.createBuffer();
 
         if (!buffer) {
             throw new Error("Unable to create instance buffer");
         }
 
-        buffer.capacity = capacity;
+        var result = new WebGLDataBuffer(buffer);
+        result.capacity = capacity;
 
-        this.bindArrayBuffer(buffer);
+        this.bindArrayBuffer(result);
         this._gl.bufferData(this._gl.ARRAY_BUFFER, capacity, this._gl.DYNAMIC_DRAW);
-        return buffer;
+        return result;
     }
 
     /**
@@ -3115,7 +3128,7 @@ export class Engine {
      * @param data defines the data to store in the buffer
      * @param offsetLocations defines the offsets or attributes information used to determine where data must be stored in the buffer
      */
-    public updateAndBindInstancesBuffer(instancesBuffer: WebGLBuffer, data: Float32Array, offsetLocations: number[] | InstancingAttributeInfo[]): void {
+    public updateAndBindInstancesBuffer(instancesBuffer: DataBuffer, data: Float32Array, offsetLocations: number[] | InstancingAttributeInfo[]): void {
         this.bindArrayBuffer(instancesBuffer);
         if (data) {
             this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, data);
@@ -3276,21 +3289,22 @@ export class Engine {
         if (this._compiledEffects[effect._key]) {
             delete this._compiledEffects[effect._key];
 
-            this._deleteProgram(effect.getProgram());
+            this._deletePipelineContext(effect.getPipelineContext() as WebGLPipelineContext);
         }
     }
 
     /** @hidden */
-    public _deleteProgram(program: WebGLProgram): void {
-        if (program) {
-            program.__SPECTOR_rebuildProgram = null;
-
-            if (program.transformFeedback) {
-                this.deleteTransformFeedback(program.transformFeedback);
-                program.transformFeedback = null;
+    public _deletePipelineContext(pipelineContext: IPipelineContext): void {
+        let webGLPipelineContext = pipelineContext as WebGLPipelineContext;
+        if (webGLPipelineContext && webGLPipelineContext.program) {
+            webGLPipelineContext.program.__SPECTOR_rebuildProgram = null;
+
+            if (webGLPipelineContext.transformFeedback) {
+                this.deleteTransformFeedback(webGLPipelineContext.transformFeedback);
+                webGLPipelineContext.transformFeedback = null;
             }
 
-            this._gl.deleteProgram(program);
+            this._gl.deleteProgram(webGLPipelineContext.program);
         }
     }
 
@@ -3348,23 +3362,25 @@ export class Engine {
 
     /**
      * Directly creates a webGL program
+     * @param pipelineContext  defines the pipeline context to attach to
      * @param vertexCode defines the vertex shader code to use
      * @param fragmentCode defines the fragment shader code to use
      * @param context defines the webGL context to use (if not set, the current one will be used)
      * @param transformFeedbackVaryings defines the list of transform feedback varyings to use
      * @returns the new webGL program
      */
-    public createRawShaderProgram(vertexCode: string, fragmentCode: string, context?: WebGLRenderingContext, transformFeedbackVaryings: Nullable<string[]> = null): WebGLProgram {
+    public createRawShaderProgram(pipelineContext: IPipelineContext, vertexCode: string, fragmentCode: string, context?: WebGLRenderingContext, transformFeedbackVaryings: Nullable<string[]> = null): WebGLProgram {
         context = context || this._gl;
 
         var vertexShader = this._compileRawShader(vertexCode, "vertex");
         var fragmentShader = this._compileRawShader(fragmentCode, "fragment");
 
-        return this._createShaderProgram(vertexShader, fragmentShader, context, transformFeedbackVaryings);
+        return this._createShaderProgram(pipelineContext as WebGLPipelineContext, vertexShader, fragmentShader, context, transformFeedbackVaryings);
     }
 
     /**
      * Creates a webGL program
+     * @param pipelineContext  defines the pipeline context to attach to
      * @param vertexCode  defines the vertex shader code to use
      * @param fragmentCode defines the fragment shader code to use
      * @param defines defines the string containing the defines to use to compile the shaders
@@ -3372,7 +3388,7 @@ export class Engine {
      * @param transformFeedbackVaryings defines the list of transform feedback varyings to use
      * @returns the new webGL program
      */
-    public createShaderProgram(vertexCode: string, fragmentCode: string, defines: Nullable<string>, context?: WebGLRenderingContext, transformFeedbackVaryings: Nullable<string[]> = null): WebGLProgram {
+    public createShaderProgram(pipelineContext: IPipelineContext, vertexCode: string, fragmentCode: string, defines: Nullable<string>, context?: WebGLRenderingContext, transformFeedbackVaryings: Nullable<string[]> = null): WebGLProgram {
         context = context || this._gl;
 
         this.onBeforeShaderCompilationObservable.notifyObservers(this);
@@ -3381,24 +3397,36 @@ export class Engine {
         var vertexShader = this._compileShader(vertexCode, "vertex", defines, shaderVersion);
         var fragmentShader = this._compileShader(fragmentCode, "fragment", defines, shaderVersion);
 
-        let program = this._createShaderProgram(vertexShader, fragmentShader, context, transformFeedbackVaryings);
+        let program = this._createShaderProgram(pipelineContext as WebGLPipelineContext, vertexShader, fragmentShader, context, transformFeedbackVaryings);
 
         this.onAfterShaderCompilationObservable.notifyObservers(this);
 
         return program;
     }
 
-    private _createShaderProgram(vertexShader: WebGLShader, fragmentShader: WebGLShader, context: WebGLRenderingContext, transformFeedbackVaryings: Nullable<string[]> = null): WebGLProgram {
+    /**
+     * Creates a new pipeline context
+     * @returns the new pipeline
+     */
+    public createPipelineContext() {
+        var pipelineContext = new WebGLPipelineContext();
+        pipelineContext.engine = this;
+
+        if (this._caps.parallelShaderCompile) {
+            pipelineContext.isParallelCompiled = true;
+        }
+
+        return pipelineContext;
+    }
+
+    private _createShaderProgram(pipelineContext: WebGLPipelineContext, vertexShader: WebGLShader, fragmentShader: WebGLShader, context: WebGLRenderingContext, transformFeedbackVaryings: Nullable<string[]> = null): WebGLProgram {
         var shaderProgram = context.createProgram();
+        pipelineContext.program = shaderProgram;
 
         if (!shaderProgram) {
             throw new Error("Unable to create program");
         }
 
-        if (this._caps.parallelShaderCompile) {
-            shaderProgram.isParallelCompiled = true;
-        }
-
         context.attachShader(shaderProgram, vertexShader);
         context.attachShader(shaderProgram, fragmentShader);
 
@@ -3407,7 +3435,7 @@ export class Engine {
 
             this.bindTransformFeedback(transformFeedback);
             this.setTranformFeedbackVaryings(shaderProgram, transformFeedbackVaryings);
-            shaderProgram.transformFeedback = transformFeedback;
+            pipelineContext.transformFeedback = transformFeedback;
         }
 
         context.linkProgram(shaderProgram);
@@ -3416,23 +3444,24 @@ export class Engine {
             this.bindTransformFeedback(null);
         }
 
-        shaderProgram.context = context;
-        shaderProgram.vertexShader = vertexShader;
-        shaderProgram.fragmentShader = fragmentShader;
+        pipelineContext.context = context;
+        pipelineContext.vertexShader = vertexShader;
+        pipelineContext.fragmentShader = fragmentShader;
 
-        if (!shaderProgram.isParallelCompiled) {
-            this._finalizeProgram(shaderProgram);
+        if (!pipelineContext.isParallelCompiled) {
+            this._finalizePipelineContext(pipelineContext);
         }
 
         return shaderProgram;
     }
 
-    private _finalizeProgram(shaderProgram: WebGLProgram) {
-        const context = shaderProgram.context!;
-        const vertexShader = shaderProgram.vertexShader!;
-        const fragmentShader = shaderProgram.fragmentShader!;
+    private _finalizePipelineContext(pipelineContext: WebGLPipelineContext) {
+        const context = pipelineContext.context!;
+        const vertexShader = pipelineContext.vertexShader!;
+        const fragmentShader = pipelineContext.fragmentShader!;
+        const program = pipelineContext.program!;
 
-        var linked = context.getProgramParameter(shaderProgram, context.LINK_STATUS);
+        var linked = context.getProgramParameter(program, context.LINK_STATUS);
 
         if (!linked) { // Get more info
 
@@ -3452,18 +3481,18 @@ export class Engine {
                 }
             }
 
-            var error = context.getProgramInfoLog(shaderProgram);
+            var error = context.getProgramInfoLog(program);
             if (error) {
                 throw new Error(error);
             }
         }
 
         if (this.validateShaderPrograms) {
-            context.validateProgram(shaderProgram);
-            var validated = context.getProgramParameter(shaderProgram, context.VALIDATE_STATUS);
+            context.validateProgram(program);
+            var validated = context.getProgramParameter(program, context.VALIDATE_STATUS);
 
             if (!validated) {
-                var error = context.getProgramInfoLog(shaderProgram);
+                var error = context.getProgramInfoLog(program);
                 if (error) {
                     throw new Error(error);
                 }
@@ -3473,24 +3502,37 @@ export class Engine {
         context.deleteShader(vertexShader);
         context.deleteShader(fragmentShader);
 
-        shaderProgram.context = undefined;
-        shaderProgram.vertexShader = undefined;
-        shaderProgram.fragmentShader = undefined;
+        pipelineContext.context = undefined;
+        pipelineContext.vertexShader = undefined;
+        pipelineContext.fragmentShader = undefined;
 
-        if (shaderProgram.onCompiled) {
-            shaderProgram.onCompiled();
-            shaderProgram.onCompiled = undefined;
+        if (pipelineContext.onCompiled) {
+            pipelineContext.onCompiled();
+            pipelineContext.onCompiled = undefined;
         }
     }
 
     /** @hidden */
-    public _isProgramCompiled(shaderProgram: WebGLProgram): boolean {
-        if (!shaderProgram.isParallelCompiled) {
-            return true;
+    public _preparePipelineContext(pipelineContext: IPipelineContext, vertexSourceCode: string, fragmentSourceCode: string, createAsRaw: boolean,
+        rebuildRebind: any,
+        defines: Nullable<string>,
+        transformFeedbackVaryings: Nullable<string[]>) {
+        let webGLRenderingState = pipelineContext as WebGLPipelineContext;
+
+        if (createAsRaw) {
+            webGLRenderingState.program = this.createRawShaderProgram(webGLRenderingState, vertexSourceCode, fragmentSourceCode, undefined, transformFeedbackVaryings);
         }
+        else {
+            webGLRenderingState.program = this.createShaderProgram(webGLRenderingState, vertexSourceCode, fragmentSourceCode, defines, undefined, transformFeedbackVaryings);
+        }
+        webGLRenderingState.program.__SPECTOR_rebuildProgram = rebuildRebind;
+    }
 
-        if (this._gl.getProgramParameter(shaderProgram, this._caps.parallelShaderCompile.COMPLETION_STATUS_KHR)) {
-            this._finalizeProgram(shaderProgram);
+    /** @hidden */
+    public _isRenderingStateCompiled(pipelineContext: IPipelineContext): boolean {
+        let webGLPipelineContext = pipelineContext as WebGLPipelineContext;
+        if (this._gl.getProgramParameter(webGLPipelineContext.program!, this._caps.parallelShaderCompile.COMPLETION_STATUS_KHR)) {
+            this._finalizePipelineContext(webGLPipelineContext);
             return true;
         }
 
@@ -3498,26 +3540,29 @@ export class Engine {
     }
 
     /** @hidden */
-    public _executeWhenProgramIsCompiled(shaderProgram: WebGLProgram, action: () => void) {
-        if (!shaderProgram.isParallelCompiled) {
+    public _executeWhenRenderingStateIsCompiled(pipelineContext: IPipelineContext, action: () => void) {
+        let webGLPipelineContext = pipelineContext as WebGLPipelineContext;
+
+        if (!webGLPipelineContext.isParallelCompiled) {
             action();
             return;
         }
 
-        shaderProgram.onCompiled = action;
+        webGLPipelineContext.onCompiled = action;
     }
 
     /**
      * Gets the list of webGL uniform locations associated with a specific program based on a list of uniform names
-     * @param shaderProgram defines the webGL program to use
+     * @param pipelineContext defines the pipeline context to use
      * @param uniformsNames defines the list of uniform names
      * @returns an array of webGL uniform locations
      */
-    public getUniforms(shaderProgram: WebGLProgram, uniformsNames: string[]): Nullable<WebGLUniformLocation>[] {
+    public getUniforms(pipelineContext: IPipelineContext, uniformsNames: string[]): Nullable<WebGLUniformLocation>[] {
         var results = new Array<Nullable<WebGLUniformLocation>>();
+        let webGLPipelineContext = pipelineContext as WebGLPipelineContext;
 
         for (var index = 0; index < uniformsNames.length; index++) {
-            results.push(this._gl.getUniformLocation(shaderProgram, uniformsNames[index]));
+            results.push(this._gl.getUniformLocation(webGLPipelineContext.program!, uniformsNames[index]));
         }
 
         return results;
@@ -3525,16 +3570,17 @@ export class Engine {
 
     /**
      * Gets the lsit of active attributes for a given webGL program
-     * @param shaderProgram defines the webGL program to use
+     * @param pipelineContext defines the pipeline context to use
      * @param attributesNames defines the list of attribute names to get
      * @returns an array of indices indicating the offset of each attribute
      */
-    public getAttributes(shaderProgram: WebGLProgram, attributesNames: string[]): number[] {
+    public getAttributes(pipelineContext: IPipelineContext, attributesNames: string[]): number[] {
         var results = [];
+        let webGLPipelineContext = pipelineContext as WebGLPipelineContext;
 
         for (var index = 0; index < attributesNames.length; index++) {
             try {
-                results.push(this._gl.getAttribLocation(shaderProgram, attributesNames[index]));
+                results.push(this._gl.getAttribLocation(webGLPipelineContext.program!, attributesNames[index]));
             } catch (e) {
                 results.push(-1);
             }
@@ -5361,7 +5407,8 @@ export class Engine {
      * @param effect defines the effect to bind
      */
     public bindSamplers(effect: Effect): void {
-        this.setProgram(effect.getProgram());
+        let webGLPipelineContext = effect.getPipelineContext() as WebGLPipelineContext;
+        this.setProgram(webGLPipelineContext.program!);
         var samplers = effect.getSamplers();
         for (var index = 0; index < samplers.length; index++) {
             var uniform = effect.getUniform(samplers[index]);
@@ -5803,7 +5850,8 @@ export class Engine {
      */
     public releaseEffects() {
         for (var name in this._compiledEffects) {
-            this._deleteProgram(this._compiledEffects[name]._program);
+            let webGLPipelineContext = this._compiledEffects[name].getPipelineContext() as WebGLPipelineContext;
+            this._deletePipelineContext(webGLPipelineContext);
         }
 
         this._compiledEffects = {};
@@ -6502,4 +6550,4 @@ export class Engine {
             return false;
         }
     }
-}
+}

+ 3 - 1
src/Engines/index.ts

@@ -2,4 +2,6 @@ export * from "./constants";
 export * from "./engine";
 export * from "./engineStore";
 export * from "./nullEngine";
-export * from "./Extensions/index";
+export * from "./Extensions/index";
+export * from "./IPipelineContext";
+export * from "./WebGL/webGLPipelineContext";

+ 20 - 27
src/Engines/nullEngine.ts

@@ -10,6 +10,8 @@ import { Effect } from "../Materials/effect";
 import { _TimeToken } from "../Instrumentation/timeToken";
 import { _DepthCullingState, _StencilState, _AlphaState } from "../States/index";
 import { Constants } from "./constants";
+import { IPipelineContext } from './IPipelineContext';
+import { DataBuffer } from '../Meshes/dataBuffer';
 
 declare const global: any;
 
@@ -144,20 +146,16 @@ export class NullEngine extends Engine {
         }
     }
 
-    public createVertexBuffer(vertices: FloatArray): WebGLBuffer {
-        return {
-            capacity: 0,
-            references: 1,
-            is32Bits: false
-        };
+    public createVertexBuffer(vertices: FloatArray): DataBuffer {
+        let buffer = new DataBuffer();
+        buffer.references = 1;
+        return buffer;
     }
 
-    public createIndexBuffer(indices: IndicesArray): WebGLBuffer {
-        return {
-            capacity: 0,
-            references: 1,
-            is32Bits: false
-        };
+    public createIndexBuffer(indices: IndicesArray): DataBuffer {
+        let buffer = new DataBuffer();
+        buffer.references = 1;
+        return buffer;
     }
 
     public clear(color: Color4, backBuffer: boolean, depth: boolean, stencil: boolean = false): void {
@@ -183,19 +181,17 @@ export class NullEngine extends Engine {
         this._cachedViewport = viewport;
     }
 
-    public createShaderProgram(vertexCode: string, fragmentCode: string, defines: string, context?: WebGLRenderingContext): WebGLProgram {
+    public createShaderProgram(pipelineContext: IPipelineContext, vertexCode: string, fragmentCode: string, defines: string, context?: WebGLRenderingContext): WebGLProgram {
         return {
-            transformFeedback: null,
             __SPECTOR_rebuildProgram: null,
-            isParallelCompiled: false
         };
     }
 
-    public getUniforms(shaderProgram: WebGLProgram, uniformsNames: string[]): WebGLUniformLocation[] {
+    public getUniforms(pipelineContext: IPipelineContext, uniformsNames: string[]): Nullable<WebGLUniformLocation>[] {
         return [];
     }
 
-    public getAttributes(shaderProgram: WebGLProgram, attributesNames: string[]): number[] {
+    public getAttributes(pipelineContext: IPipelineContext, attributesNames: string[]): number[] {
         return [];
     }
 
@@ -299,7 +295,7 @@ export class NullEngine extends Engine {
         this._alphaMode = mode;
     }
 
-    public bindBuffers(vertexBuffers: { [key: string]: VertexBuffer; }, indexBuffer: WebGLBuffer, effect: Effect): void {
+    public bindBuffers(vertexBuffers: { [key: string]: VertexBuffer; }, indexBuffer: DataBuffer, effect: Effect): void {
     }
 
     public wipeCaches(bruteForce?: boolean): void {
@@ -434,14 +430,11 @@ export class NullEngine extends Engine {
         this._currentFramebuffer = null;
     }
 
-    public createDynamicVertexBuffer(vertices: FloatArray): WebGLBuffer {
-        var vbo = {
-            capacity: 1,
-            references: 1,
-            is32Bits: false
-        };
-
-        return vbo;
+    public createDynamicVertexBuffer(vertices: FloatArray): DataBuffer {
+        let buffer = new DataBuffer();
+        buffer.references = 1;
+        buffer.capacity = 1;
+        return buffer;
     }
 
     public updateDynamicTexture(texture: Nullable<InternalTexture>, canvas: HTMLCanvasElement, invertY: boolean, premulAlpha: boolean = false, format?: number): void {
@@ -502,7 +495,7 @@ export class NullEngine extends Engine {
     }
 
     /** @hidden */
-    public _releaseBuffer(buffer: WebGLBuffer): boolean {
+    public _releaseBuffer(buffer: DataBuffer): boolean {
         buffer.references--;
 
         if (buffer.references === 0) {

+ 2 - 1
src/Layers/effectLayer.ts

@@ -26,6 +26,7 @@ import { Constants } from "../Engines/constants";
 import "../Shaders/glowMapGeneration.fragment";
 import "../Shaders/glowMapGeneration.vertex";
 import { _DevTools } from '../Misc/devTools';
+import { DataBuffer } from '../Meshes/dataBuffer';
 
 /**
  * Effect layer options. This helps customizing the behaviour
@@ -70,7 +71,7 @@ export interface IEffectLayerOptions {
 export abstract class EffectLayer {
 
     private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};
-    private _indexBuffer: Nullable<WebGLBuffer>;
+    private _indexBuffer: Nullable<DataBuffer>;
     private _cachedDefines: string;
     private _effectLayerMapGenerationEffect: Effect;
     private _effectLayerOptions: IEffectLayerOptions;

+ 2 - 1
src/Layers/layer.ts

@@ -16,6 +16,7 @@ import { RenderTargetTexture } from "../Materials/Textures/renderTargetTexture";
 
 import "../Shaders/layer.fragment";
 import "../Shaders/layer.vertex";
+import { DataBuffer } from '../Meshes/dataBuffer';
 
 /**
  * This represents a full screen 2d layer.
@@ -78,7 +79,7 @@ export class Layer {
 
     private _scene: Scene;
     private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};
-    private _indexBuffer: Nullable<WebGLBuffer>;
+    private _indexBuffer: Nullable<DataBuffer>;
     private _effect: Effect;
     private _alphaTestEffect: Effect;
 

+ 2 - 1
src/LensFlares/lensFlareSystem.ts

@@ -17,6 +17,7 @@ import { Constants } from "../Engines/constants";
 import "../Shaders/lensFlare.fragment";
 import "../Shaders/lensFlare.vertex";
 import { _DevTools } from '../Misc/devTools';
+import { DataBuffer } from '../Meshes/dataBuffer';
 
 /**
  * This represents a Lens Flare System or the shiny effect created by the light reflection on the  camera lenses.
@@ -58,7 +59,7 @@ export class LensFlareSystem {
     private _scene: Scene;
     private _emitter: any;
     private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};
-    private _indexBuffer: Nullable<WebGLBuffer>;
+    private _indexBuffer: Nullable<DataBuffer>;
     private _effect: Effect;
     private _positionX: number;
     private _positionY: number;

+ 0 - 16
src/LibDeclarations/webgl.d.ts

@@ -1,12 +1,3 @@
-
-interface WebGLProgram {
-    context?: WebGLRenderingContext;
-    vertexShader?: WebGLShader;
-    fragmentShader?: WebGLShader;
-    isParallelCompiled: boolean;
-    onCompiled?: () => void;
-}
-
 interface WebGLRenderingContext {
     drawArraysInstanced(mode: number, first: number, count: number, primcount: number): void;
     drawElementsInstanced(mode: number, count: number, type: number, offset: number, primcount: number): void;
@@ -70,14 +61,7 @@ interface WebGLRenderingContext {
     QUERY_RESULT: number;
 }
 
-interface WebGLBuffer {
-    references: number;
-    capacity: number;
-    is32Bits: boolean;
-}
-
 interface WebGLProgram {
-    transformFeedback?: WebGLTransformFeedback | null;
     __SPECTOR_rebuildProgram?: ((vertexSourceCode: string, fragmentSourceCode: string, onCompiled: (program: WebGLProgram) => void, onError: (message: string) => void) => void) | null;
 }
 

+ 2 - 1
src/Materials/Textures/Procedurals/proceduralTexture.ts

@@ -17,6 +17,7 @@ import { ProceduralTextureSceneComponent } from "./proceduralTextureSceneCompone
 
 import "../../../Engines/Extensions/engine.renderTarget";
 import "../../../Shaders/procedural.vertex";
+import { DataBuffer } from '../../../Meshes/dataBuffer';
 
 /**
  * Procedural texturing is a way to programmatically create a texture. There are 2 types of procedural textures: code-only, and code that references some classic 2D images, sometimes calmpler' images.
@@ -61,7 +62,7 @@ export class ProceduralTexture extends Texture {
     private _currentRefreshId = -1;
     private _refreshRate = 1;
     private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};
-    private _indexBuffer: Nullable<WebGLBuffer>;
+    private _indexBuffer: Nullable<DataBuffer>;
     private _uniforms = new Array<string>();
     private _samplers = new Array<string>();
     private _fragment: any;

+ 32 - 39
src/Materials/effect.ts

@@ -5,6 +5,8 @@ import { Constants } from "../Engines/constants";
 import { DomManagement } from "../Misc/domManagement";
 import { Logger } from "../Misc/logger";
 import { IDisposable } from '../scene';
+import { IPipelineContext } from '../Engines/IPipelineContext';
+import { DataBuffer } from '../Meshes/dataBuffer';
 
 declare type Engine = import("../Engines/engine").Engine;
 declare type InternalTexture = import("../Materials/Textures/internalTexture").InternalTexture;
@@ -243,12 +245,12 @@ export class Effect implements IDisposable {
     private _uniformBuffersNames: { [key: string]: number } = {};
     private _uniformsNames: string[];
     private _samplerList: string[];
-    private _samplers: {[key: string]: number} = {};
+    private _samplers: { [key: string]: number } = {};
     private _isReady = false;
     private _compilationError = "";
     private _attributesNames: string[];
     private _attributes: number[];
-    private _uniforms: {[key: string] : Nullable<WebGLUniformLocation>} = {};
+    private _uniforms: { [key: string]: Nullable<WebGLUniformLocation> } = {};
     /**
      * Key for the effect.
      * @hidden
@@ -265,9 +267,9 @@ export class Effect implements IDisposable {
      * Compiled shader to webGL program.
      * @hidden
      */
-    public _program: WebGLProgram;
+    public _pipelineContext: IPipelineContext;
     private _valueCache: { [key: string]: any };
-    private static _baseCache: { [key: number]: WebGLBuffer } = {};
+    private static _baseCache: { [key: number]: DataBuffer } = {};
 
     /**
      * Instantiates an effect.
@@ -382,10 +384,7 @@ export class Effect implements IDisposable {
      * @returns if the effect is compiled and prepared.
      */
     public isReady(): boolean {
-        if (!this._isReady && this._program && this._program.isParallelCompiled) {
-            return this._engine._isProgramCompiled(this._program);
-        }
-        return this._isReady;
+        return this._isReady && this._pipelineContext.isReady;
     }
 
     /**
@@ -397,11 +396,11 @@ export class Effect implements IDisposable {
     }
 
     /**
-     * The compiled webGL program for the effect
-     * @returns the webGL program.
+     * The pipeline context for this effect
+     * @returns the associated pipeline context
      */
-    public getProgram(): WebGLProgram {
-        return this._program;
+    public getPipelineContext(): IPipelineContext {
+        return this._pipelineContext;
     }
 
     /**
@@ -488,7 +487,7 @@ export class Effect implements IDisposable {
             func(effect);
         });
 
-        if (!this._program || this._program.isParallelCompiled) {
+        if (!this._pipelineContext || this._pipelineContext.isAsync) {
             setTimeout(() => {
                 this._checkIsReady();
             }, 16);
@@ -772,7 +771,7 @@ export class Effect implements IDisposable {
      * @param onError Callback called on error.
      * @hidden
      */
-    public _rebuildProgram(vertexSourceCode: string, fragmentSourceCode: string, onCompiled: (program: WebGLProgram) => void, onError: (message: string) => void) {
+    public _rebuildProgram(vertexSourceCode: string, fragmentSourceCode: string, onCompiled: (pipelineContext: IPipelineContext) => void, onError: (message: string) => void) {
         this._isReady = false;
 
         this._vertexSourceCodeOverride = vertexSourceCode;
@@ -789,7 +788,7 @@ export class Effect implements IDisposable {
             }
 
             if (onCompiled) {
-                onCompiled(this._program);
+                onCompiled(this._pipelineContext);
             }
         };
         this._fallbacks = null;
@@ -797,16 +796,6 @@ export class Effect implements IDisposable {
     }
 
     /**
-     * Gets the uniform locations of the the specified variable names
-     * @param names THe names of the variables to lookup.
-     * @returns Array of locations in the same order as variable names.
-     */
-    public getSpecificUniformLocations(names: string[]): Nullable<WebGLUniformLocation>[] {
-        let engine = this._engine;
-        return engine.getUniforms(this._program, names);
-    }
-
-    /**
      * Prepares the effect
      * @hidden
      */
@@ -816,32 +805,36 @@ export class Effect implements IDisposable {
         let fallbacks = this._fallbacks;
         this._valueCache = {};
 
-        var previousProgram = this._program;
+        var previousPipelineContext = this._pipelineContext;
 
         try {
             let engine = this._engine;
 
+            if (!this._pipelineContext) {
+                this._pipelineContext = engine.createPipelineContext();
+            }
+
+            let rebuildRebind = this._rebuildProgram.bind(this);
             if (this._vertexSourceCodeOverride && this._fragmentSourceCodeOverride) {
-                this._program = engine.createRawShaderProgram(this._vertexSourceCodeOverride, this._fragmentSourceCodeOverride, undefined, this._transformFeedbackVaryings);
+                engine._preparePipelineContext(this._pipelineContext, this._vertexSourceCodeOverride, this._fragmentSourceCodeOverride, true, rebuildRebind, null, this._transformFeedbackVaryings);
             }
             else {
-                this._program = engine.createShaderProgram(this._vertexSourceCode, this._fragmentSourceCode, defines, undefined, this._transformFeedbackVaryings);
+                engine._preparePipelineContext(this._pipelineContext, this._vertexSourceCode, this._fragmentSourceCode, false, rebuildRebind, defines, this._transformFeedbackVaryings);
             }
-            this._program.__SPECTOR_rebuildProgram = this._rebuildProgram.bind(this);
 
-            engine._executeWhenProgramIsCompiled(this._program, () => {
+            engine._executeWhenRenderingStateIsCompiled(this._pipelineContext, () => {
                 if (engine.supportsUniformBuffers) {
                     for (var name in this._uniformBuffersNames) {
                         this.bindUniformBlock(name, this._uniformBuffersNames[name]);
                     }
                 }
 
-                let uniforms = engine.getUniforms(this._program, this._uniformsNames);
+                let uniforms = engine.getUniforms(this._pipelineContext, this._uniformsNames);
                 uniforms.forEach((uniform, index) => {
                     this._uniforms[this._uniformsNames[index]] = uniform;
                 });
 
-                this._attributes = engine.getAttributes(this._program, attributesNames);
+                this._attributes = engine.getAttributes(this._pipelineContext, attributesNames);
 
                 var index: number;
                 for (index = 0; index < this._samplerList.length; index++) {
@@ -872,12 +865,12 @@ export class Effect implements IDisposable {
                     this._fallbacks.unBindMesh();
                 }
 
-                if (previousProgram) {
-                    this.getEngine()._deleteProgram(previousProgram);
+                if (previousPipelineContext) {
+                    this.getEngine()._deletePipelineContext(previousPipelineContext);
                 }
             });
 
-            if (this._program.isParallelCompiled) {
+            if (this._pipelineContext.isAsync) {
                 this._checkIsReady();
             }
 
@@ -893,8 +886,8 @@ export class Effect implements IDisposable {
                 return " " + attribute;
             }));
             Logger.Error("Error: " + this._compilationError);
-            if (previousProgram) {
-                this._program = previousProgram;
+            if (previousPipelineContext) {
+                this._pipelineContext = previousPipelineContext;
                 this._isReady = true;
                 if (this.onError) {
                     this.onError(this, this._compilationError);
@@ -1090,7 +1083,7 @@ export class Effect implements IDisposable {
      * @param buffer Buffer to bind.
      * @param name Name of the uniform variable to bind to.
      */
-    public bindUniformBuffer(buffer: WebGLBuffer, name: string): void {
+    public bindUniformBuffer(buffer: DataBuffer, name: string): void {
         let bufferName = this._uniformBuffersNames[name];
         if (bufferName === undefined || Effect._baseCache[bufferName] === buffer) {
             return;
@@ -1105,7 +1098,7 @@ export class Effect implements IDisposable {
      * @param index Index to bind.
      */
     public bindUniformBlock(blockName: string, index: number): void {
-        this._engine.bindUniformBlock(this._program, blockName, index);
+        this._engine.bindUniformBlock(this._pipelineContext, blockName, index);
     }
 
     /**

+ 3 - 2
src/Materials/uniformBuffer.ts

@@ -4,6 +4,7 @@ import { Matrix, Vector3, Color3, Vector4 } from "../Maths/math";
 import { Engine } from "../Engines/engine";
 import { Effect } from "./effect";
 import { BaseTexture } from "../Materials/Textures/baseTexture";
+import { DataBuffer } from '../Meshes/dataBuffer';
 /**
  * Uniform buffer objects.
  *
@@ -16,7 +17,7 @@ import { BaseTexture } from "../Materials/Textures/baseTexture";
  */
 export class UniformBuffer {
     private _engine: Engine;
-    private _buffer: Nullable<WebGLBuffer>;
+    private _buffer: Nullable<DataBuffer>;
     private _data: number[];
     private _bufferData: Float32Array;
     private _dynamic?: boolean;
@@ -201,7 +202,7 @@ export class UniformBuffer {
      * The underlying WebGL Uniform buffer.
      * @returns the webgl buffer
      */
-    public getBuffer(): Nullable<WebGLBuffer> {
+    public getBuffer(): Nullable<DataBuffer> {
         return this._buffer;
     }
 

+ 16 - 0
src/Meshes/WebGL/webGLDataBuffer.ts

@@ -0,0 +1,16 @@
+import { DataBuffer } from '../dataBuffer';
+import { Nullable } from '../../types';
+
+/** @hidden */
+export class WebGLDataBuffer extends DataBuffer {
+    private _buffer: Nullable<WebGLBuffer>;
+
+    public constructor(resource: WebGLBuffer) {
+        super();
+        this._buffer = resource;
+    }
+
+    public get underlyingResource(): any {
+        return this._buffer;
+    }
+}

+ 4 - 0
src/Meshes/abstractMesh.ts

@@ -270,6 +270,10 @@ export class AbstractMesh extends TransformNode implements IDisposable, ICullabl
 
     /** @hidden */
     public _isActive = false;
+
+    /** @hidden */
+    public _onlyForInstances = false;
+
     /** @hidden */
     public _renderingGroup: Nullable<RenderingGroup> = null;
 

+ 4 - 3
src/Meshes/buffer.ts

@@ -1,12 +1,13 @@
 import { Nullable, DataArray } from "../types";
 import { Engine } from "../Engines/engine";
+import { DataBuffer } from './dataBuffer';
 
 /**
  * Class used to store data that will be store in GPU memory
  */
 export class Buffer {
     private _engine: Engine;
-    private _buffer: Nullable<WebGLBuffer>;
+    private _buffer: Nullable<DataBuffer>;
     /** @hidden */
     public _data: Nullable<DataArray>;
     private _updatable: boolean;
@@ -87,7 +88,7 @@ export class Buffer {
      * Gets underlying native buffer
      * @returns underlying native buffer
      */
-    public getBuffer(): Nullable<WebGLBuffer> {
+    public getBuffer(): Nullable<DataBuffer> {
         return this._buffer;
     }
 
@@ -357,7 +358,7 @@ export class VertexBuffer {
      * Gets underlying native buffer
      * @returns underlying native buffer
      */
-    public getBuffer(): Nullable<WebGLBuffer> {
+    public getBuffer(): Nullable<DataBuffer> {
         return this._buffer.getBuffer();
     }
 

+ 22 - 0
src/Meshes/dataBuffer.ts

@@ -0,0 +1,22 @@
+/**
+ * Class used to store gfx data (like WebGLBuffer)
+ */
+export class DataBuffer {
+    /**
+     * Gets or sets the number of objects referencing this buffer
+     */
+    public references: number = 0;
+    /** Gets or sets the size of the underlying buffer */
+    public capacity: number = 0;
+    /**
+     * Gets or sets a boolean indicating if the buffer contains 32bits indices
+     */
+    public is32Bits: boolean = false;
+
+    /**
+     * Gets the underlying buffer
+     */
+    public get underlyingResource(): any {
+        return null;
+    }
+}

+ 5 - 4
src/Meshes/geometry.ts

@@ -12,6 +12,7 @@ import { BoundingInfo } from "../Culling/boundingInfo";
 import { Constants } from "../Engines/constants";
 import { Tools } from "../Misc/tools";
 import { Tags } from "../Misc/tags";
+import { DataBuffer } from './dataBuffer';
 
 declare type Mesh = import("../Meshes/mesh").Mesh;
 
@@ -55,7 +56,7 @@ export class Geometry implements IGetSetVerticesData {
     private _boundingBias: Vector2;
     /** @hidden */
     public _delayInfo: Array<string>;
-    private _indexBuffer: Nullable<WebGLBuffer>;
+    private _indexBuffer: Nullable<DataBuffer>;
     private _indexBufferIsUpdatable = false;
     /** @hidden */
     public _boundingInfo: Nullable<BoundingInfo>;
@@ -285,7 +286,7 @@ export class Geometry implements IGetSetVerticesData {
 
     /**
      * Update a specific vertex buffer
-     * This function will directly update the underlying WebGLBuffer according to the passed numeric array or Float32Array
+     * This function will directly update the underlying DataBuffer according to the passed numeric array or Float32Array
      * It will do nothing if the buffer is not updatable
      * @param kind defines the data kind (Position, normal, etc...)
      * @param data defines the data to use
@@ -351,7 +352,7 @@ export class Geometry implements IGetSetVerticesData {
     }
 
     /** @hidden */
-    public _bind(effect: Nullable<Effect>, indexToBind?: Nullable<WebGLBuffer>): void {
+    public _bind(effect: Nullable<Effect>, indexToBind?: Nullable<DataBuffer>): void {
         if (!effect) {
             return;
         }
@@ -615,7 +616,7 @@ export class Geometry implements IGetSetVerticesData {
      * Gets the index buffer
      * @return the index buffer
      */
-    public getIndexBuffer(): Nullable<WebGLBuffer> {
+    public getIndexBuffer(): Nullable<DataBuffer> {
         if (!this.isReady()) {
             return null;
         }

+ 4 - 1
src/Meshes/index.ts

@@ -14,5 +14,8 @@ export * from "./meshSimplification";
 export * from "./meshSimplificationSceneComponent";
 export * from "./polygonMesh";
 export * from "./subMesh";
+export * from "./meshLODLevel";
 export * from "./transformNode";
-export * from "./Builders/index";
+export * from "./Builders/index";
+export * from "./dataBuffer";
+export * from "./WebGL/webGLDataBuffer";

+ 15 - 1
src/Meshes/instancedMesh.ts

@@ -1,5 +1,5 @@
 import { Nullable, FloatArray, IndicesArray } from "../types";
-import { Vector3 } from "../Maths/math";
+import { Vector3, Matrix, Tmp } from "../Maths/math";
 import { Logger } from "../Misc/logger";
 import { Camera } from "../Cameras/camera";
 import { Node } from "../node";
@@ -8,6 +8,7 @@ import { Mesh } from "../Meshes/mesh";
 import { Material } from "../Materials/material";
 import { Skeleton } from "../Bones/skeleton";
 import { DeepCopier } from "../Misc/deepCopier";
+import { TransformNode } from './transformNode';
 
 Mesh._instancedMeshFactory = (name: string, mesh: Mesh): InstancedMesh => {
     return new InstancedMesh(name, mesh);
@@ -269,12 +270,25 @@ export class InstancedMesh extends AbstractMesh {
         }
 
         if (!this._currentLOD._isActive) {
+            this._currentLOD._onlyForInstances = true;
             this._currentLOD._isActive = true;
             return true;
         }
         return false;
     }
 
+    public getWorldMatrix(): Matrix {
+        if (this._currentLOD && this._currentLOD.billboardMode !== TransformNode.BILLBOARDMODE_NONE) {
+            this._worldMatrix.getTranslationToRef(Tmp.Vector3[0]);
+            this._worldMatrix.copyFrom(this._currentLOD.getWorldMatrix());
+            this._worldMatrix.setTranslation(Tmp.Vector3[0]);
+
+            return this._worldMatrix;
+        }
+
+        return super.getWorldMatrix();
+    }
+
     /**
      * Returns the current associated LOD AbstractMesh.
      */

+ 4 - 19
src/Meshes/mesh.ts

@@ -28,6 +28,7 @@ import { Logger } from "../Misc/logger";
 import { _TypeStore } from '../Misc/typeStore';
 import { _DevTools } from '../Misc/devTools';
 import { SceneComponentConstants } from "../sceneComponent";
+import { MeshLODLevel } from './meshLODLevel';
 
 declare type LinesMesh = import("./linesMesh").LinesMesh;
 declare type InstancedMesh = import("./instancedMesh").InstancedMesh;
@@ -38,24 +39,6 @@ declare type PhysicsImpostor = import("../Physics/physicsImpostor").PhysicsImpos
 declare var earcut: any;
 
 /**
- * Class used to represent a specific level of detail of a mesh
- * @see http://doc.babylonjs.com/how_to/how_to_use_lod
- */
-export class MeshLODLevel {
-    /**
-     * Creates a new LOD level
-     * @param distance defines the distance where this level should star being displayed
-     * @param mesh defines the mesh to use to render this level
-     */
-    constructor(
-        /** Defines the distance where this level should star being displayed */
-        public distance: number,
-        /** Defines the mesh to use to render this level */
-        public mesh: Nullable<Mesh>) {
-    }
-}
-
-/**
  * @hidden
  **/
 export class _CreationDataStorage {
@@ -1324,6 +1307,8 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
             engine.drawElementsType(fillMode, subMesh.indexStart, subMesh.indexCount, instancesCount);
         }
 
+        this._isActive = false;
+
         return this;
     }
 
@@ -1375,7 +1360,7 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
         var scene = this.getScene();
         let batchCache = this._instanceDataStorage.batchCache;
         batchCache.mustReturn = false;
-        batchCache.renderSelf[subMeshId] = this.isEnabled() && this.isVisible;
+        batchCache.renderSelf[subMeshId] = !this._onlyForInstances && this.isEnabled() && this.isVisible;
         batchCache.visibleInstances[subMeshId] = null;
 
         if (this._instanceDataStorage.visibleInstances) {

+ 20 - 0
src/Meshes/meshLODLevel.ts

@@ -0,0 +1,20 @@
+import { Mesh } from './mesh';
+import { Nullable } from '../types';
+
+/**
+ * Class used to represent a specific level of detail of a mesh
+ * @see http://doc.babylonjs.com/how_to/how_to_use_lod
+ */
+export class MeshLODLevel {
+    /**
+     * Creates a new LOD level
+     * @param distance defines the distance where this level should star being displayed
+     * @param mesh defines the mesh to use to render this level
+     */
+    constructor(
+        /** Defines the distance where this level should star being displayed */
+        public distance: number,
+        /** Defines the mesh to use to render this level */
+        public mesh: Nullable<Mesh>) {
+    }
+}

+ 3 - 2
src/Meshes/subMesh.ts

@@ -7,6 +7,7 @@ import { IntersectionInfo } from "../Collisions/intersectionInfo";
 import { ICullable, BoundingInfo } from "../Culling/boundingInfo";
 import { Effect } from "../Materials/effect";
 import { Constants } from "../Engines/constants";
+import { DataBuffer } from './dataBuffer';
 
 declare type Collider = import("../Collisions/collider").Collider;
 declare type Material = import("../Materials/material").Material;
@@ -59,7 +60,7 @@ export class SubMesh extends BaseSubMesh implements ICullable {
     private _mesh: AbstractMesh;
     private _renderingMesh: Mesh;
     private _boundingInfo: BoundingInfo;
-    private _linesIndexBuffer: Nullable<WebGLBuffer> = null;
+    private _linesIndexBuffer: Nullable<DataBuffer> = null;
     /** @hidden */
     public _lastColliderWorldVertices: Nullable<Vector3[]> = null;
     /** @hidden */
@@ -310,7 +311,7 @@ export class SubMesh extends BaseSubMesh implements ICullable {
     /**
      * @hidden
      */
-    public _getLinesIndexBuffer(indices: IndicesArray, engine: Engine): WebGLBuffer {
+    public _getLinesIndexBuffer(indices: IndicesArray, engine: Engine): DataBuffer {
         if (!this._linesIndexBuffer) {
             var linesIndices = [];
 

+ 2 - 1
src/Particles/particleSystem.ts

@@ -27,6 +27,7 @@ import { _TypeStore } from '../Misc/typeStore';
 
 import "../Shaders/particles.fragment";
 import "../Shaders/particles.vertex";
+import { DataBuffer } from '../Meshes/dataBuffer';
 
 /**
  * This represents a particle system in Babylon.
@@ -98,7 +99,7 @@ export class ParticleSystem extends BaseParticleSystem implements IDisposable, I
     private _vertexBuffer: Nullable<Buffer>;
     private _vertexBuffers: { [key: string]: VertexBuffer } = {};
     private _spriteBuffer: Nullable<Buffer>;
-    private _indexBuffer: Nullable<WebGLBuffer>;
+    private _indexBuffer: Nullable<DataBuffer>;
     private _effect: Effect;
     private _customEffect: Nullable<Effect>;
     private _cachedDefines: string;

+ 1 - 1
src/PostProcesses/RenderPipeline/postProcessRenderEffect.ts

@@ -129,7 +129,7 @@ export class PostProcessRenderEffect {
     }
 
     /**
-     * Detatches the effect on cameras
+     * Detaches the effect on cameras
      * @param cameras The camera to detatch from.
      * @hidden
      */

+ 8 - 0
src/PostProcesses/depthOfFieldEffect.ts

@@ -145,6 +145,14 @@ export class DepthOfFieldEffect extends PostProcessRenderEffect {
     }
 
     /**
+    * Get the current class name of the current effet
+    * @returns "DepthOfFieldEffect"
+    */
+    public getClassName(): string {
+        return "DepthOfFieldEffect";
+    }
+
+    /**
      * Depth texture to be used to compute the circle of confusion. This must be set here or in the constructor in order for the post process to function.
      */
     public set depthTexture(value: RenderTargetTexture) {

+ 3 - 2
src/PostProcesses/postProcessManager.ts

@@ -4,8 +4,9 @@ import { InternalTexture } from "../Materials/Textures/internalTexture";
 import { PostProcess } from "./postProcess";
 import { VertexBuffer } from "../Meshes/buffer";
 import { Constants } from "../Engines/constants";
+import { DataBuffer } from '../Meshes/dataBuffer';
 
-declare type Scene  = import("../scene").Scene;
+declare type Scene = import("../scene").Scene;
 
 /**
  * PostProcessManager is used to manage one or more post processes or post process pipelines
@@ -13,7 +14,7 @@ declare type Scene  = import("../scene").Scene;
  */
 export class PostProcessManager {
     private _scene: Scene;
-    private _indexBuffer: Nullable<WebGLBuffer>;
+    private _indexBuffer: Nullable<DataBuffer>;
     private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};
 
     /**

+ 2 - 1
src/Rendering/boundingBoxRenderer.ts

@@ -16,6 +16,7 @@ import "../Meshes/Builders/boxBuilder";
 
 import "../Shaders/color.fragment";
 import "../Shaders/color.vertex";
+import { DataBuffer } from '../Meshes/dataBuffer';
 
 declare module "../scene" {
     export interface Scene {
@@ -123,7 +124,7 @@ export class BoundingBoxRenderer implements ISceneComponent {
 
     private _colorShader: ShaderMaterial;
     private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};
-    private _indexBuffer: WebGLBuffer;
+    private _indexBuffer: DataBuffer;
 
     /**
      * Instantiates a new bounding box renderer in a scene.

+ 2 - 1
src/Rendering/edgesRenderer.ts

@@ -14,6 +14,7 @@ import { Node } from "../node";
 
 import "../Shaders/line.fragment";
 import "../Shaders/line.vertex";
+import { DataBuffer } from '../Meshes/dataBuffer';
 
 declare module "../Meshes/abstractMesh" {
     export interface AbstractMesh {
@@ -154,7 +155,7 @@ export class EdgesRenderer implements IEdgesRenderer {
     protected _indicesCount: number;
 
     protected _lineShader: ShaderMaterial;
-    protected _ib: WebGLBuffer;
+    protected _ib: DataBuffer;
     protected _buffers: { [key: string]: Nullable<VertexBuffer> } = {};
     protected _checkVerticesInsteadOfIndices = false;
 

+ 14 - 4
src/Rendering/geometryBufferRenderer.ts

@@ -104,6 +104,11 @@ export class GeometryBufferRenderer {
      */
     public set enableVelocity(enable: boolean) {
         this._enableVelocity = enable;
+
+        if (!enable) {
+            this._previousTransformationMatrices = {};
+        }
+
         this.dispose();
         this._createRenderTargets();
     }
@@ -218,7 +223,7 @@ export class GeometryBufferRenderer {
             this._cachedDefines = join;
             this._effect = this._scene.getEngine().createEffect("geometry",
                 attribs,
-                ["world", "mBones", "viewProjection", "diffuseMatrix", "view", "previousWorldViewProjection"],
+                ["world", "mBones", "viewProjection", "diffuseMatrix", "view", "previousWorldViewProjection", "currentWorldViewProjection"],
                 ["diffuseSampler"], join,
                 undefined, undefined, undefined,
                 { buffersCount: this._enablePosition ? 3 : 2 });
@@ -299,7 +304,7 @@ export class GeometryBufferRenderer {
             }
 
             // Velocity
-            if (!this._previousTransformationMatrices[mesh.uniqueId]) {
+            if (this._enableVelocity && !this._previousTransformationMatrices[mesh.uniqueId]) {
                 this._previousTransformationMatrices[mesh.uniqueId] = Matrix.Identity();
             }
 
@@ -338,7 +343,10 @@ export class GeometryBufferRenderer {
                 }
 
                 // Velocity
-                this._effect.setMatrix("previousWorldViewProjection", this._previousTransformationMatrices[mesh.uniqueId]);
+                if (this._enableVelocity) {
+                    this._effect.setMatrix("currentWorldViewProjection", mesh.getWorldMatrix().multiply(this._scene.getTransformMatrix()));
+                    this._effect.setMatrix("previousWorldViewProjection", this._previousTransformationMatrices[mesh.uniqueId]);
+                }
 
                 // Draw
                 mesh._processRendering(subMesh, this._effect, Material.TriangleFillMode, batch, hardwareInstancedRendering,
@@ -346,7 +354,9 @@ export class GeometryBufferRenderer {
             }
 
             // Velocity
-            this._previousTransformationMatrices[mesh.uniqueId] = mesh.getWorldMatrix().multiply(this._scene.getTransformMatrix());
+            if (this._enableVelocity) {
+                this._previousTransformationMatrices[mesh.uniqueId] = mesh.getWorldMatrix().multiply(this._scene.getTransformMatrix());
+            }
         };
 
         this._multiRenderTarget.customRenderFunction = (opaqueSubMeshes: SmartArray<SubMesh>, alphaTestSubMeshes: SmartArray<SubMesh>, transparentSubMeshes: SmartArray<SubMesh>, depthOnlySubMeshes: SmartArray<SubMesh>): void => {

+ 7 - 5
src/Shaders/geometry.vertex.fx

@@ -31,6 +31,7 @@ varying vec3 vPosition;
 
 #ifdef VELOCITY
 uniform mat4 previousWorldViewProjection;
+uniform mat4 currentWorldViewProjection;
 varying vec4 vCurrentPosition;
 varying vec4 vPreviousPosition;
 #endif
@@ -39,6 +40,12 @@ void main(void)
 {
 #include<instancesVertex>
 
+	#ifdef VELOCITY
+	// Compute velocity before bones computation
+	vCurrentPosition = currentWorldViewProjection * vec4(position, 1.0);
+	vPreviousPosition = previousWorldViewProjection * vec4(position, 1.0);
+	#endif
+
 #include<bonesVertex>
 	vec4 pos = vec4(finalWorld * vec4(position, 1.0));
 
@@ -49,11 +56,6 @@ void main(void)
 	vPosition = pos.xyz / pos.w;
 	#endif
 
-	#ifdef VELOCITY
-	vCurrentPosition = viewProjection * finalWorld * vec4(position, 1.0);
-	vPreviousPosition = previousWorldViewProjection * vec4(position, 1.0);
-	#endif
-
 	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 
 #if defined(ALPHATEST) || defined(BASIC_RENDER)

+ 2 - 1
src/Sprites/spriteManager.ts

@@ -16,6 +16,7 @@ import { Constants } from "../Engines/constants";
 
 import "../Shaders/sprites.fragment";
 import "../Shaders/sprites.vertex";
+import { DataBuffer } from '../Meshes/dataBuffer';
 declare type Ray = import("../Culling/ray").Ray;
 
 /**
@@ -106,7 +107,7 @@ export class SpriteManager implements ISpriteManager {
     private _vertexData: Float32Array;
     private _buffer: Buffer;
     private _vertexBuffers: { [key: string]: VertexBuffer } = {};
-    private _indexBuffer: WebGLBuffer;
+    private _indexBuffer: DataBuffer;
     private _effectBase: Effect;
     private _effectFog: Effect;
 

+ 2 - 2
src/scene.ts

@@ -3919,7 +3919,6 @@ export class Scene extends AbstractScene implements IAnimatable {
         const len = meshes.length;
         for (let i = 0; i < len; i++) {
             const mesh = meshes.data[i];
-            mesh._isActive = false;
             if (mesh.isBlocked) {
                 continue;
             }
@@ -3957,9 +3956,10 @@ export class Scene extends AbstractScene implements IAnimatable {
                 if (meshLOD !== mesh) {
                     meshLOD._activate(this._renderId);
                 }
+                meshLOD._onlyForInstances = false;
 
                 if (mesh._activate(this._renderId)) {
-                    mesh._isActive = true;
+                    meshLOD._isActive = true;
                     this._activeMesh(mesh, meshLOD);
                 }
             }