David Catuhe 6 سال پیش
والد
کامیت
db5a2b868e

+ 44 - 46
src/Materials/Background/backgroundMaterial.ts

@@ -909,7 +909,7 @@ export class BackgroundMaterial extends PushMaterial {
             };
 
             var join = defines.toString();
-            let effect = scene.getEngine().createEffect("background", <EffectCreationOptions>{
+            subMesh.setEffect(scene.getEngine().createEffect("background", <EffectCreationOptions>{
                 attributes: attribs,
                 uniformsNames: uniforms,
                 uniformBuffersNames: uniformBuffers,
@@ -919,10 +919,9 @@ export class BackgroundMaterial extends PushMaterial {
                 onCompiled: onCompiled,
                 onError: this.onError,
                 indexParameters: { maxSimultaneousLights: this._maxSimultaneousLights }
-            }, engine);
-            subMesh.setEffect(effect, defines);
+            }, engine), defines);
 
-            this.buildUniformLayout(effect);
+            this.buildUniformLayout();
         }
 
         if (!subMesh.effect || !subMesh.effect.isReady()) {
@@ -978,23 +977,23 @@ export class BackgroundMaterial extends PushMaterial {
     /**
      * Build the uniform buffer used in the material.
      */
-    public buildUniformLayout(effect: Effect): void {
+    public buildUniformLayout(): void {
         // Order is important !
-        effect._uniformBuffer.addUniform("vPrimaryColor", 4);
-        effect._uniformBuffer.addUniform("vPrimaryColorShadow", 4);
-        effect._uniformBuffer.addUniform("vDiffuseInfos", 2);
-        effect._uniformBuffer.addUniform("vReflectionInfos", 2);
-        effect._uniformBuffer.addUniform("diffuseMatrix", 16);
-        effect._uniformBuffer.addUniform("reflectionMatrix", 16);
-        effect._uniformBuffer.addUniform("vReflectionMicrosurfaceInfos", 3);
-        effect._uniformBuffer.addUniform("fFovMultiplier", 1);
-        effect._uniformBuffer.addUniform("pointSize", 1);
-        effect._uniformBuffer.addUniform("shadowLevel", 1);
-        effect._uniformBuffer.addUniform("alpha", 1);
-        effect._uniformBuffer.addUniform("vBackgroundCenter", 3);
-        effect._uniformBuffer.addUniform("vReflectionControl", 4);
-
-        effect._uniformBuffer.create();
+        this._uniformBuffer.addUniform("vPrimaryColor", 4);
+        this._uniformBuffer.addUniform("vPrimaryColorShadow", 4);
+        this._uniformBuffer.addUniform("vDiffuseInfos", 2);
+        this._uniformBuffer.addUniform("vReflectionInfos", 2);
+        this._uniformBuffer.addUniform("diffuseMatrix", 16);
+        this._uniformBuffer.addUniform("reflectionMatrix", 16);
+        this._uniformBuffer.addUniform("vReflectionMicrosurfaceInfos", 3);
+        this._uniformBuffer.addUniform("fFovMultiplier", 1);
+        this._uniformBuffer.addUniform("pointSize", 1);
+        this._uniformBuffer.addUniform("shadowLevel", 1);
+        this._uniformBuffer.addUniform("alpha", 1);
+        this._uniformBuffer.addUniform("vBackgroundCenter", 3);
+        this._uniformBuffer.addUniform("vReflectionControl", 4);
+
+        this._uniformBuffer.create();
     }
 
     /**
@@ -1002,11 +1001,11 @@ export class BackgroundMaterial extends PushMaterial {
      */
     public unbind(): void {
         if (this._diffuseTexture && this._diffuseTexture.isRenderTarget) {
-            this._activeEffect._uniformBuffer.setTexture("diffuseSampler", null);
+            this._uniformBuffer.setTexture("diffuseSampler", null);
         }
 
         if (this._reflectionTexture && this._reflectionTexture.isRenderTarget) {
-            this._activeEffect._uniformBuffer.setTexture("reflectionSampler", null);
+            this._uniformBuffer.setTexture("reflectionSampler", null);
         }
 
         super.unbind();
@@ -1046,27 +1045,26 @@ export class BackgroundMaterial extends PushMaterial {
         MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
 
         let mustRebind = this._mustRebind(scene, effect, mesh.visibility);
-        let uniformBuffer = effect._uniformBuffer;
         if (mustRebind) {
-            uniformBuffer.bindToEffect(effect, "Material");
+            this._uniformBuffer.bindToEffect(effect, "Material");
 
             this.bindViewProjection(effect);
 
             let reflectionTexture = this._reflectionTexture;
-            if (!uniformBuffer.useUbo || !this.isFrozen || !uniformBuffer.isSync) {
+            if (!this._uniformBuffer.useUbo || !this.isFrozen || !this._uniformBuffer.isSync) {
 
                 // Texture uniforms
                 if (scene.texturesEnabled) {
                     if (this._diffuseTexture && MaterialFlags.DiffuseTextureEnabled) {
-                        uniformBuffer.updateFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
-                        MaterialHelper.BindTextureMatrix(this._diffuseTexture, uniformBuffer, "diffuse");
+                        this._uniformBuffer.updateFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
+                        MaterialHelper.BindTextureMatrix(this._diffuseTexture, this._uniformBuffer, "diffuse");
                     }
 
                     if (reflectionTexture && MaterialFlags.ReflectionTextureEnabled) {
-                        uniformBuffer.updateMatrix("reflectionMatrix", reflectionTexture.getReflectionTextureMatrix());
-                        uniformBuffer.updateFloat2("vReflectionInfos", reflectionTexture.level, this._reflectionBlur);
+                        this._uniformBuffer.updateMatrix("reflectionMatrix", reflectionTexture.getReflectionTextureMatrix());
+                        this._uniformBuffer.updateFloat2("vReflectionInfos", reflectionTexture.level, this._reflectionBlur);
 
-                        uniformBuffer.updateFloat3("vReflectionMicrosurfaceInfos",
+                        this._uniformBuffer.updateFloat3("vReflectionMicrosurfaceInfos",
                             reflectionTexture.getSize().width,
                             reflectionTexture.lodGenerationScale,
                             reflectionTexture.lodGenerationOffset);
@@ -1074,48 +1072,48 @@ export class BackgroundMaterial extends PushMaterial {
                 }
 
                 if (this.shadowLevel > 0) {
-                    uniformBuffer.updateFloat("shadowLevel", this.shadowLevel);
+                    this._uniformBuffer.updateFloat("shadowLevel", this.shadowLevel);
                 }
-                uniformBuffer.updateFloat("alpha", this.alpha);
+                this._uniformBuffer.updateFloat("alpha", this.alpha);
 
                 // Point size
                 if (this.pointsCloud) {
-                    uniformBuffer.updateFloat("pointSize", this.pointSize);
+                    this._uniformBuffer.updateFloat("pointSize", this.pointSize);
                 }
 
                 if (defines.USEHIGHLIGHTANDSHADOWCOLORS) {
-                    uniformBuffer.updateColor4("vPrimaryColor", this._primaryHighlightColor, 1.0);
-                    uniformBuffer.updateColor4("vPrimaryColorShadow", this._primaryShadowColor, 1.0);
+                    this._uniformBuffer.updateColor4("vPrimaryColor", this._primaryHighlightColor, 1.0);
+                    this._uniformBuffer.updateColor4("vPrimaryColorShadow", this._primaryShadowColor, 1.0);
                 }
                 else {
-                    uniformBuffer.updateColor4("vPrimaryColor", this._primaryColor, 1.0);
+                    this._uniformBuffer.updateColor4("vPrimaryColor", this._primaryColor, 1.0);
                 }
             }
 
-            uniformBuffer.updateFloat("fFovMultiplier", this._fovMultiplier);
+            this._uniformBuffer.updateFloat("fFovMultiplier", this._fovMultiplier);
 
             // Textures
             if (scene.texturesEnabled) {
                 if (this._diffuseTexture && MaterialFlags.DiffuseTextureEnabled) {
-                    uniformBuffer.setTexture("diffuseSampler", this._diffuseTexture);
+                    this._uniformBuffer.setTexture("diffuseSampler", this._diffuseTexture);
                 }
 
                 if (reflectionTexture && MaterialFlags.ReflectionTextureEnabled) {
                     if (defines.REFLECTIONBLUR && defines.TEXTURELODSUPPORT) {
-                        uniformBuffer.setTexture("reflectionSampler", reflectionTexture);
+                        this._uniformBuffer.setTexture("reflectionSampler", reflectionTexture);
                     }
                     else if (!defines.REFLECTIONBLUR) {
-                        uniformBuffer.setTexture("reflectionSampler", reflectionTexture);
+                        this._uniformBuffer.setTexture("reflectionSampler", reflectionTexture);
                     }
                     else {
-                        uniformBuffer.setTexture("reflectionSampler", reflectionTexture._lodTextureMid || reflectionTexture);
-                        uniformBuffer.setTexture("reflectionSamplerLow", reflectionTexture._lodTextureLow || reflectionTexture);
-                        uniformBuffer.setTexture("reflectionSamplerHigh", reflectionTexture._lodTextureHigh || reflectionTexture);
+                        this._uniformBuffer.setTexture("reflectionSampler", reflectionTexture._lodTextureMid || reflectionTexture);
+                        this._uniformBuffer.setTexture("reflectionSamplerLow", reflectionTexture._lodTextureLow || reflectionTexture);
+                        this._uniformBuffer.setTexture("reflectionSamplerHigh", reflectionTexture._lodTextureHigh || reflectionTexture);
                     }
 
                     if (defines.REFLECTIONFRESNEL) {
-                        uniformBuffer.updateFloat3("vBackgroundCenter", this.sceneCenter.x, this.sceneCenter.y, this.sceneCenter.z);
-                        uniformBuffer.updateFloat4("vReflectionControl", this._reflectionControls.x, this._reflectionControls.y, this._reflectionControls.z, this._reflectionControls.w);
+                        this._uniformBuffer.updateFloat3("vBackgroundCenter", this.sceneCenter.x, this.sceneCenter.y, this.sceneCenter.z);
+                        this._uniformBuffer.updateFloat4("vReflectionControl", this._reflectionControls.x, this._reflectionControls.y, this._reflectionControls.z, this._reflectionControls.w);
                     }
                 }
             }
@@ -1143,7 +1141,7 @@ export class BackgroundMaterial extends PushMaterial {
             }
         }
 
-        uniformBuffer.update();
+        this._uniformBuffer.update();
 
         this._afterBind(mesh, this._activeEffect);
     }

+ 97 - 96
src/Materials/PBR/pbrBaseMaterial.ts

@@ -1009,7 +1009,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             } else {
                 scene.resetCachedMaterial();
                 subMesh.setEffect(effect, defines);
-                this.buildUniformLayout(effect);
+                this.buildUniformLayout();
             }
         }
 
@@ -1524,46 +1524,47 @@ export abstract class PBRBaseMaterial extends PushMaterial {
     /**
      * Initializes the uniform buffer layout for the shader.
      */
-    public buildUniformLayout(effect: Effect): void {
+    public buildUniformLayout(): void {
         // Order is important !
-        effect._uniformBuffer.addUniform("vAlbedoInfos", 2);
-        effect._uniformBuffer.addUniform("vAmbientInfos", 4);
-        effect._uniformBuffer.addUniform("vOpacityInfos", 2);
-        effect._uniformBuffer.addUniform("vEmissiveInfos", 2);
-        effect._uniformBuffer.addUniform("vLightmapInfos", 2);
-        effect._uniformBuffer.addUniform("vReflectivityInfos", 3);
-        effect._uniformBuffer.addUniform("vMicroSurfaceSamplerInfos", 2);
-        effect._uniformBuffer.addUniform("vReflectionInfos", 2);
-        effect._uniformBuffer.addUniform("vReflectionPosition", 3);
-        effect._uniformBuffer.addUniform("vReflectionSize", 3);
-        effect._uniformBuffer.addUniform("vBumpInfos", 3);
-        effect._uniformBuffer.addUniform("albedoMatrix", 16);
-        effect._uniformBuffer.addUniform("ambientMatrix", 16);
-        effect._uniformBuffer.addUniform("opacityMatrix", 16);
-        effect._uniformBuffer.addUniform("emissiveMatrix", 16);
-        effect._uniformBuffer.addUniform("lightmapMatrix", 16);
-        effect._uniformBuffer.addUniform("reflectivityMatrix", 16);
-        effect._uniformBuffer.addUniform("microSurfaceSamplerMatrix", 16);
-        effect._uniformBuffer.addUniform("bumpMatrix", 16);
-        effect._uniformBuffer.addUniform("vTangentSpaceParams", 2);
-        effect._uniformBuffer.addUniform("reflectionMatrix", 16);
-
-        effect._uniformBuffer.addUniform("vReflectionColor", 3);
-        effect._uniformBuffer.addUniform("vAlbedoColor", 4);
-        effect._uniformBuffer.addUniform("vLightingIntensity", 4);
-
-        effect._uniformBuffer.addUniform("vReflectionMicrosurfaceInfos", 3);
-        effect._uniformBuffer.addUniform("pointSize", 1);
-        effect._uniformBuffer.addUniform("vReflectivityColor", 4);
-        effect._uniformBuffer.addUniform("vEmissiveColor", 3);
-        effect._uniformBuffer.addUniform("visibility", 1);
-
-        PBRClearCoatConfiguration.PrepareUniformBuffer(effect._uniformBuffer);
-        PBRAnisotropicConfiguration.PrepareUniformBuffer(effect._uniformBuffer);
-        PBRSheenConfiguration.PrepareUniformBuffer(effect._uniformBuffer);
-        PBRSubSurfaceConfiguration.PrepareUniformBuffer(effect._uniformBuffer);
-
-        effect._uniformBuffer.create();
+        let ubo = this._uniformBuffer;
+        ubo.addUniform("vAlbedoInfos", 2);
+        ubo.addUniform("vAmbientInfos", 4);
+        ubo.addUniform("vOpacityInfos", 2);
+        ubo.addUniform("vEmissiveInfos", 2);
+        ubo.addUniform("vLightmapInfos", 2);
+        ubo.addUniform("vReflectivityInfos", 3);
+        ubo.addUniform("vMicroSurfaceSamplerInfos", 2);
+        ubo.addUniform("vReflectionInfos", 2);
+        ubo.addUniform("vReflectionPosition", 3);
+        ubo.addUniform("vReflectionSize", 3);
+        ubo.addUniform("vBumpInfos", 3);
+        ubo.addUniform("albedoMatrix", 16);
+        ubo.addUniform("ambientMatrix", 16);
+        ubo.addUniform("opacityMatrix", 16);
+        ubo.addUniform("emissiveMatrix", 16);
+        ubo.addUniform("lightmapMatrix", 16);
+        ubo.addUniform("reflectivityMatrix", 16);
+        ubo.addUniform("microSurfaceSamplerMatrix", 16);
+        ubo.addUniform("bumpMatrix", 16);
+        ubo.addUniform("vTangentSpaceParams", 2);
+        ubo.addUniform("reflectionMatrix", 16);
+
+        ubo.addUniform("vReflectionColor", 3);
+        ubo.addUniform("vAlbedoColor", 4);
+        ubo.addUniform("vLightingIntensity", 4);
+
+        ubo.addUniform("vReflectionMicrosurfaceInfos", 3);
+        ubo.addUniform("pointSize", 1);
+        ubo.addUniform("vReflectivityColor", 4);
+        ubo.addUniform("vEmissiveColor", 3);
+        ubo.addUniform("visibility", 1);
+
+        PBRClearCoatConfiguration.PrepareUniformBuffer(ubo);
+        PBRAnisotropicConfiguration.PrepareUniformBuffer(ubo);
+        PBRSheenConfiguration.PrepareUniformBuffer(ubo);
+        PBRSubSurfaceConfiguration.PrepareUniformBuffer(ubo);
+
+        ubo.create();
     }
 
     /**
@@ -1628,42 +1629,42 @@ export abstract class PBRBaseMaterial extends PushMaterial {
         MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
 
         let reflectionTexture: Nullable<BaseTexture> = null;
-        let uniformBuffer = effect._uniformBuffer;
+        let ubo = this._uniformBuffer;
         if (mustRebind) {
             var engine = scene.getEngine();
-            uniformBuffer.bindToEffect(effect, "Material");
+            ubo.bindToEffect(effect, "Material");
 
             this.bindViewProjection(effect);
             reflectionTexture = this._getReflectionTexture();
 
-            if (!uniformBuffer.useUbo || !this.isFrozen || !uniformBuffer.isSync) {
+            if (!ubo.useUbo || !this.isFrozen || !ubo.isSync) {
 
                 // Texture uniforms
                 if (scene.texturesEnabled) {
                     if (this._albedoTexture && MaterialFlags.DiffuseTextureEnabled) {
-                        uniformBuffer.updateFloat2("vAlbedoInfos", this._albedoTexture.coordinatesIndex, this._albedoTexture.level);
-                        MaterialHelper.BindTextureMatrix(this._albedoTexture, uniformBuffer, "albedo");
+                        ubo.updateFloat2("vAlbedoInfos", this._albedoTexture.coordinatesIndex, this._albedoTexture.level);
+                        MaterialHelper.BindTextureMatrix(this._albedoTexture, ubo, "albedo");
                     }
 
                     if (this._ambientTexture && MaterialFlags.AmbientTextureEnabled) {
-                        uniformBuffer.updateFloat4("vAmbientInfos", this._ambientTexture.coordinatesIndex, this._ambientTexture.level, this._ambientTextureStrength, this._ambientTextureImpactOnAnalyticalLights);
-                        MaterialHelper.BindTextureMatrix(this._ambientTexture, uniformBuffer, "ambient");
+                        ubo.updateFloat4("vAmbientInfos", this._ambientTexture.coordinatesIndex, this._ambientTexture.level, this._ambientTextureStrength, this._ambientTextureImpactOnAnalyticalLights);
+                        MaterialHelper.BindTextureMatrix(this._ambientTexture, ubo, "ambient");
                     }
 
                     if (this._opacityTexture && MaterialFlags.OpacityTextureEnabled) {
-                        uniformBuffer.updateFloat2("vOpacityInfos", this._opacityTexture.coordinatesIndex, this._opacityTexture.level);
-                        MaterialHelper.BindTextureMatrix(this._opacityTexture, uniformBuffer, "opacity");
+                        ubo.updateFloat2("vOpacityInfos", this._opacityTexture.coordinatesIndex, this._opacityTexture.level);
+                        MaterialHelper.BindTextureMatrix(this._opacityTexture, ubo, "opacity");
                     }
 
                     if (reflectionTexture && MaterialFlags.ReflectionTextureEnabled) {
-                        uniformBuffer.updateMatrix("reflectionMatrix", reflectionTexture.getReflectionTextureMatrix());
-                        uniformBuffer.updateFloat2("vReflectionInfos", reflectionTexture.level, 0);
+                        ubo.updateMatrix("reflectionMatrix", reflectionTexture.getReflectionTextureMatrix());
+                        ubo.updateFloat2("vReflectionInfos", reflectionTexture.level, 0);
 
                         if ((<any>reflectionTexture).boundingBoxSize) {
                             let cubeTexture = <CubeTexture>reflectionTexture;
 
-                            uniformBuffer.updateVector3("vReflectionPosition", cubeTexture.boundingBoxPosition);
-                            uniformBuffer.updateVector3("vReflectionSize", cubeTexture.boundingBoxSize);
+                            ubo.updateVector3("vReflectionPosition", cubeTexture.boundingBoxPosition);
+                            ubo.updateVector3("vReflectionSize", cubeTexture.boundingBoxSize);
                         }
 
                         var polynomials = reflectionTexture.sphericalPolynomial;
@@ -1683,71 +1684,71 @@ export abstract class PBRBaseMaterial extends PushMaterial {
                             this._activeEffect.setFloat3("vSphericalZX", polynomials.zx.x, polynomials.zx.y, polynomials.zx.z);
                         }
 
-                        uniformBuffer.updateFloat3("vReflectionMicrosurfaceInfos",
+                        ubo.updateFloat3("vReflectionMicrosurfaceInfos",
                             reflectionTexture.getSize().width,
                             reflectionTexture.lodGenerationScale,
                             reflectionTexture.lodGenerationOffset);
                     }
 
                     if (this._emissiveTexture && MaterialFlags.EmissiveTextureEnabled) {
-                        uniformBuffer.updateFloat2("vEmissiveInfos", this._emissiveTexture.coordinatesIndex, this._emissiveTexture.level);
-                        MaterialHelper.BindTextureMatrix(this._emissiveTexture, uniformBuffer, "emissive");
+                        ubo.updateFloat2("vEmissiveInfos", this._emissiveTexture.coordinatesIndex, this._emissiveTexture.level);
+                        MaterialHelper.BindTextureMatrix(this._emissiveTexture, ubo, "emissive");
                     }
 
                     if (this._lightmapTexture && MaterialFlags.LightmapTextureEnabled) {
-                        uniformBuffer.updateFloat2("vLightmapInfos", this._lightmapTexture.coordinatesIndex, this._lightmapTexture.level);
-                        MaterialHelper.BindTextureMatrix(this._lightmapTexture, uniformBuffer, "lightmap");
+                        ubo.updateFloat2("vLightmapInfos", this._lightmapTexture.coordinatesIndex, this._lightmapTexture.level);
+                        MaterialHelper.BindTextureMatrix(this._lightmapTexture, ubo, "lightmap");
                     }
 
                     if (MaterialFlags.SpecularTextureEnabled) {
                         if (this._metallicTexture) {
-                            uniformBuffer.updateFloat3("vReflectivityInfos", this._metallicTexture.coordinatesIndex, this._metallicTexture.level, this._ambientTextureStrength);
-                            MaterialHelper.BindTextureMatrix(this._metallicTexture, uniformBuffer, "reflectivity");
+                            ubo.updateFloat3("vReflectivityInfos", this._metallicTexture.coordinatesIndex, this._metallicTexture.level, this._ambientTextureStrength);
+                            MaterialHelper.BindTextureMatrix(this._metallicTexture, ubo, "reflectivity");
                         }
                         else if (this._reflectivityTexture) {
-                            uniformBuffer.updateFloat3("vReflectivityInfos", this._reflectivityTexture.coordinatesIndex, this._reflectivityTexture.level, 1.0);
-                            MaterialHelper.BindTextureMatrix(this._reflectivityTexture, uniformBuffer, "reflectivity");
+                            ubo.updateFloat3("vReflectivityInfos", this._reflectivityTexture.coordinatesIndex, this._reflectivityTexture.level, 1.0);
+                            MaterialHelper.BindTextureMatrix(this._reflectivityTexture, ubo, "reflectivity");
                         }
 
                         if (this._microSurfaceTexture) {
-                            uniformBuffer.updateFloat2("vMicroSurfaceSamplerInfos", this._microSurfaceTexture.coordinatesIndex, this._microSurfaceTexture.level);
-                            MaterialHelper.BindTextureMatrix(this._microSurfaceTexture, uniformBuffer, "microSurfaceSampler");
+                            ubo.updateFloat2("vMicroSurfaceSamplerInfos", this._microSurfaceTexture.coordinatesIndex, this._microSurfaceTexture.level);
+                            MaterialHelper.BindTextureMatrix(this._microSurfaceTexture, ubo, "microSurfaceSampler");
                         }
                     }
 
                     if (this._bumpTexture && engine.getCaps().standardDerivatives && MaterialFlags.BumpTextureEnabled && !this._disableBumpMap) {
-                        uniformBuffer.updateFloat3("vBumpInfos", this._bumpTexture.coordinatesIndex, this._bumpTexture.level, this._parallaxScaleBias);
-                        MaterialHelper.BindTextureMatrix(this._bumpTexture, uniformBuffer, "bump");
+                        ubo.updateFloat3("vBumpInfos", this._bumpTexture.coordinatesIndex, this._bumpTexture.level, this._parallaxScaleBias);
+                        MaterialHelper.BindTextureMatrix(this._bumpTexture, ubo, "bump");
 
                         if (scene._mirroredCameraPosition) {
-                            uniformBuffer.updateFloat2("vTangentSpaceParams", this._invertNormalMapX ? 1.0 : -1.0, this._invertNormalMapY ? 1.0 : -1.0);
+                            ubo.updateFloat2("vTangentSpaceParams", this._invertNormalMapX ? 1.0 : -1.0, this._invertNormalMapY ? 1.0 : -1.0);
                         } else {
-                            uniformBuffer.updateFloat2("vTangentSpaceParams", this._invertNormalMapX ? -1.0 : 1.0, this._invertNormalMapY ? -1.0 : 1.0);
+                            ubo.updateFloat2("vTangentSpaceParams", this._invertNormalMapX ? -1.0 : 1.0, this._invertNormalMapY ? -1.0 : 1.0);
                         }
                     }
                 }
 
                 // Point size
                 if (this.pointsCloud) {
-                    uniformBuffer.updateFloat("pointSize", this.pointSize);
+                    ubo.updateFloat("pointSize", this.pointSize);
                 }
 
                 // Colors
                 if (defines.METALLICWORKFLOW) {
                     Tmp.Color3[0].r = (this._metallic === undefined || this._metallic === null) ? 1 : this._metallic;
                     Tmp.Color3[0].g = (this._roughness === undefined || this._roughness === null) ? 1 : this._roughness;
-                    uniformBuffer.updateColor4("vReflectivityColor", Tmp.Color3[0], 0);
+                    ubo.updateColor4("vReflectivityColor", Tmp.Color3[0], 0);
                 }
                 else {
-                    uniformBuffer.updateColor4("vReflectivityColor", this._reflectivityColor, this._microSurface);
+                    ubo.updateColor4("vReflectivityColor", this._reflectivityColor, this._microSurface);
                 }
 
-                uniformBuffer.updateColor3("vEmissiveColor", MaterialFlags.EmissiveTextureEnabled ? this._emissiveColor : Color3.BlackReadOnly);
-                uniformBuffer.updateColor3("vReflectionColor", this._reflectionColor);
-                uniformBuffer.updateColor4("vAlbedoColor", this._albedoColor, this.alpha);
+                ubo.updateColor3("vEmissiveColor", MaterialFlags.EmissiveTextureEnabled ? this._emissiveColor : Color3.BlackReadOnly);
+                ubo.updateColor3("vReflectionColor", this._reflectionColor);
+                ubo.updateColor4("vAlbedoColor", this._albedoColor, this.alpha);
 
                 // Visibility
-                uniformBuffer.updateFloat("visibility", mesh.visibility);
+                ubo.updateFloat("visibility", mesh.visibility);
 
                 // Misc
                 this._lightingInfos.x = this._directIntensity;
@@ -1755,68 +1756,68 @@ export abstract class PBRBaseMaterial extends PushMaterial {
                 this._lightingInfos.z = this._environmentIntensity;
                 this._lightingInfos.w = this._specularIntensity;
 
-                uniformBuffer.updateVector4("vLightingIntensity", this._lightingInfos);
+                ubo.updateVector4("vLightingIntensity", this._lightingInfos);
             }
 
             // Textures
             if (scene.texturesEnabled) {
                 if (this._albedoTexture && MaterialFlags.DiffuseTextureEnabled) {
-                    uniformBuffer.setTexture("albedoSampler", this._albedoTexture);
+                    ubo.setTexture("albedoSampler", this._albedoTexture);
                 }
 
                 if (this._ambientTexture && MaterialFlags.AmbientTextureEnabled) {
-                    uniformBuffer.setTexture("ambientSampler", this._ambientTexture);
+                    ubo.setTexture("ambientSampler", this._ambientTexture);
                 }
 
                 if (this._opacityTexture && MaterialFlags.OpacityTextureEnabled) {
-                    uniformBuffer.setTexture("opacitySampler", this._opacityTexture);
+                    ubo.setTexture("opacitySampler", this._opacityTexture);
                 }
 
                 if (reflectionTexture && MaterialFlags.ReflectionTextureEnabled) {
                     if (defines.LODBASEDMICROSFURACE) {
-                        uniformBuffer.setTexture("reflectionSampler", reflectionTexture);
+                        ubo.setTexture("reflectionSampler", reflectionTexture);
                     }
                     else {
-                        uniformBuffer.setTexture("reflectionSampler", reflectionTexture._lodTextureMid || reflectionTexture);
-                        uniformBuffer.setTexture("reflectionSamplerLow", reflectionTexture._lodTextureLow || reflectionTexture);
-                        uniformBuffer.setTexture("reflectionSamplerHigh", reflectionTexture._lodTextureHigh || reflectionTexture);
+                        ubo.setTexture("reflectionSampler", reflectionTexture._lodTextureMid || reflectionTexture);
+                        ubo.setTexture("reflectionSamplerLow", reflectionTexture._lodTextureLow || reflectionTexture);
+                        ubo.setTexture("reflectionSamplerHigh", reflectionTexture._lodTextureHigh || reflectionTexture);
                     }
                 }
 
                 if (defines.ENVIRONMENTBRDF) {
-                    uniformBuffer.setTexture("environmentBrdfSampler", this._environmentBRDFTexture);
+                    ubo.setTexture("environmentBrdfSampler", this._environmentBRDFTexture);
                 }
 
                 if (this._emissiveTexture && MaterialFlags.EmissiveTextureEnabled) {
-                    uniformBuffer.setTexture("emissiveSampler", this._emissiveTexture);
+                    ubo.setTexture("emissiveSampler", this._emissiveTexture);
                 }
 
                 if (this._lightmapTexture && MaterialFlags.LightmapTextureEnabled) {
-                    uniformBuffer.setTexture("lightmapSampler", this._lightmapTexture);
+                    ubo.setTexture("lightmapSampler", this._lightmapTexture);
                 }
 
                 if (MaterialFlags.SpecularTextureEnabled) {
                     if (this._metallicTexture) {
-                        uniformBuffer.setTexture("reflectivitySampler", this._metallicTexture);
+                        ubo.setTexture("reflectivitySampler", this._metallicTexture);
                     }
                     else if (this._reflectivityTexture) {
-                        uniformBuffer.setTexture("reflectivitySampler", this._reflectivityTexture);
+                        ubo.setTexture("reflectivitySampler", this._reflectivityTexture);
                     }
 
                     if (this._microSurfaceTexture) {
-                        uniformBuffer.setTexture("microSurfaceSampler", this._microSurfaceTexture);
+                        ubo.setTexture("microSurfaceSampler", this._microSurfaceTexture);
                     }
                 }
 
                 if (this._bumpTexture && engine.getCaps().standardDerivatives && MaterialFlags.BumpTextureEnabled && !this._disableBumpMap) {
-                    uniformBuffer.setTexture("bumpSampler", this._bumpTexture);
+                    ubo.setTexture("bumpSampler", this._bumpTexture);
                 }
             }
 
-            this.subSurface.bindForSubMesh(uniformBuffer, scene, engine, this.isFrozen, defines.LODBASEDMICROSFURACE);
-            this.clearCoat.bindForSubMesh(uniformBuffer, scene, engine, this._disableBumpMap, this.isFrozen, this._invertNormalMapX, this._invertNormalMapY);
-            this.anisotropy.bindForSubMesh(uniformBuffer, scene, this.isFrozen);
-            this.sheen.bindForSubMesh(uniformBuffer, scene, this.isFrozen);
+            this.subSurface.bindForSubMesh(ubo, scene, engine, this.isFrozen, defines.LODBASEDMICROSFURACE);
+            this.clearCoat.bindForSubMesh(ubo, scene, engine, this._disableBumpMap, this.isFrozen, this._invertNormalMapX, this._invertNormalMapY);
+            this.anisotropy.bindForSubMesh(ubo, scene, this.isFrozen);
+            this.sheen.bindForSubMesh(ubo, scene, this.isFrozen);
 
             // Clip plane
             MaterialHelper.BindClipPlane(this._activeEffect, scene);
@@ -1862,7 +1863,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             MaterialHelper.BindLogDepth(defines, this._activeEffect, scene);
         }
 
-        uniformBuffer.update();
+        ubo.update();
 
         this._afterBind(mesh, this._activeEffect);
     }
@@ -2097,4 +2098,4 @@ export abstract class PBRBaseMaterial extends PushMaterial {
 
         super.dispose(forceDisposeEffect, forceDisposeTextures);
     }
-}
+}

+ 1 - 10
src/Materials/effect.ts

@@ -4,7 +4,6 @@ import { Matrix, Vector3, Vector2, Color3, Color4, Vector4 } from "../Maths/math
 import { Constants } from "../Engines/constants";
 import { DomManagement } from "../Misc/domManagement";
 import { Logger } from "../Misc/logger";
-import { UniformBuffer } from './uniformBuffer';
 import { IDisposable } from 'scene';
 
 declare type Engine = import("../Engines/engine").Engine;
@@ -239,11 +238,6 @@ export class Effect implements IDisposable {
     /** @hidden */
     public _bonesComputationForcedToCPU = false;
 
-    /**
-     * Stores the uniform buffer
-     */
-    public _uniformBuffer: UniformBuffer;
-
     private static _uniqueIdSeed = 0;
     private _engine: Engine;
     private _uniformBuffersNames: { [key: string]: number } = {};
@@ -327,8 +321,6 @@ export class Effect implements IDisposable {
         }
 
         this.uniqueId = Effect._uniqueIdSeed++;
-        
-        this._uniformBuffer = new UniformBuffer(this._engine);
 
         var vertexSource: any;
         var fragmentSource: any;
@@ -1510,9 +1502,8 @@ export class Effect implements IDisposable {
         return this;
     }
 
+    /** Release all associated resources */
     public dispose() {
-        this._uniformBuffer.dispose();
-
         this._engine._releaseEffect(this);
     }
 

+ 9 - 1
src/Materials/material.ts

@@ -522,6 +522,11 @@ export class Material implements IAnimatable {
      */
     private _cachedDepthWriteState: boolean;
 
+    /**
+     * Stores the uniform buffer
+     */
+    protected _uniformBuffer: UniformBuffer;
+
     /** @hidden */
     public _indexInSceneMaterialArray = -1;
 
@@ -547,6 +552,7 @@ export class Material implements IAnimatable {
             this.sideOrientation = Material.CounterClockWiseSideOrientation;
         }
 
+        this._uniformBuffer = new UniformBuffer(this._scene.getEngine());
         this._useUBO = this.getScene().getEngine().supportsUniformBuffers;
 
         if (!doNotAdd) {
@@ -1093,6 +1099,8 @@ export class Material implements IAnimatable {
             }
         }
 
+        this._uniformBuffer.dispose();
+
         // Shader are kept in cache for further use but we can get rid of this by using forceDisposeEffect
         if (forceDisposeEffect && this._effect) {
             if (!this._storeEffectOnSubMeshes) {
@@ -1162,4 +1170,4 @@ export class Material implements IAnimatable {
         var materialType = Tools.Instantiate(parsedMaterial.customType);
         return materialType.Parse(parsedMaterial, scene, rootUrl);
     }
-}
+}

+ 84 - 85
src/Materials/standardMaterial.ts

@@ -14,7 +14,7 @@ import { Mesh } from "../Meshes/mesh";
 import { ImageProcessingConfiguration, IImageProcessingConfigurationDefines } from "./imageProcessingConfiguration";
 import { ColorCurves } from "./colorCurves";
 import { FresnelParameters } from "./fresnelParameters";
-import { EffectFallbacks, EffectCreationOptions, Effect } from "./effect";
+import { EffectFallbacks, EffectCreationOptions } from "./effect";
 import { MaterialDefines } from "../Materials/materialDefines";
 import { PushMaterial } from "./pushMaterial";
 import { MaterialHelper } from "./materialHelper";
@@ -1169,7 +1169,7 @@ export class StandardMaterial extends PushMaterial {
                 } else {
                     scene.resetCachedMaterial();
                     subMesh.setEffect(effect, defines);
-                    this.buildUniformLayout(effect);
+                    this.buildUniformLayout();
                 }
             }
         }
@@ -1188,47 +1188,48 @@ export class StandardMaterial extends PushMaterial {
      * Builds the material UBO layouts.
      * Used internally during the effect preparation.
      */
-    public buildUniformLayout(effect: Effect): void {
+    public buildUniformLayout(): void {
         // Order is important !
-        effect._uniformBuffer.addUniform("diffuseLeftColor", 4);
-        effect._uniformBuffer.addUniform("diffuseRightColor", 4);
-        effect._uniformBuffer.addUniform("opacityParts", 4);
-        effect._uniformBuffer.addUniform("reflectionLeftColor", 4);
-        effect._uniformBuffer.addUniform("reflectionRightColor", 4);
-        effect._uniformBuffer.addUniform("refractionLeftColor", 4);
-        effect._uniformBuffer.addUniform("refractionRightColor", 4);
-        effect._uniformBuffer.addUniform("emissiveLeftColor", 4);
-        effect._uniformBuffer.addUniform("emissiveRightColor", 4);
-
-        effect._uniformBuffer.addUniform("vDiffuseInfos", 2);
-        effect._uniformBuffer.addUniform("vAmbientInfos", 2);
-        effect._uniformBuffer.addUniform("vOpacityInfos", 2);
-        effect._uniformBuffer.addUniform("vReflectionInfos", 2);
-        effect._uniformBuffer.addUniform("vReflectionPosition", 3);
-        effect._uniformBuffer.addUniform("vReflectionSize", 3);
-        effect._uniformBuffer.addUniform("vEmissiveInfos", 2);
-        effect._uniformBuffer.addUniform("vLightmapInfos", 2);
-        effect._uniformBuffer.addUniform("vSpecularInfos", 2);
-        effect._uniformBuffer.addUniform("vBumpInfos", 3);
-
-        effect._uniformBuffer.addUniform("diffuseMatrix", 16);
-        effect._uniformBuffer.addUniform("ambientMatrix", 16);
-        effect._uniformBuffer.addUniform("opacityMatrix", 16);
-        effect._uniformBuffer.addUniform("reflectionMatrix", 16);
-        effect._uniformBuffer.addUniform("emissiveMatrix", 16);
-        effect._uniformBuffer.addUniform("lightmapMatrix", 16);
-        effect._uniformBuffer.addUniform("specularMatrix", 16);
-        effect._uniformBuffer.addUniform("bumpMatrix", 16);
-        effect._uniformBuffer.addUniform("vTangentSpaceParams", 2);
-        effect._uniformBuffer.addUniform("pointSize", 1);
-        effect._uniformBuffer.addUniform("refractionMatrix", 16);
-        effect._uniformBuffer.addUniform("vRefractionInfos", 4);
-        effect._uniformBuffer.addUniform("vSpecularColor", 4);
-        effect._uniformBuffer.addUniform("vEmissiveColor", 3);
-        effect._uniformBuffer.addUniform("visibility", 1);
-        effect._uniformBuffer.addUniform("vDiffuseColor", 4);
-
-        effect._uniformBuffer.create();
+        let ubo = this._uniformBuffer;
+        ubo.addUniform("diffuseLeftColor", 4);
+        ubo.addUniform("diffuseRightColor", 4);
+        ubo.addUniform("opacityParts", 4);
+        ubo.addUniform("reflectionLeftColor", 4);
+        ubo.addUniform("reflectionRightColor", 4);
+        ubo.addUniform("refractionLeftColor", 4);
+        ubo.addUniform("refractionRightColor", 4);
+        ubo.addUniform("emissiveLeftColor", 4);
+        ubo.addUniform("emissiveRightColor", 4);
+
+        ubo.addUniform("vDiffuseInfos", 2);
+        ubo.addUniform("vAmbientInfos", 2);
+        ubo.addUniform("vOpacityInfos", 2);
+        ubo.addUniform("vReflectionInfos", 2);
+        ubo.addUniform("vReflectionPosition", 3);
+        ubo.addUniform("vReflectionSize", 3);
+        ubo.addUniform("vEmissiveInfos", 2);
+        ubo.addUniform("vLightmapInfos", 2);
+        ubo.addUniform("vSpecularInfos", 2);
+        ubo.addUniform("vBumpInfos", 3);
+
+        ubo.addUniform("diffuseMatrix", 16);
+        ubo.addUniform("ambientMatrix", 16);
+        ubo.addUniform("opacityMatrix", 16);
+        ubo.addUniform("reflectionMatrix", 16);
+        ubo.addUniform("emissiveMatrix", 16);
+        ubo.addUniform("lightmapMatrix", 16);
+        ubo.addUniform("specularMatrix", 16);
+        ubo.addUniform("bumpMatrix", 16);
+        ubo.addUniform("vTangentSpaceParams", 2);
+        ubo.addUniform("pointSize", 1);
+        ubo.addUniform("refractionMatrix", 16);
+        ubo.addUniform("vRefractionInfos", 4);
+        ubo.addUniform("vSpecularColor", 4);
+        ubo.addUniform("vEmissiveColor", 3);
+        ubo.addUniform("visibility", 1);
+        ubo.addUniform("vDiffuseColor", 4);
+
+        ubo.create();
     }
 
     /**
@@ -1290,47 +1291,45 @@ export class StandardMaterial extends PushMaterial {
 
         // Bones
         MaterialHelper.BindBonesParameters(mesh, effect);
-
-        let uniformBuffer = effect._uniformBuffer;
-
+        let ubo = this._uniformBuffer;
         if (mustRebind) {
-            uniformBuffer.bindToEffect(effect, "Material");
+            ubo.bindToEffect(effect, "Material");
 
             this.bindViewProjection(effect);
-            if (!uniformBuffer.useUbo || !this.isFrozen || !uniformBuffer.isSync) {
+            if (!ubo.useUbo || !this.isFrozen || !ubo.isSync) {
 
                 if (StandardMaterial.FresnelEnabled && defines.FRESNEL) {
                     // Fresnel
                     if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled) {
-                        uniformBuffer.updateColor4("diffuseLeftColor", this.diffuseFresnelParameters.leftColor, this.diffuseFresnelParameters.power);
-                        uniformBuffer.updateColor4("diffuseRightColor", this.diffuseFresnelParameters.rightColor, this.diffuseFresnelParameters.bias);
+                        ubo.updateColor4("diffuseLeftColor", this.diffuseFresnelParameters.leftColor, this.diffuseFresnelParameters.power);
+                        ubo.updateColor4("diffuseRightColor", this.diffuseFresnelParameters.rightColor, this.diffuseFresnelParameters.bias);
                     }
 
                     if (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled) {
-                        uniformBuffer.updateColor4("opacityParts", new Color3(this.opacityFresnelParameters.leftColor.toLuminance(), this.opacityFresnelParameters.rightColor.toLuminance(), this.opacityFresnelParameters.bias), this.opacityFresnelParameters.power);
+                        ubo.updateColor4("opacityParts", new Color3(this.opacityFresnelParameters.leftColor.toLuminance(), this.opacityFresnelParameters.rightColor.toLuminance(), this.opacityFresnelParameters.bias), this.opacityFresnelParameters.power);
                     }
 
                     if (this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
-                        uniformBuffer.updateColor4("reflectionLeftColor", this.reflectionFresnelParameters.leftColor, this.reflectionFresnelParameters.power);
-                        uniformBuffer.updateColor4("reflectionRightColor", this.reflectionFresnelParameters.rightColor, this.reflectionFresnelParameters.bias);
+                        ubo.updateColor4("reflectionLeftColor", this.reflectionFresnelParameters.leftColor, this.reflectionFresnelParameters.power);
+                        ubo.updateColor4("reflectionRightColor", this.reflectionFresnelParameters.rightColor, this.reflectionFresnelParameters.bias);
                     }
 
                     if (this.refractionFresnelParameters && this.refractionFresnelParameters.isEnabled) {
-                        uniformBuffer.updateColor4("refractionLeftColor", this.refractionFresnelParameters.leftColor, this.refractionFresnelParameters.power);
-                        uniformBuffer.updateColor4("refractionRightColor", this.refractionFresnelParameters.rightColor, this.refractionFresnelParameters.bias);
+                        ubo.updateColor4("refractionLeftColor", this.refractionFresnelParameters.leftColor, this.refractionFresnelParameters.power);
+                        ubo.updateColor4("refractionRightColor", this.refractionFresnelParameters.rightColor, this.refractionFresnelParameters.bias);
                     }
 
                     if (this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) {
-                        uniformBuffer.updateColor4("emissiveLeftColor", this.emissiveFresnelParameters.leftColor, this.emissiveFresnelParameters.power);
-                        uniformBuffer.updateColor4("emissiveRightColor", this.emissiveFresnelParameters.rightColor, this.emissiveFresnelParameters.bias);
+                        ubo.updateColor4("emissiveLeftColor", this.emissiveFresnelParameters.leftColor, this.emissiveFresnelParameters.power);
+                        ubo.updateColor4("emissiveRightColor", this.emissiveFresnelParameters.rightColor, this.emissiveFresnelParameters.bias);
                     }
                 }
 
                 // Textures
                 if (scene.texturesEnabled) {
                     if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
-                        uniformBuffer.updateFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
-                        MaterialHelper.BindTextureMatrix(this._diffuseTexture, uniformBuffer, "diffuse");
+                        ubo.updateFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
+                        MaterialHelper.BindTextureMatrix(this._diffuseTexture, ubo, "diffuse");
 
                         if (this._diffuseTexture.hasAlpha) {
                             effect.setFloat("alphaCutOff", this.alphaCutOff);
@@ -1338,81 +1337,81 @@ export class StandardMaterial extends PushMaterial {
                     }
 
                     if (this._ambientTexture && StandardMaterial.AmbientTextureEnabled) {
-                        uniformBuffer.updateFloat2("vAmbientInfos", this._ambientTexture.coordinatesIndex, this._ambientTexture.level);
-                        MaterialHelper.BindTextureMatrix(this._ambientTexture, uniformBuffer, "ambient");
+                        ubo.updateFloat2("vAmbientInfos", this._ambientTexture.coordinatesIndex, this._ambientTexture.level);
+                        MaterialHelper.BindTextureMatrix(this._ambientTexture, ubo, "ambient");
                     }
 
                     if (this._opacityTexture && StandardMaterial.OpacityTextureEnabled) {
-                        uniformBuffer.updateFloat2("vOpacityInfos", this._opacityTexture.coordinatesIndex, this._opacityTexture.level);
-                        MaterialHelper.BindTextureMatrix(this._opacityTexture, uniformBuffer, "opacity");
+                        ubo.updateFloat2("vOpacityInfos", this._opacityTexture.coordinatesIndex, this._opacityTexture.level);
+                        MaterialHelper.BindTextureMatrix(this._opacityTexture, ubo, "opacity");
                     }
 
                     if (this._reflectionTexture && StandardMaterial.ReflectionTextureEnabled) {
-                        uniformBuffer.updateFloat2("vReflectionInfos", this._reflectionTexture.level, this.roughness);
-                        uniformBuffer.updateMatrix("reflectionMatrix", this._reflectionTexture.getReflectionTextureMatrix());
+                        ubo.updateFloat2("vReflectionInfos", this._reflectionTexture.level, this.roughness);
+                        ubo.updateMatrix("reflectionMatrix", this._reflectionTexture.getReflectionTextureMatrix());
 
                         if ((<any>this._reflectionTexture).boundingBoxSize) {
                             let cubeTexture = <CubeTexture>this._reflectionTexture;
 
-                            uniformBuffer.updateVector3("vReflectionPosition", cubeTexture.boundingBoxPosition);
-                            uniformBuffer.updateVector3("vReflectionSize", cubeTexture.boundingBoxSize);
+                            ubo.updateVector3("vReflectionPosition", cubeTexture.boundingBoxPosition);
+                            ubo.updateVector3("vReflectionSize", cubeTexture.boundingBoxSize);
                         }
                     }
 
                     if (this._emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {
-                        uniformBuffer.updateFloat2("vEmissiveInfos", this._emissiveTexture.coordinatesIndex, this._emissiveTexture.level);
-                        MaterialHelper.BindTextureMatrix(this._emissiveTexture, uniformBuffer, "emissive");
+                        ubo.updateFloat2("vEmissiveInfos", this._emissiveTexture.coordinatesIndex, this._emissiveTexture.level);
+                        MaterialHelper.BindTextureMatrix(this._emissiveTexture, ubo, "emissive");
                     }
 
                     if (this._lightmapTexture && StandardMaterial.LightmapTextureEnabled) {
-                        uniformBuffer.updateFloat2("vLightmapInfos", this._lightmapTexture.coordinatesIndex, this._lightmapTexture.level);
-                        MaterialHelper.BindTextureMatrix(this._lightmapTexture, uniformBuffer, "lightmap");
+                        ubo.updateFloat2("vLightmapInfos", this._lightmapTexture.coordinatesIndex, this._lightmapTexture.level);
+                        MaterialHelper.BindTextureMatrix(this._lightmapTexture, ubo, "lightmap");
                     }
 
                     if (this._specularTexture && StandardMaterial.SpecularTextureEnabled) {
-                        uniformBuffer.updateFloat2("vSpecularInfos", this._specularTexture.coordinatesIndex, this._specularTexture.level);
-                        MaterialHelper.BindTextureMatrix(this._specularTexture, uniformBuffer, "specular");
+                        ubo.updateFloat2("vSpecularInfos", this._specularTexture.coordinatesIndex, this._specularTexture.level);
+                        MaterialHelper.BindTextureMatrix(this._specularTexture, ubo, "specular");
                     }
 
                     if (this._bumpTexture && scene.getEngine().getCaps().standardDerivatives && StandardMaterial.BumpTextureEnabled) {
-                        uniformBuffer.updateFloat3("vBumpInfos", this._bumpTexture.coordinatesIndex, 1.0 / this._bumpTexture.level, this.parallaxScaleBias);
-                        MaterialHelper.BindTextureMatrix(this._bumpTexture, uniformBuffer, "bump");
+                        ubo.updateFloat3("vBumpInfos", this._bumpTexture.coordinatesIndex, 1.0 / this._bumpTexture.level, this.parallaxScaleBias);
+                        MaterialHelper.BindTextureMatrix(this._bumpTexture, ubo, "bump");
 
                         if (scene._mirroredCameraPosition) {
-                            uniformBuffer.updateFloat2("vTangentSpaceParams", this._invertNormalMapX ? 1.0 : -1.0, this._invertNormalMapY ? 1.0 : -1.0);
+                            ubo.updateFloat2("vTangentSpaceParams", this._invertNormalMapX ? 1.0 : -1.0, this._invertNormalMapY ? 1.0 : -1.0);
                         } else {
-                            uniformBuffer.updateFloat2("vTangentSpaceParams", this._invertNormalMapX ? -1.0 : 1.0, this._invertNormalMapY ? -1.0 : 1.0);
+                            ubo.updateFloat2("vTangentSpaceParams", this._invertNormalMapX ? -1.0 : 1.0, this._invertNormalMapY ? -1.0 : 1.0);
                         }
                     }
 
                     if (this._refractionTexture && StandardMaterial.RefractionTextureEnabled) {
                         var depth = 1.0;
                         if (!this._refractionTexture.isCube) {
-                            uniformBuffer.updateMatrix("refractionMatrix", this._refractionTexture.getReflectionTextureMatrix());
+                            ubo.updateMatrix("refractionMatrix", this._refractionTexture.getReflectionTextureMatrix());
 
                             if ((<any>this._refractionTexture).depth) {
                                 depth = (<any>this._refractionTexture).depth;
                             }
                         }
-                        uniformBuffer.updateFloat4("vRefractionInfos", this._refractionTexture.level, this.indexOfRefraction, depth, this.invertRefractionY ? -1 : 1);
+                        ubo.updateFloat4("vRefractionInfos", this._refractionTexture.level, this.indexOfRefraction, depth, this.invertRefractionY ? -1 : 1);
                     }
                 }
 
                 // Point size
                 if (this.pointsCloud) {
-                    uniformBuffer.updateFloat("pointSize", this.pointSize);
+                    ubo.updateFloat("pointSize", this.pointSize);
                 }
 
                 if (defines.SPECULARTERM) {
-                    uniformBuffer.updateColor4("vSpecularColor", this.specularColor, this.specularPower);
+                    ubo.updateColor4("vSpecularColor", this.specularColor, this.specularPower);
                 }
-                uniformBuffer.updateColor3("vEmissiveColor", StandardMaterial.EmissiveTextureEnabled ? this.emissiveColor : Color3.BlackReadOnly);
+                ubo.updateColor3("vEmissiveColor", StandardMaterial.EmissiveTextureEnabled ? this.emissiveColor : Color3.BlackReadOnly);
 
                 // Visibility
-                uniformBuffer.updateFloat("visibility", mesh.visibility);
+                ubo.updateFloat("visibility", mesh.visibility);
 
                 // Diffuse
-                uniformBuffer.updateColor4("vDiffuseColor", this.diffuseColor, this.alpha);
+                ubo.updateColor4("vDiffuseColor", this.diffuseColor, this.alpha);
             }
 
             // Textures
@@ -1501,7 +1500,7 @@ export class StandardMaterial extends PushMaterial {
             }
         }
 
-        uniformBuffer.update();
+        ubo.update();
         this._afterBind(mesh, this._activeEffect);
     }
 
@@ -1846,4 +1845,4 @@ _TypeStore.RegisteredTypes["BABYLON.StandardMaterial"] = StandardMaterial;
 
 Scene.DefaultMaterialFactory = (scene: Scene) => {
     return new StandardMaterial("default material", scene);
-};
+};

+ 29 - 18
src/Meshes/mesh.ts

@@ -82,8 +82,9 @@ class _InstanceDataStorage {
     public instancesData: Float32Array;
     public overridenInstanceCount: number;
     public isFrozen: boolean;
-    public _previousBatch: _InstancesBatch;
+    public previousBatch: _InstancesBatch;
     public hardwareInstancedRendering: boolean;
+    public sideOrientation: number;
 }
 
 /**
@@ -1367,8 +1368,8 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
 
     /** @hidden */
     public _getInstancesRenderList(subMeshId: number): _InstancesBatch {
-        if (this._instanceDataStorage.isFrozen && this._instanceDataStorage._previousBatch) {
-            return this._instanceDataStorage._previousBatch;
+        if (this._instanceDataStorage.isFrozen && this._instanceDataStorage.previousBatch) {
+            return this._instanceDataStorage.previousBatch;
         }
         var scene = this.getScene();
         let batchCache = this._instanceDataStorage.batchCache;
@@ -1387,7 +1388,7 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
             }
         }
         batchCache.hardwareInstancedRendering[subMeshId] = this._instanceDataStorage.hardwareInstancedRendering && (batchCache.visibleInstances[subMeshId] !== null) && (batchCache.visibleInstances[subMeshId] !== undefined);
-        this._instanceDataStorage._previousBatch = batchCache;
+        this._instanceDataStorage.previousBatch = batchCache;
         return batchCache;
     }
 
@@ -1544,22 +1545,25 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
 
         var engine = scene.getEngine();
         var hardwareInstancedRendering = batch.hardwareInstancedRendering[subMesh._id];
+        let instanceDataStorage = this._instanceDataStorage;
 
         // Material
-        let material = subMesh.getMaterial();
+        if (!instanceDataStorage.isFrozen ||!this._effectiveMaterial) {
+            let material = subMesh.getMaterial();
 
-        if (!material) {
-            return this;
-        }
+            if (!material) {
+                return this;
+            }
 
-        this._effectiveMaterial = material;
+            this._effectiveMaterial = material;
 
-        if (this._effectiveMaterial._storeEffectOnSubMeshes) {
-            if (!this._effectiveMaterial.isReadyForSubMesh(this, subMesh, hardwareInstancedRendering)) {
+            if (this._effectiveMaterial._storeEffectOnSubMeshes) {
+                if (!this._effectiveMaterial.isReadyForSubMesh(this, subMesh, hardwareInstancedRendering)) {
+                    return this;
+                }
+            } else if (!this._effectiveMaterial.isReady(this, hardwareInstancedRendering)) {
                 return this;
             }
-        } else if (!this._effectiveMaterial.isReady(this, hardwareInstancedRendering)) {
-            return this;
         }
 
         // Alpha mode
@@ -1584,12 +1588,19 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
 
         const effectiveMesh = this._effectiveMesh;
 
-        var sideOrientation = this.overrideMaterialSideOrientation;
-        if (sideOrientation == null) {
-            sideOrientation = this._effectiveMaterial.sideOrientation;
-            if (effectiveMesh._getWorldMatrixDeterminant() < 0) {
-                sideOrientation = (sideOrientation === Material.ClockWiseSideOrientation ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation);
+        var sideOrientation: Nullable<number>;
+        
+        if (!instanceDataStorage.isFrozen) {
+            sideOrientation = this.overrideMaterialSideOrientation;
+            if (sideOrientation == null) {
+                sideOrientation = this._effectiveMaterial.sideOrientation;
+                if (effectiveMesh._getWorldMatrixDeterminant() < 0) {
+                    sideOrientation = (sideOrientation === Material.ClockWiseSideOrientation ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation);
+                }
             }
+            instanceDataStorage.sideOrientation = sideOrientation!;
+        } else {
+            sideOrientation = instanceDataStorage.sideOrientation;
         }
 
         var reverse = this._effectiveMaterial._preBind(effect, sideOrientation);

+ 25 - 20
src/Meshes/transformNode.ts

@@ -302,11 +302,13 @@ export class TransformNode extends Node {
 
     /** @hidden */
     public _isSynchronized(): boolean {
-        if (this.billboardMode !== this._cache.billboardMode || this.billboardMode !== TransformNode.BILLBOARDMODE_NONE) {
+        let cache = this._cache;
+
+        if (this.billboardMode !== cache.billboardMode || this.billboardMode !== TransformNode.BILLBOARDMODE_NONE) {
             return false;
         }
 
-        if (this._cache.pivotMatrixUpdated) {
+        if (cache.pivotMatrixUpdated) {
             return false;
         }
 
@@ -314,19 +316,19 @@ export class TransformNode extends Node {
             return false;
         }
 
-        if (!this._cache.position.equals(this._position)) {
+        if (!cache.position.equals(this._position)) {
             return false;
         }
 
         if (this._rotationQuaternion) {
-            if (!this._cache.rotationQuaternion.equals(this._rotationQuaternion)) {
+            if (!cache.rotationQuaternion.equals(this._rotationQuaternion)) {
                 return false;
             }
-        } else if (!this._cache.rotation.equals(this._rotation)) {
+        } else if (!cache.rotation.equals(this._rotation)) {
             return false;
         }
 
-        if (!this._cache.scaling.equals(this._scaling)) {
+        if (!cache.scaling.equals(this._scaling)) {
             return false;
         }
 
@@ -337,13 +339,14 @@ export class TransformNode extends Node {
     public _initCache() {
         super._initCache();
 
-        this._cache.localMatrixUpdated = false;
-        this._cache.position = Vector3.Zero();
-        this._cache.scaling = Vector3.Zero();
-        this._cache.rotation = Vector3.Zero();
-        this._cache.rotationQuaternion = new Quaternion(0, 0, 0, 0);
-        this._cache.billboardMode = -1;
-        this._cache.infiniteDistance = false;
+        let cache = this._cache;
+        cache.localMatrixUpdated = false;
+        cache.position = Vector3.Zero();
+        cache.scaling = Vector3.Zero();
+        cache.rotation = Vector3.Zero();
+        cache.rotationQuaternion = new Quaternion(0, 0, 0, 0);
+        cache.billboardMode = -1;
+        cache.infiniteDistance = false;
     }
 
     /**
@@ -387,6 +390,7 @@ export class TransformNode extends Node {
         } else {
             this._activeCompositionProcessor = this._pivotCompositionProcessor;
         }
+        
         this._cache.pivotMatrixUpdated = true;
         this._postMultiplyPivotMatrix = postMultiplyPivotMatrix;
 
@@ -1056,9 +1060,10 @@ export class TransformNode extends Node {
         }
 
         this._updateCache();
-        this._cache.pivotMatrixUpdated = false;
-        this._cache.billboardMode = this.billboardMode;
-        this._cache.infiniteDistance = this.infiniteDistance;
+        let cache = this._cache;
+        cache.pivotMatrixUpdated = false;
+        cache.billboardMode = this.billboardMode;
+        cache.infiniteDistance = this.infiniteDistance;
 
         this._currentRenderId = currentRenderId;
         this._childUpdateId++;
@@ -1066,8 +1071,8 @@ export class TransformNode extends Node {
         let parent = this._getEffectiveParent();
 
         // Scaling
-        let scaling: Vector3 = this._cache.scaling;
-        let translation: Vector3 = this._cache.position;
+        let scaling: Vector3 = cache.scaling;
+        let translation: Vector3 = cache.position;
 
         // Translation
         this._translationProcessor(translation);
@@ -1076,7 +1081,7 @@ export class TransformNode extends Node {
         scaling.copyFromFloats(this._scaling.x * this.scalingDeterminant, this._scaling.y * this.scalingDeterminant, this._scaling.z * this.scalingDeterminant);
 
         // Rotation
-        let rotation: Quaternion = this._cache.rotationQuaternion;
+        let rotation: Quaternion = cache.rotationQuaternion;
         if (this._rotationQuaternion) {
             if (this.reIntegrateRotationIntoRotationQuaternion) {
                 var len = this.rotation.lengthSquared();
@@ -1088,7 +1093,7 @@ export class TransformNode extends Node {
             rotation.copyFrom(this._rotationQuaternion);
         } else {
             Quaternion.RotationYawPitchRollToRef(this._rotation.y, this._rotation.x, this._rotation.z, rotation);
-            this._cache.rotation.copyFrom(this._rotation);
+            cache.rotation.copyFrom(this._rotation);
         }
 
         // Compose