Przeglądaj źródła

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

Conflicts:
	Babylon/PostProcess/RenderPipeline/babylon.postProcessRenderEffect.js
	Babylon/PostProcess/RenderPipeline/babylon.postProcessRenderPass.js
	Babylon/PostProcess/RenderPipeline/babylon.postProcessRenderPipeline.js
	Babylon/PostProcess/RenderPipeline/babylon.postProcessRenderPipelineManager.js
michael-korbas 11 lat temu
rodzic
commit
5912875f20

+ 4 - 1
Babylon/Cameras/babylon.camera.js

@@ -289,6 +289,7 @@ var BABYLON = BABYLON || {};
 
         this._computedViewMatrix.invert();
 
+        this._currentRenderId = this._scene.getRenderId();
         return this._computedViewMatrix;
     };
     
@@ -297,8 +298,10 @@ var BABYLON = BABYLON || {};
             return this._computedViewMatrix;
         }
 
-        this._currentRenderId = this._scene.getRenderId();
         this._computedViewMatrix = this._getViewMatrix();
+        if (!this.parent || !this.parent.getWorldMatrix) {
+            this._currentRenderId = this._scene.getRenderId();
+        }
         return this._computedViewMatrix;
     };
 

+ 21 - 7
Babylon/Materials/babylon.effect.js

@@ -4,7 +4,7 @@ var BABYLON = BABYLON || {};
 
 (function () {
 
-    BABYLON.Effect = function (baseName, attributesNames, uniformsNames, samplers, engine, defines, optionalDefines) {
+    BABYLON.Effect = function (baseName, attributesNames, uniformsNames, samplers, engine, defines, optionalDefines, onCompiled, onError) {
         this._engine = engine;
         this.name = baseName;
         this.defines = defines;
@@ -14,6 +14,9 @@ var BABYLON = BABYLON || {};
         this._compilationError = "";
         this._attributesNames = attributesNames;
 
+        this.onError = onError;
+        this.onCompiled = onCompiled;
+
         var vertexSource;
         var fragmentSource;
 
@@ -30,12 +33,16 @@ var BABYLON = BABYLON || {};
             that._loadFragmentShader(fragmentSource, function (fragmentCode) {
                 that._prepareEffect(vertexCode, fragmentCode, attributesNames, defines, optionalDefines);
             });
-        });   
+        });
 
         // Cache
         this._valueCache = [];
     };
 
+    // Events
+    BABYLON.Effect.prototype.onCompiled = null;
+    BABYLON.Effect.prototype.onError = null;
+
     // Properties
     BABYLON.Effect.prototype.isReady = function () {
         return this._isReady;
@@ -87,7 +94,7 @@ var BABYLON = BABYLON || {};
             callback(BABYLON.Effect.ShadersStore[vertex + "VertexShader"]);
             return;
         }
-        
+
         var vertexShaderUrl;
 
         if (vertex[0] === ".") {
@@ -113,7 +120,7 @@ var BABYLON = BABYLON || {};
             callback(BABYLON.Effect.ShadersStore[fragment + "PixelShader"]);
             return;
         }
-        
+
         var fragmentShaderUrl;
 
         if (fragment[0] === ".") {
@@ -146,6 +153,9 @@ var BABYLON = BABYLON || {};
             engine.bindSamplers(this);
 
             this._isReady = true;
+            if (this.onCompiled) {
+                this.onCompiled(this);
+            }
         } catch (e) {
             if (!useFallback && optionalDefines) {
                 for (var index = 0; index < optionalDefines.length; index++) {
@@ -157,6 +167,10 @@ var BABYLON = BABYLON || {};
                 console.error("Defines: " + defines);
                 console.error("Optional defines: " + optionalDefines);
                 this._compilationError = e.message;
+
+                if (this.onError) {
+                    this.onError(this, this._compilationError);
+                }
             }
         }
     };
@@ -215,7 +229,7 @@ var BABYLON = BABYLON || {};
         this._valueCache[uniformName][2] = z;
         this._valueCache[uniformName][3] = w;
     };
-    
+
     BABYLON.Effect.prototype.setArray = function (uniformName, array) {
         this._engine.setArray(this.getUniform(uniformName), array);
 
@@ -259,7 +273,7 @@ var BABYLON = BABYLON || {};
 
         return this;
     };
-    
+
     BABYLON.Effect.prototype.setVector2 = function (uniformName, vector2) {
         if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == vector2.x && this._valueCache[uniformName][1] == vector2.y)
             return this;
@@ -279,7 +293,7 @@ var BABYLON = BABYLON || {};
 
         return this;
     };
-    
+
     BABYLON.Effect.prototype.setVector3 = function (uniformName, vector3) {
         if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == vector3.x && this._valueCache[uniformName][1] == vector3.y && this._valueCache[uniformName][2] == vector3.z)
             return this;

+ 16 - 4
Babylon/Materials/babylon.material.js

@@ -20,8 +20,11 @@ var BABYLON = BABYLON || {};
     BABYLON.Material.prototype._effect = null;
     BABYLON.Material.prototype._wasPreviouslyReady = false;
 
+    // Events
+    BABYLON.Effect.prototype.onCompiled = null;
+    BABYLON.Effect.prototype.onError = null;
     BABYLON.Material.prototype.onDispose = null;
-    
+
     // Properties
     BABYLON.Material.prototype.isReady = function (mesh) {
         return true;
@@ -40,6 +43,9 @@ var BABYLON = BABYLON || {};
     };
 
     // Methods   
+    BABYLON.Material.prototype.trackCreation = function (onCompiled, onError) {
+    };
+
     BABYLON.Material.prototype._preBind = function () {
         var engine = this._scene.getEngine();
         
@@ -53,18 +59,24 @@ var BABYLON = BABYLON || {};
     BABYLON.Material.prototype.unbind = function () {
     };
     
-    BABYLON.Material.prototype.baseDispose = function () {
+    BABYLON.Material.prototype.baseDispose = function (forceDisposeEffect) {
         // Remove from scene
         var index = this._scene.materials.indexOf(this);
         this._scene.materials.splice(index, 1);
 
+        // Shader are kept in cache for further use but we can get rid of this by using forceDisposeEffect
+        if (forceDisposeEffect && this._effect) {
+            this._scene.getEngine()._releaseEffect(this._effect);
+            this._effect = null;
+        }
+
         // Callback
         if (this.onDispose) {
             this.onDispose();
         }
     };
 
-    BABYLON.Material.prototype.dispose = function () {
-        this.baseDispose();
+    BABYLON.Material.prototype.dispose = function (forceDisposeEffect) {
+        this.baseDispose(forceDisposeEffect);
     };
 })();

+ 14 - 5
Babylon/Materials/babylon.shaderMaterial.js

@@ -27,6 +27,8 @@ var BABYLON = BABYLON || {};
         this._vectors3 = [];
         this._vectors4 = [];
         this._matrices = [];
+
+        this._cachedWorldViewMatrix = new BABYLON.Matrix();
     };
 
     BABYLON.ShaderMaterial.prototype = Object.create(BABYLON.Material.prototype);
@@ -48,7 +50,9 @@ var BABYLON = BABYLON || {};
     };
 
     BABYLON.ShaderMaterial.prototype.setTexture = function (name, texture) {
-        this._checkUniform(name);
+        if (this._options.samplers.indexOf(name) === -1) {
+            this._options.samplers.push(name);
+        }
         this._textures[name] = texture;
 
         return this;
@@ -116,8 +120,8 @@ var BABYLON = BABYLON || {};
         this._effect = engine.createEffect(this._shaderPath,
             this._options.attributes,
             this._options.uniforms,
-            this._options.samplers,
-            "");
+            this._options.samplers,            
+            "", null, this.onCompiled, this.onError);
 
         if (!this._effect.isReady()) {
             return false;
@@ -136,6 +140,11 @@ var BABYLON = BABYLON || {};
             this._effect.setMatrix("view", this._scene.getViewMatrix());
         }
 
+        if (this._options.uniforms.indexOf("worldView") !== -1) {
+            world.multiplyToRef(this._scene.getViewMatrix(), this._cachedWorldViewMatrix);
+            this._effect.setMatrix("worldView", this._cachedWorldViewMatrix);
+        }
+
         if (this._options.uniforms.indexOf("projection") !== -1) {
             this._effect.setMatrix("projection", this._scene.getProjectionMatrix());
         }
@@ -190,13 +199,13 @@ var BABYLON = BABYLON || {};
         }
     };
 
-    BABYLON.ShaderMaterial.prototype.dispose = function () {
+    BABYLON.ShaderMaterial.prototype.dispose = function (forceDisposeEffect) {
         for (var name in this._textures) {
             this._textures[name].dispose();
         }
 
         this._textures = [];
         
-        this.baseDispose();
+        this.baseDispose(forceDisposeEffect);
     };
 })();

+ 3 - 3
Babylon/Materials/babylon.standardMaterial.js

@@ -250,7 +250,7 @@ var BABYLON = BABYLON || {};
                 ["diffuseSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "specularSampler", "bumpSampler",
                  "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
                 ],
-                join, optionalDefines);
+                join, optionalDefines, this.onCompiled, this.onError);
         }
         if (!this._effect.isReady()) {
             return false;
@@ -452,7 +452,7 @@ var BABYLON = BABYLON || {};
         return results;
     };
 
-    BABYLON.StandardMaterial.prototype.dispose = function () {
+    BABYLON.StandardMaterial.prototype.dispose = function (forceDisposeEffect) {
         if (this.diffuseTexture) {
             this.diffuseTexture.dispose();
         }
@@ -481,7 +481,7 @@ var BABYLON = BABYLON || {};
             this.bumpTexture.dispose();
         }
 
-        this.baseDispose();
+        this.baseDispose(forceDisposeEffect);
     };
 
     BABYLON.StandardMaterial.prototype.clone = function (name) {

+ 4 - 3
Babylon/Materials/textures/babylon.renderTargetTexture.js

@@ -86,12 +86,13 @@ var BABYLON = BABYLON || {};
         // Render
         this._renderingManager.render(this.customRenderFunction, this.renderList, this.renderParticles, this.renderSprites);
 
-        // Unbind
-        engine.unBindFramebuffer(this._texture);
-
+        //Call this before unBinding Framebuffer in case of manipulating texture with WebGL commands inside the onAfterRender method.
         if (this.onAfterRender) {
             this.onAfterRender();
         }
+
+        // Unbind
+        engine.unBindFramebuffer(this._texture);
     };
 
     BABYLON.RenderTargetTexture.prototype.clone = function () {

+ 30 - 53
Babylon/Mesh/babylon.mesh.js

@@ -324,7 +324,7 @@ var BABYLON = BABYLON || {};
     };
 
     BABYLON.Mesh.prototype.computeWorldMatrix = function (force) {
-        if (!force && this.isSynchronized(true)) {
+        if (!force && (this._currentRenderId == this._scene.getRenderId() || this.isSynchronized(true))) {
             return this._worldMatrix;
         }
 
@@ -449,6 +449,8 @@ var BABYLON = BABYLON || {};
         this._vertexBuffers[kind] = new BABYLON.VertexBuffer(this, data, kind, updatable);
 
         if (kind === BABYLON.VertexBuffer.PositionKind) {
+            this._resetPointsArrayCache();
+
             var stride = this._vertexBuffers[kind].getStrideSize();
             this._totalVertices = data.length / stride;
 
@@ -459,9 +461,21 @@ var BABYLON = BABYLON || {};
         }
     };
 
-    BABYLON.Mesh.prototype.updateVerticesData = function (kind, data) {
+    BABYLON.Mesh.prototype.updateVerticesData = function (kind, data, updateExtends) {
         if (this._vertexBuffers[kind]) {
             this._vertexBuffers[kind].update(data);
+
+            if (kind === BABYLON.VertexBuffer.PositionKind) {
+                this._resetPointsArrayCache();
+
+                if (updateExtends) {
+                    var stride = this._vertexBuffers[kind].getStrideSize();
+                    this._totalVertices = data.length / stride;
+
+                    var extend = BABYLON.Tools.ExtractMinAndMax(data, 0, this._totalVertices);
+                    this._boundingInfo = new BABYLON.BoundingInfo(extend.minimum, extend.maximum);
+                }
+            }
         }
     };
 
@@ -1117,7 +1131,7 @@ var BABYLON = BABYLON || {};
 
     // Cylinder and cone (Code inspired by SharpDX.org)
     BABYLON.Mesh.CreateCylinder = function (name, height, diameterTop, diameterBottom, tessellation, scene, updatable) {
-        var cylinder = new BABYLON.Mesh(name, scene);        
+        var cylinder = new BABYLON.Mesh(name, scene);
         var vertexData = BABYLON.VertexData.CreateCylinder(height, diameterTop, diameterBottom, tessellation);
 
         vertexData.applyToMesh(cylinder, updatable);
@@ -1135,6 +1149,15 @@ var BABYLON = BABYLON || {};
         return torus;
     };
 
+    BABYLON.Mesh.CreateTorusKnot = function (name, radius, tube, radialSegments, tubularSegments, p, q, scene, updatable) {
+        var torusKnot = new BABYLON.Mesh(name, scene);
+        var vertexData = BABYLON.VertexData.CreateTorusKnot(radius, tube, radialSegments, tubularSegments, p, q);
+
+        vertexData.applyToMesh(torusKnot, updatable);
+
+        return torusKnot;
+    };
+
     // Plane & ground
     BABYLON.Mesh.CreatePlane = function (name, size, scene, updatable) {
         var plane = new BABYLON.Mesh(name, scene);
@@ -1215,7 +1238,7 @@ var BABYLON = BABYLON || {};
             }
 
             // Normals
-            BABYLON.Mesh.ComputeNormal(positions, normals, indices);
+            BABYLON.VertexData.ComputeNormal(positions, indices, normals);
 
             // Transfer
             ground.setVerticesData(positions, BABYLON.VertexBuffer.PositionKind, updatable);
@@ -1234,56 +1257,10 @@ var BABYLON = BABYLON || {};
     };
 
     // Tools
-    BABYLON.Mesh.ComputeNormal = function (positions, normals, indices) {
-        var positionVectors = [];
-        var facesOfVertices = [];
-        var index;
-
-        for (index = 0; index < positions.length; index += 3) {
-            var vector3 = new BABYLON.Vector3(positions[index], positions[index + 1], positions[index + 2]);
-            positionVectors.push(vector3);
-            facesOfVertices.push([]);
-        }
-        // Compute normals
-        var facesNormals = [];
-        for (index = 0; index < indices.length / 3; index++) {
-            var i1 = indices[index * 3];
-            var i2 = indices[index * 3 + 1];
-            var i3 = indices[index * 3 + 2];
-
-            var p1 = positionVectors[i1];
-            var p2 = positionVectors[i2];
-            var p3 = positionVectors[i3];
-
-            var p1p2 = p1.subtract(p2);
-            var p3p2 = p3.subtract(p2);
-
-            facesNormals[index] = BABYLON.Vector3.Normalize(BABYLON.Vector3.Cross(p1p2, p3p2));
-            facesOfVertices[i1].push(index);
-            facesOfVertices[i2].push(index);
-            facesOfVertices[i3].push(index);
-        }
-
-        for (index = 0; index < positionVectors.length; index++) {
-            var faces = facesOfVertices[index];
-
-            var normal = BABYLON.Vector3.Zero();
-            for (var faceIndex = 0; faceIndex < faces.length; faceIndex++) {
-                normal.addInPlace(facesNormals[faces[faceIndex]]);
-            }
-
-            normal = BABYLON.Vector3.Normalize(normal.scale(1.0 / faces.length));
-
-            normals[index * 3] = normal.x;
-            normals[index * 3 + 1] = normal.y;
-            normals[index * 3 + 2] = normal.z;
-        }
-    };
-
-    BABYLON.Mesh.MinMax = function(meshes) {
+    BABYLON.Mesh.MinMax = function (meshes) {
         var minVector;
         var maxVector;
-        for(var i in meshes) {
+        for (var i in meshes) {
             var mesh = meshes[i];
             var boundingBox = mesh.getBoundingInfo().boundingBox;
             if (!minVector) {
@@ -1301,7 +1278,7 @@ var BABYLON = BABYLON || {};
         };
     };
 
-    BABYLON.Mesh.Center = function(meshesOrMinMaxVector) {
+    BABYLON.Mesh.Center = function (meshesOrMinMaxVector) {
         var minMaxVector = meshesOrMinMaxVector.min !== undefined ? meshesOrMinMaxVector : BABYLON.Mesh.MinMax(meshesOrMinMaxVector);
         return BABYLON.Vector3.Center(minMaxVector.min, minMaxVector.max);
     };

+ 158 - 2
Babylon/Mesh/babylon.mesh.vertexData.js

@@ -7,7 +7,7 @@ var BABYLON = BABYLON || {};
     };
 
     // Methods
-    BABYLON.VertexData.prototype.applyToMesh = function(mesh, updatable) {
+    BABYLON.VertexData.prototype.applyToMesh = function (mesh, updatable) {
         if (this.positions) {
             mesh.setVerticesData(this.positions, BABYLON.VertexBuffer.PositionKind, updatable);
         }
@@ -185,7 +185,7 @@ var BABYLON = BABYLON || {};
         return result;
     };
 
-    BABYLON.VertexData.CreateBox = function(size) {
+    BABYLON.VertexData.CreateBox = function (size) {
         var normalsSource = [
             new BABYLON.Vector3(0, 0, 1),
             new BABYLON.Vector3(0, 0, -1),
@@ -200,6 +200,8 @@ var BABYLON = BABYLON || {};
         var normals = [];
         var uvs = [];
 
+        size = size || 1;
+
         // Create each face in turn.
         for (var index = 0; index < normalsSource.length; index++) {
             var normal = normalsSource[index];
@@ -252,6 +254,10 @@ var BABYLON = BABYLON || {};
     };
 
     BABYLON.VertexData.CreateSphere = function (segments, diameter) {
+
+        segments = segments || 32;
+        diameter = diameter || 1;
+
         var radius = diameter / 2;
 
         var totalZRotationSteps = 2 + segments;
@@ -317,6 +323,11 @@ var BABYLON = BABYLON || {};
         var normals = [];
         var uvs = [];
 
+        height = height || 1;
+        diameterTop = diameterTop || 0.5;
+        diameterBottom = diameterBottom || 1;
+        tessellation = tessellation || 16;
+
         var getCircleVector = function (i) {
             var angle = (i * 2.0 * Math.PI / tessellation);
             var dx = Math.sin(angle);
@@ -425,6 +436,10 @@ var BABYLON = BABYLON || {};
         var normals = [];
         var uvs = [];
 
+        diameter = diameter || 1;
+        thickness = thickness || 0.5;
+        tessellation = tessellation || 16;
+
         var stride = tessellation + 1;
 
         for (var i = 0; i <= tessellation; i++) {
@@ -485,6 +500,10 @@ var BABYLON = BABYLON || {};
         var uvs = [];
         var row, col;
 
+        width = width || 1;
+        height = height || 1;
+        subdivisions = subdivisions || 1;
+
         for (row = 0; row <= subdivisions; row++) {
             for (col = 0; col <= subdivisions; col++) {
                 var position = new BABYLON.Vector3((col * width) / subdivisions - (width / 2.0), 0, ((subdivisions - row) * height) / subdivisions - (height / 2.0));
@@ -525,6 +544,8 @@ var BABYLON = BABYLON || {};
         var normals = [];
         var uvs = [];
 
+        size = size || 1;
+
         // Vertices
         var halfSize = size / 2.0;
         positions.push(-halfSize, -halfSize, 0);
@@ -562,4 +583,139 @@ var BABYLON = BABYLON || {};
 
         return vertexData;
     };
+
+    // based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3D/src/away3d/primitives/TorusKnot.as?spec=svn2473&r=2473
+    BABYLON.VertexData.CreateTorusKnot = function (radius, tube, radialSegments, tubularSegments, p, q) {
+        var indices = [];
+        var positions = [];
+        var normals = [];
+        var uvs = [];
+
+        radius = radius || 2;
+        tube = tube || 0.5;
+        radialSegments = radialSegments || 32;
+        tubularSegments = tubularSegments || 32;
+        p = p || 2;
+        q = q || 3;
+
+        // Helper
+        function getPos(u, q, p, radius) {
+
+            var cu = Math.cos(u);
+            var su = Math.sin(u);
+            var quOverP = q / p * u;
+            var cs = Math.cos(quOverP);
+
+            var tx = radius * (2 + cs) * 0.5 * cu;
+            var ty = radius * (2 + cs) * su * 0.5;
+            var tz = radius * Math.sin(quOverP) * 0.5;
+
+            return new BABYLON.Vector3(tx, ty, tz);
+        };
+
+        // Vertices
+        for (var i = 0; i <= radialSegments; i++) {
+            var modI = i % radialSegments;
+            var u = modI / radialSegments * 2 * p * Math.PI;
+            var p1 = getPos(u, q, p, radius);
+            var p2 = getPos(u + 0.01, q, p, radius);
+            var tang = p2.subtract(p1);
+            var n = p2.add(p1);
+
+            var bitan = BABYLON.Vector3.Cross(tang, n);
+            n = BABYLON.Vector3.Cross(bitan, tang);
+
+            bitan.normalize();
+            n.normalize();
+
+            for (var j = 0; j < tubularSegments; j++) {
+                var modJ = j % tubularSegments;
+                var v = modJ / tubularSegments * 2 * Math.PI;
+                var cx = -tube * Math.cos(v);
+                var cy = tube * Math.sin(v);
+
+                positions.push(p1.x + cx * n.x + cy * bitan.x);
+                positions.push(p1.y + cx * n.y + cy * bitan.y);
+                positions.push(p1.z + cx * n.z + cy * bitan.z);
+
+                uvs.push(i / radialSegments);
+                uvs.push(j / tubularSegments);
+            }
+        }
+
+        var max = radialSegments * tubularSegments - 1;
+
+        for (var i = 0; i < radialSegments; i++) {
+            for (var j = 0; j < tubularSegments; j++) {
+                var jNext =  (j + 1) % tubularSegments;
+                var a = i * tubularSegments + j;
+                var b = (i + 1) * tubularSegments + j;
+                var c = (i + 1) * tubularSegments + jNext;
+                var d = i * tubularSegments + jNext;
+
+                indices.push(a); indices.push(b); indices.push(d);
+                indices.push(b); indices.push(c); indices.push(d);
+            }
+        }
+
+        // Normals
+        BABYLON.VertexData.ComputeNormals(positions, indices, normals);
+
+        // Result
+        var vertexData = new BABYLON.VertexData();
+
+        vertexData.indices = indices;
+        vertexData.positions = positions;
+        vertexData.normals = normals;
+        vertexData.uvs = uvs;
+
+        return vertexData;
+    };
+
+    // Tools
+    BABYLON.VertexData.ComputeNormals = function (positions, indices, normals) {
+        var positionVectors = [];
+        var facesOfVertices = [];
+        var index;
+
+        for (index = 0; index < positions.length; index += 3) {
+            var vector3 = new BABYLON.Vector3(positions[index], positions[index + 1], positions[index + 2]);
+            positionVectors.push(vector3);
+            facesOfVertices.push([]);
+        }
+        // Compute normals
+        var facesNormals = [];
+        for (index = 0; index < indices.length / 3; index++) {
+            var i1 = indices[index * 3];
+            var i2 = indices[index * 3 + 1];
+            var i3 = indices[index * 3 + 2];
+
+            var p1 = positionVectors[i1];
+            var p2 = positionVectors[i2];
+            var p3 = positionVectors[i3];
+
+            var p1p2 = p1.subtract(p2);
+            var p3p2 = p3.subtract(p2);
+
+            facesNormals[index] = BABYLON.Vector3.Normalize(BABYLON.Vector3.Cross(p1p2, p3p2));
+            facesOfVertices[i1].push(index);
+            facesOfVertices[i2].push(index);
+            facesOfVertices[i3].push(index);
+        }
+
+        for (index = 0; index < positionVectors.length; index++) {
+            var faces = facesOfVertices[index];
+
+            var normal = BABYLON.Vector3.Zero();
+            for (var faceIndex = 0; faceIndex < faces.length; faceIndex++) {
+                normal.addInPlace(facesNormals[faces[faceIndex]]);
+            }
+
+            normal = BABYLON.Vector3.Normalize(normal.scale(1.0 / faces.length));
+
+            normals[index * 3] = normal.x;
+            normals[index * 3 + 1] = normal.y;
+            normals[index * 3 + 2] = normal.z;
+        }
+    };
 })();

+ 14 - 2
Babylon/babylon.engine.js

@@ -272,6 +272,8 @@ var BABYLON = BABYLON || {};
             gl.generateMipmap(gl.TEXTURE_2D);
             gl.bindTexture(gl.TEXTURE_2D, null);
         }
+
+        this._gl.bindFramebuffer(this._gl.FRAMEBUFFER, null);
     };
 
     BABYLON.Engine.prototype.flushFramebuffer = function () {
@@ -388,7 +390,16 @@ var BABYLON = BABYLON || {};
     };
 
     // Shaders
-    BABYLON.Engine.prototype.createEffect = function (baseName, attributesNames, uniformsNames, samplers, defines, optionalDefines) {
+    BABYLON.Engine.prototype._releaseEffect = function (effect) {
+        if (this._compiledEffects[effect._key]) {
+            delete this._compiledEffects[effect._key];
+            if (effect._program) {
+                this._gl.deleteProgram(effect._program);
+            }
+        }
+    };
+
+    BABYLON.Engine.prototype.createEffect = function (baseName, attributesNames, uniformsNames, samplers, defines, optionalDefines, onCompiled, onError) {
         var vertex = baseName.vertexElement || baseName.vertex || baseName;
         var fragment = baseName.fragmentElement || baseName.fragment || baseName;
         
@@ -397,7 +408,8 @@ var BABYLON = BABYLON || {};
             return this._compiledEffects[name];
         }
 
-        var effect = new BABYLON.Effect(baseName, attributesNames, uniformsNames, samplers, this, defines, optionalDefines);
+        var effect = new BABYLON.Effect(baseName, attributesNames, uniformsNames, samplers, this, defines, optionalDefines, onCompiled, onError);
+        effect._key = name;
         this._compiledEffects[name] = effect;
 
         return effect;

+ 1 - 1
Babylon/babylon.node.js

@@ -52,7 +52,7 @@ var BABYLON = BABYLON || {};
     };
 
     BABYLON.Node.prototype.isSynchronizedWithParent = function() {
-        return this.parent ? this.parent._currentRenderId === this._currentRenderId : true;
+        return this.parent ? this.parent._currentRenderId <= this._currentRenderId : true;
     };
 
     BABYLON.Node.prototype.isSynchronized = function (updateCache) {

Plik diff jest za duży
+ 26 - 0
babylon.1.11.0-beta.js