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

Still fixing latest small issues

David Catuhe пре 10 година
родитељ
комит
d7a08c8a03
27 измењених фајлова са 589 додато и 254 уклоњено
  1. 2 0
      Babylon/Audio/babylon.sound.js
  2. 3 1
      Babylon/Audio/babylon.soundtrack.js
  3. 2 1
      Babylon/Cameras/babylon.gamepadCamera.js
  4. 3 1
      Babylon/Cameras/babylon.gamepadCamera.ts
  5. 1 1
      Babylon/Culling/babylon.boundingBox.js
  6. 1 1
      Babylon/Lights/Shadows/babylon.shadowGenerator.js
  7. 7 2
      Babylon/Loading/Plugins/babylon.babylonFileLoader.js
  8. 2 2
      Babylon/Materials/Textures/Procedurals/babylon.customProceduralTexture.js
  9. 8 11
      Babylon/Materials/Textures/babylon.renderTargetTexture.js
  10. 0 4
      Babylon/Materials/Textures/babylon.renderTargetTexture.ts
  11. 119 33
      Babylon/Math/babylon.math.js
  12. 9 4
      Babylon/Mesh/babylon.abstractMesh.js
  13. 2 2
      Babylon/PostProcess/babylon.postProcess.js
  14. 2 2
      Babylon/PostProcess/babylon.postProcess.ts
  15. 45 5
      Babylon/PostProcess/babylon.ssaoRenderingPipeline.js
  16. 4 1
      Babylon/PostProcess/babylon.ssaoRenderingPipeline.ts
  17. 130 43
      Babylon/PostProcess/babylon.volumetricLightScatteringPostProcess.js
  18. 86 44
      Babylon/PostProcess/babylon.volumetricLightScatteringPostProcess.ts
  19. 9 16
      Babylon/Shaders/volumetricLightScattering.fragment.fx
  20. 21 5
      Babylon/Shaders/volumetricLightScatteringPass.fragment.fx
  21. 1 0
      Babylon/Tools/babylon.filesInput.js
  22. 8 8
      Babylon/Tools/babylon.tools.js
  23. 2 2
      Babylon/babylon.engine.js
  24. 2 0
      Babylon/babylon.scene.js
  25. 2 0
      Babylon/babylon.scene.ts
  26. 104 51
      babylon.2.0-beta.debug.js
  27. 14 14
      babylon.2.0-beta.js

+ 2 - 0
Babylon/Audio/babylon.sound.js

@@ -90,6 +90,8 @@ var BABYLON;
                 }
             }
             else {
+                // Adding an empty sound to avoid breaking audio calls for non Web Audio browsers
+                this._scene.mainSoundTrack.AddSound(this);
                 if (!BABYLON.Engine.audioEngine.WarnedWebAudioUnsupported) {
                     BABYLON.Tools.Error("Web Audio is not supported by your browser.");
                     BABYLON.Engine.audioEngine.WarnedWebAudioUnsupported = true;

+ 3 - 1
Babylon/Audio/babylon.soundtrack.js

@@ -37,7 +37,9 @@ var BABYLON;
             }
         };
         SoundTrack.prototype.AddSound = function (sound) {
-            sound.connectToSoundTrackAudioNode(this._trackGain);
+            if (BABYLON.Engine.audioEngine.canUseWebAudio) {
+                sound.connectToSoundTrackAudioNode(this._trackGain);
+            }
             if (sound.soundTrackId) {
                 if (sound.soundTrackId === -1) {
                     this._scene.mainSoundTrack.RemoveSound(sound);

+ 2 - 1
Babylon/Cameras/babylon.gamepadCamera.js

@@ -40,7 +40,8 @@ var BABYLON;
             RSValues.y = Math.abs(normalizedRY) > 0.001 ? 0 + normalizedRY : 0;
             ;
             var cameraTransform = BABYLON.Matrix.RotationYawPitchRoll(this.rotation.y, this.rotation.x, 0);
-            var deltaTransform = BABYLON.Vector3.TransformCoordinates(new BABYLON.Vector3(LSValues.x, 0, -LSValues.y), cameraTransform);
+            var speed = this._computeLocalCameraSpeed() * 50.0;
+            var deltaTransform = BABYLON.Vector3.TransformCoordinates(new BABYLON.Vector3(LSValues.x * speed, 0, -LSValues.y * speed), cameraTransform);
             this.cameraDirection = this.cameraDirection.add(deltaTransform);
             this.cameraRotation = this.cameraRotation.add(new BABYLON.Vector2(RSValues.y, RSValues.x));
         };

+ 3 - 1
Babylon/Cameras/babylon.gamepadCamera.ts

@@ -36,7 +36,9 @@ module BABYLON {
             RSValues.y = Math.abs(normalizedRY) > 0.001 ? 0 + normalizedRY : 0;;
 
             var cameraTransform = BABYLON.Matrix.RotationYawPitchRoll(this.rotation.y, this.rotation.x, 0);
-            var deltaTransform = BABYLON.Vector3.TransformCoordinates(new BABYLON.Vector3(LSValues.x, 0, -LSValues.y), cameraTransform);
+
+            var speed = this._computeLocalCameraSpeed() * 50.0;
+            var deltaTransform = BABYLON.Vector3.TransformCoordinates(new BABYLON.Vector3(LSValues.x * speed, 0, -LSValues.y * speed), cameraTransform);
             this.cameraDirection = this.cameraDirection.add(deltaTransform);
             this.cameraRotation = this.cameraRotation.add(new BABYLON.Vector2(RSValues.y, RSValues.x));
         }

+ 1 - 1
Babylon/Culling/babylon.boundingBox.js

@@ -127,7 +127,7 @@ var BABYLON;
                         break;
                     }
                 }
-                if (inCount == 0)
+                if (inCount === 0)
                     return false;
             }
             return true;

+ 1 - 1
Babylon/Lights/Shadows/babylon.shadowGenerator.js

@@ -4,7 +4,7 @@ var BABYLON;
         function ShadowGenerator(mapSize, light) {
             var _this = this;
             // Members
-            this.filter = ShadowGenerator.FILTER_VARIANCESHADOWMAP;
+            this.filter = ShadowGenerator.FILTER_NONE;
             this._darkness = 0;
             this._transparencyShadow = false;
             this._viewMatrix = BABYLON.Matrix.Zero();

+ 7 - 2
Babylon/Loading/Plugins/babylon.babylonFileLoader.js

@@ -1165,10 +1165,15 @@ var BABYLON;
                     }
                 }
                 // Sounds
-                if (parsedData.sounds && BABYLON.Engine.audioEngine.canUseWebAudio) {
+                if (parsedData.sounds) {
                     for (index = 0; index < parsedData.sounds.length; index++) {
                         var parsedSound = parsedData.sounds[index];
-                        parseSound(parsedSound, scene, rootUrl);
+                        if (BABYLON.Engine.audioEngine.canUseWebAudio) {
+                            parseSound(parsedSound, scene, rootUrl);
+                        }
+                        else {
+                            var emptySound = new BABYLON.Sound(parsedSound.name, null, scene);
+                        }
                     }
                 }
                 for (index = 0; index < scene.meshes.length; index++) {

+ 2 - 2
Babylon/Materials/Textures/Procedurals/babylon.customProceduralTexture.js

@@ -21,7 +21,7 @@ var BABYLON;
             var _this = this;
             var that = this;
             function noConfigFile() {
-                BABYLON.Tools.Log("No config file found in " + jsonUrl + " trying to use ShaderStore or DOM element");
+                BABYLON.Tools.Log("No config file found in " + jsonUrl + " trying to use ShadersStore or DOM element");
                 try {
                     that.setFragment(that._texturePath);
                 }
@@ -50,7 +50,7 @@ var BABYLON;
                     noConfigFile();
                 }
             }, false);
-            xhr.addEventListener("error", function (event) {
+            xhr.addEventListener("error", function () {
                 noConfigFile();
             }, false);
             try {

+ 8 - 11
Babylon/Materials/Textures/babylon.renderTargetTexture.js

@@ -81,9 +81,6 @@ var BABYLON;
         RenderTargetTexture.prototype.render = function (useCameraPostProcess) {
             var scene = this.getScene();
             var engine = scene.getEngine();
-            if (!this.activeCamera) {
-                this.activeCamera = scene.activeCamera;
-            }
             if (this._waitingRenderList) {
                 this.renderList = [];
                 for (var index = 0; index < this._waitingRenderList.length; index++) {
@@ -99,8 +96,6 @@ var BABYLON;
             if (!useCameraPostProcess || !scene.postProcessManager._prepareFrame(this._texture)) {
                 engine.bindFramebuffer(this._texture);
             }
-            // Clear
-            engine.clear(scene.clearColor, true, true);
             this._renderingManager.reset();
             var currentRenderList = this.renderList ? this.renderList : scene.getActiveMeshes().data;
             for (var meshIndex = 0; meshIndex < currentRenderList.length; meshIndex++) {
@@ -121,25 +116,27 @@ var BABYLON;
                     }
                 }
             }
-            if (!this._doNotChangeAspectRatio) {
-                scene.updateTransformMatrix(true);
-            }
             if (this.onBeforeRender) {
                 this.onBeforeRender();
             }
+            // Clear
+            engine.clear(scene.clearColor, true, true);
+            if (!this._doNotChangeAspectRatio) {
+                scene.updateTransformMatrix(true);
+            }
             // Render
             this._renderingManager.render(this.customRenderFunction, currentRenderList, this.renderParticles, this.renderSprites);
             if (useCameraPostProcess) {
                 scene.postProcessManager._finalizeFrame(false, this._texture);
             }
+            if (!this._doNotChangeAspectRatio) {
+                scene.updateTransformMatrix(true);
+            }
             if (this.onAfterRender) {
                 this.onAfterRender();
             }
             // Unbind
             engine.unBindFramebuffer(this._texture);
-            if (!this._doNotChangeAspectRatio) {
-                scene.updateTransformMatrix(true);
-            }
         };
         RenderTargetTexture.prototype.clone = function () {
             var textureSize = this.getSize();

+ 0 - 4
Babylon/Materials/Textures/babylon.renderTargetTexture.ts

@@ -91,10 +91,6 @@
             var scene = this.getScene();
             var engine = scene.getEngine();
 
-            if (!this.activeCamera) {
-                this.activeCamera = scene.activeCamera;
-            }
-
             if (this._waitingRenderList) {
                 this.renderList = [];
                 for (var index = 0; index < this._waitingRenderList.length; index++) {

+ 119 - 33
Babylon/Math/babylon.math.js

@@ -20,6 +20,7 @@ var BABYLON;
             array[index] = this.r;
             array[index + 1] = this.g;
             array[index + 2] = this.b;
+            return this;
         };
         Color3.prototype.toColor4 = function (alpha) {
             if (alpha === void 0) { alpha = 1; }
@@ -40,6 +41,7 @@ var BABYLON;
             result.r = this.r * otherColor.r;
             result.g = this.g * otherColor.g;
             result.b = this.b * otherColor.b;
+            return this;
         };
         Color3.prototype.equals = function (otherColor) {
             return otherColor && this.r === otherColor.r && this.g === otherColor.g && this.b === otherColor.b;
@@ -51,6 +53,7 @@ var BABYLON;
             result.r = this.r * scale;
             result.g = this.g * scale;
             result.b = this.b * scale;
+            return this;
         };
         Color3.prototype.add = function (otherColor) {
             return new Color3(this.r + otherColor.r, this.g + otherColor.g, this.b + otherColor.b);
@@ -59,6 +62,7 @@ var BABYLON;
             result.r = this.r + otherColor.r;
             result.g = this.g + otherColor.g;
             result.b = this.b + otherColor.b;
+            return this;
         };
         Color3.prototype.subtract = function (otherColor) {
             return new Color3(this.r - otherColor.r, this.g - otherColor.g, this.b - otherColor.b);
@@ -67,6 +71,7 @@ var BABYLON;
             result.r = this.r - otherColor.r;
             result.g = this.g - otherColor.g;
             result.b = this.b - otherColor.b;
+            return this;
         };
         Color3.prototype.clone = function () {
             return new Color3(this.r, this.g, this.b);
@@ -75,11 +80,13 @@ var BABYLON;
             this.r = source.r;
             this.g = source.g;
             this.b = source.b;
+            return this;
         };
         Color3.prototype.copyFromFloats = function (r, g, b) {
             this.r = r;
             this.g = g;
             this.b = b;
+            return this;
         };
         // Statics
         Color3.FromArray = function (array, offset) {
@@ -138,6 +145,7 @@ var BABYLON;
             this.g += right.g;
             this.b += right.b;
             this.a += right.a;
+            return this;
         };
         Color4.prototype.asArray = function () {
             var result = [];
@@ -152,6 +160,7 @@ var BABYLON;
             array[index + 1] = this.g;
             array[index + 2] = this.b;
             array[index + 3] = this.a;
+            return this;
         };
         Color4.prototype.add = function (right) {
             return new Color4(this.r + right.r, this.g + right.g, this.b + right.b, this.a + right.a);
@@ -164,6 +173,7 @@ var BABYLON;
             result.g = this.g - right.g;
             result.b = this.b - right.b;
             result.a = this.a - right.a;
+            return this;
         };
         Color4.prototype.scale = function (scale) {
             return new Color4(this.r * scale, this.g * scale, this.b * scale, this.a * scale);
@@ -173,6 +183,7 @@ var BABYLON;
             result.g = this.g * scale;
             result.b = this.b * scale;
             result.a = this.a * scale;
+            return this;
         };
         Color4.prototype.toString = function () {
             return "{R: " + this.r + " G:" + this.g + " B:" + this.b + " A:" + this.a + "}";
@@ -185,6 +196,7 @@ var BABYLON;
             this.g = source.g;
             this.b = source.b;
             this.a = source.a;
+            return this;
         };
         // Statics
         Color4.Lerp = function (left, right, amount) {
@@ -218,11 +230,10 @@ var BABYLON;
         };
         // Operators
         Vector2.prototype.toArray = function (array, index) {
-            if (index === undefined) {
-                index = 0;
-            }
+            if (index === void 0) { index = 0; }
             array[index] = this.x;
             array[index + 1] = this.y;
+            return this;
         };
         Vector2.prototype.asArray = function () {
             var result = [];
@@ -232,10 +243,12 @@ var BABYLON;
         Vector2.prototype.copyFrom = function (source) {
             this.x = source.x;
             this.y = source.y;
+            return this;
         };
         Vector2.prototype.copyFromFloats = function (x, y) {
             this.x = x;
             this.y = y;
+            return this;
         };
         Vector2.prototype.add = function (otherVector) {
             return new Vector2(this.x + otherVector.x, this.y + otherVector.y);
@@ -249,10 +262,12 @@ var BABYLON;
         Vector2.prototype.subtractInPlace = function (otherVector) {
             this.x -= otherVector.x;
             this.y -= otherVector.y;
+            return this;
         };
         Vector2.prototype.multiplyInPlace = function (otherVector) {
             this.x *= otherVector.x;
             this.y *= otherVector.y;
+            return this;
         };
         Vector2.prototype.multiply = function (otherVector) {
             return new Vector2(this.x * otherVector.x, this.y * otherVector.y);
@@ -260,6 +275,7 @@ var BABYLON;
         Vector2.prototype.multiplyToRef = function (otherVector, result) {
             result.x = this.x * otherVector.x;
             result.y = this.y * otherVector.y;
+            return this;
         };
         Vector2.prototype.multiplyByFloats = function (x, y) {
             return new Vector2(this.x * x, this.y * y);
@@ -270,6 +286,7 @@ var BABYLON;
         Vector2.prototype.divideToRef = function (otherVector, result) {
             result.x = this.x / otherVector.x;
             result.y = this.y / otherVector.y;
+            return this;
         };
         Vector2.prototype.negate = function () {
             return new Vector2(-this.x, -this.y);
@@ -399,17 +416,31 @@ var BABYLON;
             return result;
         };
         Vector3.prototype.toArray = function (array, index) {
-            if (index === undefined) {
-                index = 0;
-            }
+            if (index === void 0) { index = 0; }
             array[index] = this.x;
             array[index + 1] = this.y;
             array[index + 2] = this.z;
+            return this;
+        };
+        Vector3.prototype.toQuaternion = function () {
+            var result = new Quaternion(0, 0, 0, 1);
+            var cosxPlusz = Math.cos((this.x + this.z) * 0.5);
+            var sinxPlusz = Math.sin((this.x + this.z) * 0.5);
+            var coszMinusx = Math.cos((this.z - this.x) * 0.5);
+            var sinzMinusx = Math.sin((this.z - this.x) * 0.5);
+            var cosy = Math.cos(this.y * 0.5);
+            var siny = Math.sin(this.y * 0.5);
+            result.x = coszMinusx * siny;
+            result.y = -sinzMinusx * siny;
+            result.z = sinxPlusz * cosy;
+            result.w = cosxPlusz * cosy;
+            return result;
         };
         Vector3.prototype.addInPlace = function (otherVector) {
             this.x += otherVector.x;
             this.y += otherVector.y;
             this.z += otherVector.z;
+            return this;
         };
         Vector3.prototype.add = function (otherVector) {
             return new Vector3(this.x + otherVector.x, this.y + otherVector.y, this.z + otherVector.z);
@@ -418,11 +449,13 @@ var BABYLON;
             result.x = this.x + otherVector.x;
             result.y = this.y + otherVector.y;
             result.z = this.z + otherVector.z;
+            return this;
         };
         Vector3.prototype.subtractInPlace = function (otherVector) {
             this.x -= otherVector.x;
             this.y -= otherVector.y;
             this.z -= otherVector.z;
+            return this;
         };
         Vector3.prototype.subtract = function (otherVector) {
             return new Vector3(this.x - otherVector.x, this.y - otherVector.y, this.z - otherVector.z);
@@ -431,6 +464,7 @@ var BABYLON;
             result.x = this.x - otherVector.x;
             result.y = this.y - otherVector.y;
             result.z = this.z - otherVector.z;
+            return this;
         };
         Vector3.prototype.subtractFromFloats = function (x, y, z) {
             return new Vector3(this.x - x, this.y - y, this.z - z);
@@ -439,6 +473,7 @@ var BABYLON;
             result.x = this.x - x;
             result.y = this.y - y;
             result.z = this.z - z;
+            return this;
         };
         Vector3.prototype.negate = function () {
             return new Vector3(-this.x, -this.y, -this.z);
@@ -470,6 +505,7 @@ var BABYLON;
             this.x *= otherVector.x;
             this.y *= otherVector.y;
             this.z *= otherVector.z;
+            return this;
         };
         Vector3.prototype.multiply = function (otherVector) {
             return new Vector3(this.x * otherVector.x, this.y * otherVector.y, this.z * otherVector.z);
@@ -478,6 +514,7 @@ var BABYLON;
             result.x = this.x * otherVector.x;
             result.y = this.y * otherVector.y;
             result.z = this.z * otherVector.z;
+            return this;
         };
         Vector3.prototype.multiplyByFloats = function (x, y, z) {
             return new Vector3(this.x * x, this.y * y, this.z * z);
@@ -489,6 +526,7 @@ var BABYLON;
             result.x = this.x / otherVector.x;
             result.y = this.y / otherVector.y;
             result.z = this.z / otherVector.z;
+            return this;
         };
         Vector3.prototype.MinimizeInPlace = function (other) {
             if (other.x < this.x)
@@ -497,6 +535,7 @@ var BABYLON;
                 this.y = other.y;
             if (other.z < this.z)
                 this.z = other.z;
+            return this;
         };
         Vector3.prototype.MaximizeInPlace = function (other) {
             if (other.x > this.x)
@@ -505,6 +544,7 @@ var BABYLON;
                 this.y = other.y;
             if (other.z > this.z)
                 this.z = other.z;
+            return this;
         };
         // Properties
         Vector3.prototype.length = function () {
@@ -531,11 +571,13 @@ var BABYLON;
             this.x = source.x;
             this.y = source.y;
             this.z = source.z;
+            return this;
         };
         Vector3.prototype.copyFromFloats = function (x, y, z) {
             this.x = x;
             this.y = y;
             this.z = z;
+            return this;
         };
         // Statics
         Vector3.FromArray = function (array, offset) {
@@ -748,12 +790,14 @@ var BABYLON;
             array[index + 1] = this.y;
             array[index + 2] = this.z;
             array[index + 3] = this.w;
+            return this;
         };
         Vector4.prototype.addInPlace = function (otherVector) {
             this.x += otherVector.x;
             this.y += otherVector.y;
             this.z += otherVector.z;
             this.w += otherVector.w;
+            return this;
         };
         Vector4.prototype.add = function (otherVector) {
             return new Vector4(this.x + otherVector.x, this.y + otherVector.y, this.z + otherVector.z, this.w + otherVector.w);
@@ -763,12 +807,14 @@ var BABYLON;
             result.y = this.y + otherVector.y;
             result.z = this.z + otherVector.z;
             result.w = this.w + otherVector.w;
+            return this;
         };
         Vector4.prototype.subtractInPlace = function (otherVector) {
             this.x -= otherVector.x;
             this.y -= otherVector.y;
             this.z -= otherVector.z;
             this.w -= otherVector.w;
+            return this;
         };
         Vector4.prototype.subtract = function (otherVector) {
             return new Vector4(this.x - otherVector.x, this.y - otherVector.y, this.z - otherVector.z, this.w - otherVector.w);
@@ -778,6 +824,7 @@ var BABYLON;
             result.y = this.y - otherVector.y;
             result.z = this.z - otherVector.z;
             result.w = this.w - otherVector.w;
+            return this;
         };
         Vector4.prototype.subtractFromFloats = function (x, y, z, w) {
             return new Vector4(this.x - x, this.y - y, this.z - z, this.w - w);
@@ -787,6 +834,7 @@ var BABYLON;
             result.y = this.y - y;
             result.z = this.z - z;
             result.w = this.w - w;
+            return this;
         };
         Vector4.prototype.negate = function () {
             return new Vector4(-this.x, -this.y, -this.z, -this.w);
@@ -821,6 +869,7 @@ var BABYLON;
             this.y *= otherVector.y;
             this.z *= otherVector.z;
             this.w *= otherVector.w;
+            return this;
         };
         Vector4.prototype.multiply = function (otherVector) {
             return new Vector4(this.x * otherVector.x, this.y * otherVector.y, this.z * otherVector.z, this.w * otherVector.w);
@@ -830,6 +879,7 @@ var BABYLON;
             result.y = this.y * otherVector.y;
             result.z = this.z * otherVector.z;
             result.w = this.w * otherVector.w;
+            return this;
         };
         Vector4.prototype.multiplyByFloats = function (x, y, z, w) {
             return new Vector4(this.x * x, this.y * y, this.z * z, this.w * w);
@@ -842,6 +892,7 @@ var BABYLON;
             result.y = this.y / otherVector.y;
             result.z = this.z / otherVector.z;
             result.w = this.w / otherVector.w;
+            return this;
         };
         Vector4.prototype.MinimizeInPlace = function (other) {
             if (other.x < this.x)
@@ -852,6 +903,7 @@ var BABYLON;
                 this.z = other.z;
             if (other.w < this.w)
                 this.w = other.w;
+            return this;
         };
         Vector4.prototype.MaximizeInPlace = function (other) {
             if (other.x > this.x)
@@ -862,6 +914,7 @@ var BABYLON;
                 this.z = other.z;
             if (other.w > this.w)
                 this.w = other.w;
+            return this;
         };
         // Properties
         Vector4.prototype.length = function () {
@@ -890,12 +943,14 @@ var BABYLON;
             this.y = source.y;
             this.z = source.z;
             this.w = source.w;
+            return this;
         };
         Vector4.prototype.copyFromFloats = function (x, y, z, w) {
             this.x = x;
             this.y = y;
             this.z = z;
             this.w = w;
+            return this;
         };
         // Statics
         Vector4.FromArray = function (array, offset) {
@@ -990,12 +1045,14 @@ var BABYLON;
             this.y = other.y;
             this.z = other.z;
             this.w = other.w;
+            return this;
         };
         Quaternion.prototype.copyFromFloats = function (x, y, z, w) {
             this.x = x;
             this.y = y;
             this.z = z;
             this.w = w;
+            return this;
         };
         Quaternion.prototype.add = function (other) {
             return new Quaternion(this.x + other.x, this.y + other.y, this.z + other.z, this.w + other.w);
@@ -1016,6 +1073,7 @@ var BABYLON;
             result.y = -this.x * q1.z + this.y * q1.w + this.z * q1.x + this.w * q1.y;
             result.z = this.x * q1.y - this.y * q1.x + this.z * q1.w + this.w * q1.z;
             result.w = -this.x * q1.x - this.y * q1.y - this.z * q1.z + this.w * q1.w;
+            return this;
         };
         Quaternion.prototype.length = function () {
             return Math.sqrt((this.x * this.x) + (this.y * this.y) + (this.z * this.z) + (this.w * this.w));
@@ -1026,6 +1084,7 @@ var BABYLON;
             this.y *= length;
             this.z *= length;
             this.w *= length;
+            return this;
         };
         Quaternion.prototype.toEulerAngles = function () {
             var result = Vector3.Zero();
@@ -1064,6 +1123,7 @@ var BABYLON;
                     result.z = 0.0;
                 }
             }
+            return this;
         };
         Quaternion.prototype.toRotationMatrix = function (result) {
             var xx = this.x * this.x;
@@ -1091,8 +1151,19 @@ var BABYLON;
             result.m[13] = 0;
             result.m[14] = 0;
             result.m[15] = 1.0;
+            return this;
         };
         Quaternion.prototype.fromRotationMatrix = function (matrix) {
+            Quaternion.FromRotationMatrixToRef(matrix, this);
+            return this;
+        };
+        // Statics
+        Quaternion.FromRotationMatrix = function (matrix) {
+            var result = new Quaternion();
+            Quaternion.FromRotationMatrixToRef(matrix, result);
+            return result;
+        };
+        Quaternion.FromRotationMatrixToRef = function (matrix, result) {
             var data = matrix.m;
             var m11 = data[0], m12 = data[4], m13 = data[8];
             var m21 = data[1], m22 = data[5], m23 = data[9];
@@ -1101,35 +1172,33 @@ var BABYLON;
             var s;
             if (trace > 0) {
                 s = 0.5 / Math.sqrt(trace + 1.0);
-                this.w = 0.25 / s;
-                this.x = (m32 - m23) * s;
-                this.y = (m13 - m31) * s;
-                this.z = (m21 - m12) * s;
-                return;
+                result.w = 0.25 / s;
+                result.x = (m32 - m23) * s;
+                result.y = (m13 - m31) * s;
+                result.z = (m21 - m12) * s;
             }
-            if (m11 > m22 && m11 > m33) {
+            else if (m11 > m22 && m11 > m33) {
                 s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33);
-                this.w = (m32 - m23) / s;
-                this.x = 0.25 * s;
-                this.y = (m12 + m21) / s;
-                this.z = (m13 + m31) / s;
-                return;
+                result.w = (m32 - m23) / s;
+                result.x = 0.25 * s;
+                result.y = (m12 + m21) / s;
+                result.z = (m13 + m31) / s;
             }
-            if (m22 > m33) {
+            else if (m22 > m33) {
                 s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33);
-                this.w = (m13 - m31) / s;
-                this.x = (m12 + m21) / s;
-                this.y = 0.25 * s;
-                this.z = (m23 + m32) / s;
-                return;
+                result.w = (m13 - m31) / s;
+                result.x = (m12 + m21) / s;
+                result.y = 0.25 * s;
+                result.z = (m23 + m32) / s;
+            }
+            else {
+                s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22);
+                result.w = (m21 - m12) / s;
+                result.x = (m13 + m31) / s;
+                result.y = (m23 + m32) / s;
+                result.z = 0.25 * s;
             }
-            s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22);
-            this.w = (m21 - m12) / s;
-            this.x = (m13 + m31) / s;
-            this.y = (m23 + m32) / s;
-            this.z = 0.25 * s;
         };
-        // Statics
         Quaternion.Inverse = function (q) {
             return new Quaternion(-q.x, -q.y, -q.z, q.w);
         };
@@ -1226,6 +1295,7 @@ var BABYLON;
         };
         Matrix.prototype.invert = function () {
             this.invertToRef(this);
+            return this;
         };
         Matrix.prototype.invertToRef = function (other) {
             var l1 = this.m[0];
@@ -1283,11 +1353,13 @@ var BABYLON;
             other.m[7] = (((l1 * l34) - (l3 * l37)) + (l4 * l38)) * l27;
             other.m[11] = -(((l1 * l35) - (l2 * l37)) + (l4 * l39)) * l27;
             other.m[15] = (((l1 * l36) - (l2 * l38)) + (l3 * l39)) * l27;
+            return this;
         };
         Matrix.prototype.setTranslation = function (vector3) {
             this.m[12] = vector3.x;
             this.m[13] = vector3.y;
             this.m[14] = vector3.z;
+            return this;
         };
         Matrix.prototype.multiply = function (other) {
             var result = new Matrix();
@@ -1298,15 +1370,18 @@ var BABYLON;
             for (var index = 0; index < 16; index++) {
                 this.m[index] = other.m[index];
             }
+            return this;
         };
         Matrix.prototype.copyToArray = function (array, offset) {
             if (offset === void 0) { offset = 0; }
             for (var index = 0; index < 16; index++) {
                 array[offset + index] = this.m[index];
             }
+            return this;
         };
         Matrix.prototype.multiplyToRef = function (other, result) {
             this.multiplyToArray(other, result.m, 0);
+            return this;
         };
         Matrix.prototype.multiplyToArray = function (other, result, offset) {
             var tm0 = this.m[0];
@@ -1357,6 +1432,7 @@ var BABYLON;
             result[offset + 13] = tm12 * om1 + tm13 * om5 + tm14 * om9 + tm15 * om13;
             result[offset + 14] = tm12 * om2 + tm13 * om6 + tm14 * om10 + tm15 * om14;
             result[offset + 15] = tm12 * om3 + tm13 * om7 + tm14 * om11 + tm15 * om15;
+            return this;
         };
         Matrix.prototype.equals = function (value) {
             return value && (this.m[0] === value.m[0] && this.m[1] === value.m[1] && this.m[2] === value.m[2] && this.m[3] === value.m[3] && this.m[4] === value.m[4] && this.m[5] === value.m[5] && this.m[6] === value.m[6] && this.m[7] === value.m[7] && this.m[8] === value.m[8] && this.m[9] === value.m[9] && this.m[10] === value.m[10] && this.m[11] === value.m[11] && this.m[12] === value.m[12] && this.m[13] === value.m[13] && this.m[14] === value.m[14] && this.m[15] === value.m[15]);
@@ -1374,15 +1450,15 @@ var BABYLON;
             scale.x = xs * Math.sqrt(this.m[0] * this.m[0] + this.m[1] * this.m[1] + this.m[2] * this.m[2]);
             scale.y = ys * Math.sqrt(this.m[4] * this.m[4] + this.m[5] * this.m[5] + this.m[6] * this.m[6]);
             scale.z = zs * Math.sqrt(this.m[8] * this.m[8] + this.m[9] * this.m[9] + this.m[10] * this.m[10]);
-            if (scale.x == 0 || scale.y == 0 || scale.z == 0) {
+            if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
                 rotation.x = 0;
                 rotation.y = 0;
                 rotation.z = 0;
                 rotation.w = 1;
                 return false;
             }
-            var rotationMatrix = BABYLON.Matrix.FromValues(this.m[0] / scale.x, this.m[1] / scale.x, this.m[2] / scale.x, 0, this.m[4] / scale.y, this.m[5] / scale.y, this.m[6] / scale.y, 0, this.m[8] / scale.z, this.m[9] / scale.z, this.m[10] / scale.z, 0, 0, 0, 0, 1);
-            rotation.fromRotationMatrix(rotationMatrix);
+            var rotationMatrix = Matrix.FromValues(this.m[0] / scale.x, this.m[1] / scale.x, this.m[2] / scale.x, 0, this.m[4] / scale.y, this.m[5] / scale.y, this.m[6] / scale.y, 0, this.m[8] / scale.z, this.m[9] / scale.z, this.m[10] / scale.z, 0, 0, 0, 0, 1);
+            Quaternion.FromRotationMatrixToRef(rotationMatrix, rotation);
             return true;
         };
         // Statics
@@ -1769,6 +1845,7 @@ var BABYLON;
             this.normal.y *= magnitude;
             this.normal.z *= magnitude;
             this.d *= magnitude;
+            return this;
         };
         Plane.prototype.transform = function (transformation) {
             var transposedMatrix = Matrix.Transpose(transformation);
@@ -1807,6 +1884,7 @@ var BABYLON;
             this.normal.y = xz * invPyth;
             this.normal.z = xy * invPyth;
             this.d = -((this.normal.x * point1.x) + (this.normal.y * point1.y) + (this.normal.z * point1.z));
+            return this;
         };
         Plane.prototype.isFrontFacingTo = function (direction, epsilon) {
             var dot = Vector3.Dot(this.normal, direction);
@@ -2179,10 +2257,12 @@ var BABYLON;
         PathCursor.prototype.moveAhead = function (step) {
             if (step === void 0) { step = 0.002; }
             this.move(step);
+            return this;
         };
         PathCursor.prototype.moveBack = function (step) {
             if (step === void 0) { step = 0.002; }
             this.move(-step);
+            return this;
         };
         PathCursor.prototype.move = function (step) {
             if (Math.abs(step) > 1) {
@@ -2191,6 +2271,7 @@ var BABYLON;
             this.value += step;
             this.ensureLimits();
             this.raiseOnChange();
+            return this;
         };
         PathCursor.prototype.ensureLimits = function () {
             while (this.value > 1) {
@@ -2199,18 +2280,22 @@ var BABYLON;
             while (this.value < 0) {
                 this.value += 1;
             }
+            return this;
         };
         // used by animation engine
         PathCursor.prototype.markAsDirty = function (propertyName) {
             this.ensureLimits();
             this.raiseOnChange();
+            return this;
         };
         PathCursor.prototype.raiseOnChange = function () {
             var _this = this;
             this._onchange.forEach(function (f) { return f(_this); });
+            return this;
         };
         PathCursor.prototype.onchange = function (f) {
             this._onchange.push(f);
+            return this;
         };
         return PathCursor;
     })();
@@ -2274,7 +2359,7 @@ var BABYLON;
         Path2.prototype.getPointAtLengthPosition = function (normalizedLengthPosition) {
             if (normalizedLengthPosition < 0 || normalizedLengthPosition > 1) {
                 BABYLON.Tools.Error("normalized length position should be between 0 and 1.");
-                return;
+                return Vector2.Zero();
             }
             var lengthPosition = normalizedLengthPosition * this.length();
             var previousOffset = 0;
@@ -2292,6 +2377,7 @@ var BABYLON;
                 previousOffset = nextOffset;
             }
             BABYLON.Tools.Error("internal error");
+            return Vector2.Zero();
         };
         Path2.StartingAt = function (x, y) {
             return new Path2(x, y);

+ 9 - 4
Babylon/Mesh/babylon.abstractMesh.js

@@ -504,19 +504,24 @@ var BABYLON;
             if (!physicsEngine) {
                 return;
             }
+            impostor = impostor || BABYLON.PhysicsEngine.NoImpostor;
             if (impostor.impostor) {
                 // Old API
                 options = impostor;
                 impostor = impostor.impostor;
             }
-            impostor = impostor || BABYLON.PhysicsEngine.NoImpostor;
             if (impostor === BABYLON.PhysicsEngine.NoImpostor) {
                 physicsEngine._unregisterMesh(this);
                 return;
             }
-            options.mass = options.mass || 0;
-            options.friction = options.friction || 0.2;
-            options.restitution = options.restitution || 0.2;
+            if (!options) {
+                options = { mass: 0, friction: 0.2, restitution: 0.2 };
+            }
+            else {
+                options.mass = options.mass || 0;
+                options.friction = options.friction || 0.2;
+                options.restitution = options.restitution || 0.2;
+            }
             this._physicImpostor = impostor;
             this._physicsMass = options.mass;
             this._physicsFriction = options.friction;

+ 2 - 2
Babylon/PostProcess/babylon.postProcess.js

@@ -1,7 +1,7 @@
 var BABYLON;
 (function (BABYLON) {
     var PostProcess = (function () {
-        function PostProcess(name, fragmentUrl, parameters, samplers, ratio, camera, samplingMode, engine, reusable) {
+        function PostProcess(name, fragmentUrl, parameters, samplers, ratio, camera, samplingMode, engine, reusable, defines) {
             this.name = name;
             this.width = -1;
             this.height = -1;
@@ -22,7 +22,7 @@ var BABYLON;
             this._reusable = reusable || false;
             samplers = samplers || [];
             samplers.push("textureSampler");
-            this._effect = this._engine.createEffect({ vertex: "postprocess", fragment: fragmentUrl }, ["position"], parameters || [], samplers, "");
+            this._effect = this._engine.createEffect({ vertex: "postprocess", fragment: fragmentUrl }, ["position"], parameters || [], samplers, defines !== undefined ? defines : "");
         }
         PostProcess.prototype.isReusable = function () {
             return this._reusable;

+ 2 - 2
Babylon/PostProcess/babylon.postProcess.ts

@@ -17,7 +17,7 @@
         public _currentRenderTextureInd = 0;
         private _effect: Effect;
 
-        constructor(public name: string, fragmentUrl: string, parameters: string[], samplers: string[], ratio: number, camera: Camera, samplingMode: number, engine?: Engine, reusable?: boolean) {
+        constructor(public name: string, fragmentUrl: string, parameters: string[], samplers: string[], ratio: number, camera: Camera, samplingMode: number, engine?: Engine, reusable?: boolean, defines?: string) {
             if (camera != null) {
                 this._camera = camera;
                 this._scene = camera.getScene();
@@ -38,7 +38,7 @@
             this._effect = this._engine.createEffect({ vertex: "postprocess", fragment: fragmentUrl },
                 ["position"],
                 parameters || [],
-                samplers, "");
+                samplers, defines !== undefined ? defines : "");
         }
 
         public isReusable(): boolean {

+ 45 - 5
Babylon/PostProcess/babylon.ssaoRenderingPipeline.js

@@ -8,15 +8,42 @@ var BABYLON;
 (function (BABYLON) {
     var SSAORenderingPipeline = (function (_super) {
         __extends(SSAORenderingPipeline, _super);
+        /**
+         * @constructor
+         * @param {string} name - The rendering pipeline name
+         * @param {BABYLON.Scene} scene - The scene linked to this pipeline
+         * @param {number} ratio - The size of the postprocesses (0.5 means that your postprocess will have a width = canvas.width 0.5 and a height = canvas.height 0.5)
+         * @param {BABYLON.Camera[]} cameras - The array of cameras that the rendering pipeline will be attached to
+         */
         function SSAORenderingPipeline(name, scene, ratio, cameras) {
             var _this = this;
             if (ratio === void 0) { ratio = 1.0; }
             _super.call(this, scene.getEngine(), name);
             // Members
+            /**
+            * The PassPostProcess id in the pipeline that contains the original scene color
+            * @type {string}
+            */
             this.SSAOOriginalSceneColorEffect = "SSAOOriginalSceneColorEffect";
+            /**
+            * The SSAO PostProcess id in the pipeline
+            * @type {string}
+            */
             this.SSAORenderEffect = "SSAORenderEffect";
+            /**
+            * The horizontal blur PostProcess id in the pipeline
+            * @type {string}
+            */
             this.SSAOBlurHRenderEffect = "SSAOBlurHRenderEffect";
+            /**
+            * The vertical blur PostProcess id in the pipeline
+            * @type {string}
+            */
             this.SSAOBlurVRenderEffect = "SSAOBlurVRenderEffect";
+            /**
+            * The PostProcess id in the pipeline that combines the SSAO-Blur output with the original scene color (SSAOOriginalSceneColorEffect)
+            * @type {string}
+            */
             this.SSAOCombineRenderEffect = "SSAOCombineRenderEffect";
             this._firstUpdate = true;
             this._scene = scene;
@@ -25,8 +52,8 @@ var BABYLON;
             this._depthTexture = scene.enableDepthRenderer().getDepthMap(); // Force depth renderer "on"
             this._originalColorPostProcess = new BABYLON.PassPostProcess("SSAOOriginalSceneColor", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false);
             this._createSSAOPostProcess(ratio);
-            this._blurHPostProcess = new BABYLON.BlurPostProcess("SSAOBlurH", new BABYLON.Vector2(2.0, 0.0), 2.0, ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false);
-            this._blurVPostProcess = new BABYLON.BlurPostProcess("SSAOBlurV", new BABYLON.Vector2(0.0, 2.0), 2.0, ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false);
+            this._blurHPostProcess = new BABYLON.BlurPostProcess("SSAOBlurH", new BABYLON.Vector2(2.0, 0.0), 1.3, ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false);
+            this._blurVPostProcess = new BABYLON.BlurPostProcess("SSAOBlurV", new BABYLON.Vector2(0.0, 2.0), 1.3, ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false);
             this._createSSAOCombinePostProcess();
             // Set up pipeline
             this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), this.SSAOOriginalSceneColorEffect, function () {
@@ -50,21 +77,34 @@ var BABYLON;
                 scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(name, cameras);
         }
         // Public Methods
+        /**
+         * Returns the horizontal blur PostProcess
+         * @return {BABYLON.BlurPostProcess} The horizontal blur post-process
+         */
         SSAORenderingPipeline.prototype.getBlurHPostProcess = function () {
             return this._blurHPostProcess;
         };
+        /**
+         * Returns the vertical blur PostProcess
+         * @return {BABYLON.BlurPostProcess} The vertical blur post-process
+         */
         SSAORenderingPipeline.prototype.getBlurVPostProcess = function () {
             return this._blurVPostProcess;
         };
-        SSAORenderingPipeline.prototype.dispose = function (cameras) {
-            if (cameras !== undefined)
-                this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, cameras);
+        /**
+         * Removes the internal pipeline assets and detatches the pipeline from the scene cameras
+         */
+        SSAORenderingPipeline.prototype.dispose = function (disableDepthRender) {
+            if (disableDepthRender === void 0) { disableDepthRender = false; }
+            this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._scene.cameras);
             this._originalColorPostProcess = undefined;
             this._ssaoPostProcess = undefined;
             this._blurHPostProcess = undefined;
             this._blurVPostProcess = undefined;
             this._ssaoCombinePostProcess = undefined;
             this._randomTexture.dispose();
+            if (disableDepthRender)
+                this._scene.disableDepthRenderer();
         };
         // Private Methods
         SSAORenderingPipeline.prototype._createSSAOPostProcess = function (ratio) {

+ 4 - 1
Babylon/PostProcess/babylon.ssaoRenderingPipeline.ts

@@ -95,7 +95,7 @@
         /**
          * Removes the internal pipeline assets and detatches the pipeline from the scene cameras
          */
-        public dispose(): void {
+        public dispose(disableDepthRender: boolean = false): void {
             this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._scene.cameras);
 
             this._originalColorPostProcess = undefined;
@@ -105,6 +105,9 @@
             this._ssaoCombinePostProcess = undefined;
 
             this._randomTexture.dispose();
+
+            if (disableDepthRender)
+                this._scene.disableDepthRenderer();
         }
 
         // Private Methods

+ 130 - 43
Babylon/PostProcess/babylon.volumetricLightScatteringPostProcess.js

@@ -6,40 +6,74 @@ var __extends = this.__extends || function (d, b) {
 };
 var BABYLON;
 (function (BABYLON) {
-    var GodRaysPostProcess = (function (_super) {
-        __extends(GodRaysPostProcess, _super);
-        function GodRaysPostProcess(name, ratio, camera, samplingMode, engine, reusable) {
+    // Inspired by http://http.developer.nvidia.com/GPUGems3/gpugems3_ch13.html
+    var VolumetricLightScatteringPostProcess = (function (_super) {
+        __extends(VolumetricLightScatteringPostProcess, _super);
+        /**
+         * @constructor
+         * @param {string} name - The post-process name
+         * @param {number} ratio - The size of the postprocesses (0.5 means that your postprocess will have a width = canvas.width 0.5 and a height = canvas.height 0.5)
+         * @param {BABYLON.Camera} camera - The camera that the post-process will be attached to
+         * @param {BABYLON.Mesh} mesh - The mesh used to create the light scattering
+         * @param {number} samplingMode - The post-process filtering mode
+         * @param {BABYLON.Engine} engine - The babylon engine
+         * @param {boolean} reusable - If the post-process is reusable
+         */
+        function VolumetricLightScatteringPostProcess(name, ratio, camera, mesh, samples, samplingMode, engine, reusable) {
             var _this = this;
-            _super.call(this, name, "volumetricLightScattering", ["lightPositionOnScreen"], ["lightScatteringSampler"], ratio, camera, samplingMode, engine, reusable);
+            if (samples === void 0) { samples = 100; }
+            if (samplingMode === void 0) { samplingMode = BABYLON.Texture.BILINEAR_SAMPLINGMODE; }
+            _super.call(this, name, "volumetricLightScattering", ["decay", "exposure", "weight", "meshPositionOnScreen", "density"], ["lightScatteringSampler"], ratio, camera, samplingMode, engine, reusable, "#define NUM_SAMPLES " + samples);
             this._screenCoordinates = BABYLON.Vector2.Zero();
+            /**
+            * Set if the post-process should use a custom position for the light source (true) or the internal mesh position (false)
+            * @type {boolean}
+            */
+            this.useCustomMeshPosition = false;
+            /**
+            * If the post-process should inverse the light scattering direction
+            * @type {boolean}
+            */
             this.invert = true;
+            /**
+            * Array containing the excluded meshes not rendered in the internal pass
+            */
+            this.excludedMeshes = new Array();
+            this.exposure = 0.3;
+            this.decay = 0.96815;
+            this.weight = 0.58767;
+            this.density = 0.926;
             var scene = camera.getScene();
             this._viewPort = new BABYLON.Viewport(0, 0, 1, 1).toGlobal(scene.getEngine());
-            // Create billboard
-            this.mesh = BABYLON.Mesh.CreatePlane("VolumetricLightScatteringMesh", 2, scene);
-            this.mesh.billboardMode = BABYLON.AbstractMesh.BILLBOARDMODE_ALL;
-            this.mesh.material = new BABYLON.StandardMaterial('VolumetricLightScatteringMaterial', scene);
+            // Configure mesh
+            this.mesh = (mesh !== null) ? mesh : VolumetricLightScatteringPostProcess.CreateDefaultMesh("VolumetricLightScatteringMesh", scene);
             // Configure
-            this._createPass(scene);
+            this._createPass(scene, 0.5);
             this.onApply = function (effect) {
-                _this._updateScreenCoordinates(scene);
-                effect.setTexture("lightScatteringSampler", _this._godRaysRTT);
-                effect.setVector2("lightPositionOnScreen", _this._screenCoordinates);
+                _this._updateMeshScreenCoordinates(scene);
+                effect.setTexture("lightScatteringSampler", _this._volumetricLightScatteringRTT);
+                effect.setFloat("exposure", _this.exposure);
+                effect.setFloat("decay", _this.decay);
+                effect.setFloat("weight", _this.weight);
+                effect.setFloat("density", _this.density);
+                effect.setVector2("meshPositionOnScreen", _this._screenCoordinates);
             };
         }
-        GodRaysPostProcess.prototype.isReady = function (subMesh, useInstances) {
+        VolumetricLightScatteringPostProcess.prototype.isReady = function (subMesh, useInstances) {
             var mesh = subMesh.getMesh();
-            var scene = mesh.getScene();
             var defines = [];
             var attribs = [BABYLON.VertexBuffer.PositionKind];
             var material = subMesh.getMaterial();
             // Render this.mesh as default
-            if (mesh === this.mesh)
+            if (mesh === this.mesh) {
                 defines.push("#define BASIC_RENDER");
+            }
             // Alpha test
             if (material) {
                 if (material.needAlphaTesting() || mesh === this.mesh)
                     defines.push("#define ALPHATEST");
+                if (material.opacityTexture !== undefined)
+                    defines.push("#define OPACITY");
                 if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
                     attribs.push(BABYLON.VertexBuffer.UVKind);
                     defines.push("#define UV1");
@@ -68,30 +102,64 @@ var BABYLON;
             var join = defines.join("\n");
             if (this._cachedDefines !== join) {
                 this._cachedDefines = join;
-                this._godRaysPass = mesh.getScene().getEngine().createEffect({ vertexElement: "depth", fragmentElement: "volumetricLightScatteringPass" }, attribs, ["world", "mBones", "viewProjection", "diffuseMatrix", "far"], ["diffuseSampler"], join);
+                this._volumetricLightScatteringPass = mesh.getScene().getEngine().createEffect({ vertexElement: "depth", fragmentElement: "volumetricLightScatteringPass" }, attribs, ["world", "mBones", "viewProjection", "diffuseMatrix", "far"], ["diffuseSampler", "opacitySampler"], join);
             }
-            return this._godRaysPass.isReady();
+            return this._volumetricLightScatteringPass.isReady();
+        };
+        /**
+         * Sets the new light position for light scattering effect
+         * @param {BABYLON.Vector3} The new custom light position
+         */
+        VolumetricLightScatteringPostProcess.prototype.setCustomMeshPosition = function (position) {
+            this._customMeshPosition = position;
+        };
+        /**
+         * Returns the light position for light scattering effect
+         * @return {BABYLON.Vector3} The custom light position
+         */
+        VolumetricLightScatteringPostProcess.prototype.getCustomMeshPosition = function () {
+            return this._customMeshPosition;
         };
-        GodRaysPostProcess.prototype.dispose = function (camera) {
-            this._godRaysRTT.dispose();
+        /**
+         * Disposes the internal assets and detaches the post-process from the camera
+         */
+        VolumetricLightScatteringPostProcess.prototype.dispose = function (camera) {
+            var rttIndex = camera.getScene().customRenderTargets.indexOf(this._volumetricLightScatteringRTT);
+            if (rttIndex !== -1) {
+                camera.getScene().customRenderTargets.splice(rttIndex, 1);
+            }
+            this._volumetricLightScatteringRTT.dispose();
             _super.prototype.dispose.call(this, camera);
         };
-        GodRaysPostProcess.prototype.getPass = function () {
-            return this._godRaysRTT;
+        /**
+         * Returns the render target texture used by the post-process
+         * @return {BABYLON.RenderTargetTexture} The render target texture used by the post-process
+         */
+        VolumetricLightScatteringPostProcess.prototype.getPass = function () {
+            return this._volumetricLightScatteringRTT;
         };
         // Private methods
-        GodRaysPostProcess.prototype._createPass = function (scene) {
+        VolumetricLightScatteringPostProcess.prototype._meshExcluded = function (mesh) {
+            if (this.excludedMeshes.length > 0 && this.excludedMeshes.indexOf(mesh) !== -1) {
+                return true;
+            }
+            return false;
+        };
+        VolumetricLightScatteringPostProcess.prototype._createPass = function (scene, ratio) {
             var _this = this;
             var engine = scene.getEngine();
-            this._godRaysRTT = new BABYLON.RenderTargetTexture("volumetricLightScatteringMap", { width: engine.getRenderWidth(), height: engine.getRenderHeight() }, scene, false, true, BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT);
-            this._godRaysRTT.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE;
-            this._godRaysRTT.wrapV = BABYLON.Texture.CLAMP_ADDRESSMODE;
-            this._godRaysRTT.renderList = null;
-            this._godRaysRTT.renderParticles = false;
-            scene.customRenderTargets.push(this._godRaysRTT);
+            this._volumetricLightScatteringRTT = new BABYLON.RenderTargetTexture("volumetricLightScatteringMap", { width: engine.getRenderWidth() * ratio, height: engine.getRenderHeight() * ratio }, scene, false, true, BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT);
+            this._volumetricLightScatteringRTT.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE;
+            this._volumetricLightScatteringRTT.wrapV = BABYLON.Texture.CLAMP_ADDRESSMODE;
+            this._volumetricLightScatteringRTT.renderList = null;
+            this._volumetricLightScatteringRTT.renderParticles = false;
+            scene.customRenderTargets.push(this._volumetricLightScatteringRTT);
             // Custom render function for submeshes
             var renderSubMesh = function (subMesh) {
                 var mesh = subMesh.getRenderingMesh();
+                if (_this._meshExcluded(mesh)) {
+                    return;
+                }
                 var scene = mesh.getScene();
                 var engine = scene.getEngine();
                 // Culling
@@ -103,35 +171,38 @@ var BABYLON;
                 }
                 var hardwareInstancedRendering = (engine.getCaps().instancedArrays !== null) && (batch.visibleInstances[subMesh._id] !== null);
                 if (_this.isReady(subMesh, hardwareInstancedRendering)) {
-                    engine.enableEffect(_this._godRaysPass);
-                    mesh._bind(subMesh, _this._godRaysPass, BABYLON.Material.TriangleFillMode);
+                    engine.enableEffect(_this._volumetricLightScatteringPass);
+                    mesh._bind(subMesh, _this._volumetricLightScatteringPass, BABYLON.Material.TriangleFillMode);
                     var material = subMesh.getMaterial();
-                    _this._godRaysPass.setMatrix("viewProjection", scene.getTransformMatrix());
+                    _this._volumetricLightScatteringPass.setMatrix("viewProjection", scene.getTransformMatrix());
                     // Alpha test
-                    if (material && (mesh === _this.mesh || material.needAlphaTesting())) {
+                    if (material && (mesh === _this.mesh || material.needAlphaTesting() || material.opacityTexture !== undefined)) {
                         var alphaTexture = material.getAlphaTestTexture();
-                        _this._godRaysPass.setTexture("diffuseSampler", alphaTexture);
-                        _this._godRaysPass.setMatrix("diffuseMatrix", alphaTexture.getTextureMatrix());
+                        _this._volumetricLightScatteringPass.setTexture("diffuseSampler", alphaTexture);
+                        if (_this.mesh.material && alphaTexture)
+                            _this._volumetricLightScatteringPass.setMatrix("diffuseMatrix", alphaTexture.getTextureMatrix());
+                        if (material.opacityTexture !== undefined)
+                            _this._volumetricLightScatteringPass.setTexture("opacitySampler", material.opacityTexture);
                     }
                     // Bones
                     if (mesh.useBones) {
-                        _this._godRaysPass.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                        _this._volumetricLightScatteringPass.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
                     }
                     // Draw
-                    mesh._processRendering(subMesh, _this._godRaysPass, BABYLON.Material.TriangleFillMode, batch, hardwareInstancedRendering, function (isInstance, world) { return _this._godRaysPass.setMatrix("world", world); });
+                    mesh._processRendering(subMesh, _this._volumetricLightScatteringPass, BABYLON.Material.TriangleFillMode, batch, hardwareInstancedRendering, function (isInstance, world) { return _this._volumetricLightScatteringPass.setMatrix("world", world); });
                 }
             };
             // Render target texture callbacks
             var savedSceneClearColor;
             var sceneClearColor = new BABYLON.Color3(0.0, 0.0, 0.0);
-            this._godRaysRTT.onBeforeRender = function () {
+            this._volumetricLightScatteringRTT.onBeforeRender = function () {
                 savedSceneClearColor = scene.clearColor;
                 scene.clearColor = sceneClearColor;
             };
-            this._godRaysRTT.onAfterRender = function () {
+            this._volumetricLightScatteringRTT.onAfterRender = function () {
                 scene.clearColor = savedSceneClearColor;
             };
-            this._godRaysRTT.customRenderFunction = function (opaqueSubMeshes, alphaTestSubMeshes) {
+            this._volumetricLightScatteringRTT.customRenderFunction = function (opaqueSubMeshes, alphaTestSubMeshes, transparentSubMeshes) {
                 var index;
                 for (index = 0; index < opaqueSubMeshes.length; index++) {
                     renderSubMesh(opaqueSubMeshes.data[index]);
@@ -139,18 +210,34 @@ var BABYLON;
                 for (index = 0; index < alphaTestSubMeshes.length; index++) {
                     renderSubMesh(alphaTestSubMeshes.data[index]);
                 }
+                for (index = 0; index < transparentSubMeshes.length; index++) {
+                    renderSubMesh(transparentSubMeshes.data[index]);
+                }
             };
         };
-        GodRaysPostProcess.prototype._updateScreenCoordinates = function (scene) {
+        VolumetricLightScatteringPostProcess.prototype._updateMeshScreenCoordinates = function (scene) {
             var transform = scene.getTransformMatrix();
-            var pos = BABYLON.Vector3.Project(this.mesh.position, BABYLON.Matrix.Identity(), transform, this._viewPort);
+            var pos = BABYLON.Vector3.Project(this.useCustomMeshPosition ? this._customMeshPosition : this.mesh.position, BABYLON.Matrix.Identity(), transform, this._viewPort);
             this._screenCoordinates.x = pos.x / this._viewPort.width;
             this._screenCoordinates.y = pos.y / this._viewPort.height;
             if (this.invert)
                 this._screenCoordinates.y = 1.0 - this._screenCoordinates.y;
         };
-        return GodRaysPostProcess;
+        // Static methods
+        /**
+        * Creates a default mesh for the Volumeric Light Scattering post-process
+        * @param {string} The mesh name
+        * @param {BABYLON.Scene} The scene where to create the mesh
+        * @return {BABYLON.Mesh} the default mesh
+        */
+        VolumetricLightScatteringPostProcess.CreateDefaultMesh = function (name, scene) {
+            var mesh = BABYLON.Mesh.CreatePlane(name, 1, scene);
+            mesh.billboardMode = BABYLON.AbstractMesh.BILLBOARDMODE_ALL;
+            mesh.material = new BABYLON.StandardMaterial(name + "Material", scene);
+            return mesh;
+        };
+        return VolumetricLightScatteringPostProcess;
     })(BABYLON.PostProcess);
-    BABYLON.GodRaysPostProcess = GodRaysPostProcess;
+    BABYLON.VolumetricLightScatteringPostProcess = VolumetricLightScatteringPostProcess;
 })(BABYLON || (BABYLON = {}));
 //# sourceMappingURL=babylon.volumetricLightScatteringPostProcess.js.map

+ 86 - 44
Babylon/PostProcess/babylon.volumetricLightScatteringPostProcess.ts

@@ -1,18 +1,19 @@
 module BABYLON {
+    // Inspired by http://http.developer.nvidia.com/GPUGems3/gpugems3_ch13.html
     export class VolumetricLightScatteringPostProcess extends PostProcess {
         // Members
-        private _godRaysPass: Effect;
-        private _godRaysRTT: RenderTargetTexture;
+        private _volumetricLightScatteringPass: Effect;
+        private _volumetricLightScatteringRTT: RenderTargetTexture;
         private _viewPort: Viewport;
         private _screenCoordinates: Vector2 = Vector2.Zero();
         private _cachedDefines: string;
-        private _customLightPosition: Vector3;
+        private _customMeshPosition: Vector3;
 
         /**
         * Set if the post-process should use a custom position for the light source (true) or the internal mesh position (false)
         * @type {boolean}
         */
-        public useCustomLightPosition: boolean = false;
+        public useCustomMeshPosition: boolean = false;
         /**
         * If the post-process should inverse the light scattering direction
         * @type {boolean}
@@ -25,6 +26,16 @@
         public mesh: Mesh;
 
         /**
+        * Array containing the excluded meshes not rendered in the internal pass
+        */
+        public excludedMeshes = new Array<AbstractMesh>();
+
+        public exposure = 0.3;
+        public decay = 0.96815;
+        public weight = 0.58767;
+        public density = 0.926;
+
+        /**
          * @constructor
          * @param {string} name - The post-process name
          * @param {number} ratio - The size of the postprocesses (0.5 means that your postprocess will have a width = canvas.width 0.5 and a height = canvas.height 0.5)
@@ -34,8 +45,8 @@
          * @param {BABYLON.Engine} engine - The babylon engine
          * @param {boolean} reusable - If the post-process is reusable
          */
-        constructor(name: string, ratio: number, camera: Camera, mesh?: Mesh, samplingMode?: number, engine?: Engine, reusable?: boolean) {
-            super(name, "volumetricLightScattering", ["lightPositionOnScreen"], ["lightScatteringSampler"], ratio, camera, samplingMode, engine, reusable);
+        constructor(name: string, ratio: number, camera: Camera, mesh?: Mesh, samples: number = 100, samplingMode: number = Texture.BILINEAR_SAMPLINGMODE, engine?: Engine, reusable?: boolean) {
+            super(name, "volumetricLightScattering", ["decay", "exposure", "weight", "meshPositionOnScreen", "density"], ["lightScatteringSampler"], ratio, camera, samplingMode, engine, reusable, "#define NUM_SAMPLES " + samples);
             var scene = camera.getScene();
 
             this._viewPort = new Viewport(0, 0, 1, 1).toGlobal(scene.getEngine());
@@ -44,13 +55,17 @@
             this.mesh = (mesh !== null) ? mesh : VolumetricLightScatteringPostProcess.CreateDefaultMesh("VolumetricLightScatteringMesh", scene);
 
             // Configure
-            this._createPass(scene);
+            this._createPass(scene, 0.5);
 
             this.onApply = (effect: Effect) => {
-                this._updateScreenCoordinates(scene);
-
-                effect.setTexture("lightScatteringSampler", this._godRaysRTT);
-                effect.setVector2("lightPositionOnScreen", this._screenCoordinates);
+                this._updateMeshScreenCoordinates(scene);
+
+                effect.setTexture("lightScatteringSampler", this._volumetricLightScatteringRTT);
+                effect.setFloat("exposure", this.exposure);
+                effect.setFloat("decay", this.decay);
+                effect.setFloat("weight", this.weight);
+                effect.setFloat("density", this.density);
+                effect.setVector2("meshPositionOnScreen", this._screenCoordinates);
             };
         }
 
@@ -59,7 +74,7 @@
 
             var defines = [];
             var attribs = [VertexBuffer.PositionKind];
-            var material = subMesh.getMaterial();
+            var material: any = subMesh.getMaterial();
 
             // Render this.mesh as default
             if (mesh === this.mesh) {
@@ -71,6 +86,9 @@
                 if (material.needAlphaTesting() || mesh === this.mesh)
                     defines.push("#define ALPHATEST");
 
+                if (material.opacityTexture !== undefined)
+                    defines.push("#define OPACITY");
+
                 if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {
                     attribs.push(VertexBuffer.UVKind);
                     defines.push("#define UV1");
@@ -102,37 +120,42 @@
             var join = defines.join("\n");
             if (this._cachedDefines !== join) {
                 this._cachedDefines = join;
-                this._godRaysPass = mesh.getScene().getEngine().createEffect(
+                this._volumetricLightScatteringPass = mesh.getScene().getEngine().createEffect(
                     { vertexElement: "depth", fragmentElement: "volumetricLightScatteringPass" },
                     attribs,
                     ["world", "mBones", "viewProjection", "diffuseMatrix", "far"],
-                    ["diffuseSampler"], join);
+                    ["diffuseSampler", "opacitySampler"], join);
             }
 
-            return this._godRaysPass.isReady();
+            return this._volumetricLightScatteringPass.isReady();
         }
 
         /**
          * Sets the new light position for light scattering effect
          * @param {BABYLON.Vector3} The new custom light position
          */
-        public setLightPosition(position: Vector3): void {
-            this._customLightPosition = position;
+        public setCustomMeshPosition(position: Vector3): void {
+            this._customMeshPosition = position;
         }
 
         /**
          * Returns the light position for light scattering effect
          * @return {BABYLON.Vector3} The custom light position
          */
-        public getLightPosition(): Vector3 {
-            return this._customLightPosition;
+        public getCustomMeshPosition(): Vector3 {
+            return this._customMeshPosition;
         }
 
         /**
          * Disposes the internal assets and detaches the post-process from the camera
          */
         public dispose(camera: Camera): void {
-            this._godRaysRTT.dispose();
+            var rttIndex = camera.getScene().customRenderTargets.indexOf(this._volumetricLightScatteringRTT);
+            if (rttIndex !== -1) {
+                camera.getScene().customRenderTargets.splice(rttIndex, 1);
+            }
+                
+            this._volumetricLightScatteringRTT.dispose();
             super.dispose(camera);
         }
 
@@ -141,23 +164,35 @@
          * @return {BABYLON.RenderTargetTexture} The render target texture used by the post-process
          */
         public getPass(): RenderTargetTexture {
-            return this._godRaysRTT;
+            return this._volumetricLightScatteringRTT;
         }
 
         // Private methods
-        private _createPass(scene: Scene): void {
+        private _meshExcluded(mesh: AbstractMesh) {
+            if (this.excludedMeshes.length > 0 && this.excludedMeshes.indexOf(mesh) !== -1) {
+                return true;
+            }
+
+            return false;
+        }
+
+        private _createPass(scene: Scene, ratio: number): void {
             var engine = scene.getEngine();
 
-            this._godRaysRTT = new RenderTargetTexture("volumetricLightScatteringMap", { width: engine.getRenderWidth(), height: engine.getRenderHeight() }, scene, false, true, Engine.TEXTURETYPE_UNSIGNED_INT);
-            this._godRaysRTT.wrapU = Texture.CLAMP_ADDRESSMODE;
-            this._godRaysRTT.wrapV = Texture.CLAMP_ADDRESSMODE;
-            this._godRaysRTT.renderList = null;
-            this._godRaysRTT.renderParticles = false;
-            scene.customRenderTargets.push(this._godRaysRTT);
+            this._volumetricLightScatteringRTT = new RenderTargetTexture("volumetricLightScatteringMap", { width: engine.getRenderWidth() * ratio, height: engine.getRenderHeight() * ratio }, scene, false, true, Engine.TEXTURETYPE_UNSIGNED_INT);
+            this._volumetricLightScatteringRTT.wrapU = Texture.CLAMP_ADDRESSMODE;
+            this._volumetricLightScatteringRTT.wrapV = Texture.CLAMP_ADDRESSMODE;
+            this._volumetricLightScatteringRTT.renderList = null;
+            this._volumetricLightScatteringRTT.renderParticles = false;
+            scene.customRenderTargets.push(this._volumetricLightScatteringRTT);
 
             // Custom render function for submeshes
             var renderSubMesh = (subMesh: SubMesh): void => {
                 var mesh = subMesh.getRenderingMesh();
+                if (this._meshExcluded(mesh)) {
+                    return;
+                }
+
                 var scene = mesh.getScene();
                 var engine = scene.getEngine();
 
@@ -174,27 +209,31 @@
                 var hardwareInstancedRendering = (engine.getCaps().instancedArrays !== null) && (batch.visibleInstances[subMesh._id] !== null);
 
                 if (this.isReady(subMesh, hardwareInstancedRendering)) {
-                    engine.enableEffect(this._godRaysPass);
-                    mesh._bind(subMesh, this._godRaysPass, Material.TriangleFillMode);
-                    var material = subMesh.getMaterial();
+                    engine.enableEffect(this._volumetricLightScatteringPass);
+                    mesh._bind(subMesh, this._volumetricLightScatteringPass, Material.TriangleFillMode);
+                    var material: any = subMesh.getMaterial();
 
-                    this._godRaysPass.setMatrix("viewProjection", scene.getTransformMatrix());
+                    this._volumetricLightScatteringPass.setMatrix("viewProjection", scene.getTransformMatrix());
 
                     // Alpha test
-                    if (material && (mesh === this.mesh || material.needAlphaTesting())) {
+                    if (material && (mesh === this.mesh || material.needAlphaTesting() || material.opacityTexture !== undefined)) {
                         var alphaTexture = material.getAlphaTestTexture();
-                        this._godRaysPass.setTexture("diffuseSampler", alphaTexture);
-                        this._godRaysPass.setMatrix("diffuseMatrix", alphaTexture.getTextureMatrix());
+                        this._volumetricLightScatteringPass.setTexture("diffuseSampler", alphaTexture);
+                        if (this.mesh.material && alphaTexture)
+                            this._volumetricLightScatteringPass.setMatrix("diffuseMatrix", alphaTexture.getTextureMatrix());
+
+                        if (material.opacityTexture !== undefined)
+                            this._volumetricLightScatteringPass.setTexture("opacitySampler", material.opacityTexture);
                     }
 
                     // Bones
                     if (mesh.useBones) {
-                        this._godRaysPass.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                        this._volumetricLightScatteringPass.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
                     }
 
                     // Draw
-                    mesh._processRendering(subMesh, this._godRaysPass, Material.TriangleFillMode, batch, hardwareInstancedRendering,
-                        (isInstance, world) => this._godRaysPass.setMatrix("world", world));
+                    mesh._processRendering(subMesh, this._volumetricLightScatteringPass, Material.TriangleFillMode, batch, hardwareInstancedRendering,
+                        (isInstance, world) => this._volumetricLightScatteringPass.setMatrix("world", world));
                 }
             };
 
@@ -202,16 +241,16 @@
             var savedSceneClearColor: Color3;
             var sceneClearColor = new Color3(0.0, 0.0, 0.0);
 
-            this._godRaysRTT.onBeforeRender = (): void => {
+            this._volumetricLightScatteringRTT.onBeforeRender = (): void => {
                 savedSceneClearColor = scene.clearColor;
                 scene.clearColor = sceneClearColor;
             };
 
-            this._godRaysRTT.onAfterRender = (): void => {
+            this._volumetricLightScatteringRTT.onAfterRender = (): void => {
                 scene.clearColor = savedSceneClearColor;
             };
 
-            this._godRaysRTT.customRenderFunction = (opaqueSubMeshes: SmartArray<SubMesh>, alphaTestSubMeshes: SmartArray<SubMesh>): void => {
+            this._volumetricLightScatteringRTT.customRenderFunction = (opaqueSubMeshes: SmartArray<SubMesh>, alphaTestSubMeshes: SmartArray<SubMesh>, transparentSubMeshes: SmartArray<SubMesh>): void => {
                 var index;
 
                 for (index = 0; index < opaqueSubMeshes.length; index++) {
@@ -221,12 +260,16 @@
                 for (index = 0; index < alphaTestSubMeshes.length; index++) {
                     renderSubMesh(alphaTestSubMeshes.data[index]);
                 }
+
+                for (index = 0; index < transparentSubMeshes.length; index++) {
+                    renderSubMesh(transparentSubMeshes.data[index]);
+                }
             };
         }
 
-        private _updateScreenCoordinates(scene: Scene): void {
+        private _updateMeshScreenCoordinates(scene: Scene): void {
             var transform = scene.getTransformMatrix();
-            var pos = Vector3.Project(this.useCustomLightPosition ? this._customLightPosition : this.mesh.position, Matrix.Identity(), transform, this._viewPort);
+            var pos = Vector3.Project(this.useCustomMeshPosition ? this._customMeshPosition : this.mesh.position, Matrix.Identity(), transform, this._viewPort);
 
             this._screenCoordinates.x = pos.x / this._viewPort.width;
             this._screenCoordinates.y = pos.y / this._viewPort.height;
@@ -246,7 +289,6 @@
             var mesh = Mesh.CreatePlane(name, 1, scene);
             mesh.billboardMode = AbstractMesh.BILLBOARDMODE_ALL;
             mesh.material = new StandardMaterial(name + "Material", scene);
-
             return mesh;
         }
     }

+ 9 - 16
Babylon/Shaders/volumetricLightScattering.fragment.fx

@@ -1,35 +1,28 @@
-// Inspired by http://http.developer.nvidia.com/GPUGems3/gpugems3_ch13.html
-
-#ifdef GL_ES
-precision mediump float;
+#ifdef GL_ES
+precision highp float;
 #endif
 
 uniform sampler2D textureSampler;
 uniform sampler2D lightScatteringSampler;
 
-uniform vec2 lightPositionOnScreen;
+uniform float decay;
+uniform float exposure;
+uniform float weight;
+uniform float density;
+uniform vec2 meshPositionOnScreen;
 
 varying vec2 vUV;
 
 void main(void) {
-	
-    float decay = 0.96815;
-    float exposure = 0.3;
-    float density = 0.926;
-    float weight = 0.58767;
-
-    const int NUM_SAMPLES = 100;
-
     vec2 tc = vUV;
-    vec2 deltaTexCoord = (tc - lightPositionOnScreen.xy);
+	vec2 deltaTexCoord = (tc - meshPositionOnScreen.xy);
     deltaTexCoord *= 1.0 / float(NUM_SAMPLES) * density;
 
     float illuminationDecay = 1.0;
 
 	vec4 color = texture2D(lightScatteringSampler, tc) * 0.4;
 
-    for(int i=0; i < NUM_SAMPLES; i++)
-    {
+    for(int i=0; i < NUM_SAMPLES; i++) {
         tc -= deltaTexCoord;
 		vec4 sample = texture2D(lightScatteringSampler, tc) * 0.4;
         sample *= illuminationDecay * weight;

+ 21 - 5
Babylon/Shaders/volumetricLightScatteringPass.fragment.fx

@@ -1,22 +1,38 @@
 #ifdef GL_ES
-precision mediump float;
+precision highp float;
 #endif
 
-#if defined(ALPHATEST) || defined(BASIC_RENDER)
+#if defined(ALPHATEST) || defined(BASIC_RENDER) || defined(OPACITY)
 varying vec2 vUV;
+#endif
+
+#if defined(ALPHATEST) || defined(BASIC_RENDER)
 uniform sampler2D diffuseSampler;
 #endif
 
+#if defined(OPACITY)
+uniform sampler2D opacitySampler;
+#endif
+
 void main(void)
 {
+#if defined(ALPHATEST) || defined(OPACITY) || defined(BASIC_RENDER)
+	vec4 diffuseColor = texture2D(diffuseSampler, vUV);
+#endif
+
 #ifdef ALPHATEST
-	if (texture2D(diffuseSampler, vUV).a < 0.4)
+	if (diffuseColor.a < 0.4)
 		discard;
 #endif
 
 #ifdef BASIC_RENDER
-	gl_FragColor = texture2D(diffuseSampler, vUV);
+#ifdef OPACITY
+	gl_FragColor = diffuseColor * texture2D(opacitySampler, vUV);
+#else
+	gl_FragColor = diffuseColor;
+#endif
 #else
 	gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
 #endif
-}
+
+}

+ 1 - 0
Babylon/Tools/babylon.filesInput.js

@@ -77,6 +77,7 @@ var BABYLON;
                         case "image/vnd.ms-dds":
                         case "audio/wav":
                         case "audio/x-wav":
+                        case "audio/mp3":
                         case "audio/mpeg":
                         case "audio/mpeg3":
                         case "audio/x-mpeg-3":

+ 8 - 8
Babylon/Tools/babylon.tools.js

@@ -29,7 +29,7 @@ var BABYLON;
             var result = "";
             var child = element.firstChild;
             while (child) {
-                if (child.nodeType == 3) {
+                if (child.nodeType === 3) {
                     result += child.textContent;
                 }
                 child = child.nextSibling;
@@ -129,7 +129,7 @@ var BABYLON;
         Tools.LoadImage = function (url, onload, onerror, database) {
             url = Tools.CleanUrl(url);
             var img = new Image();
-            if (url.substr(0, 5) != "data:")
+            if (url.substr(0, 5) !== "data:")
                 img.crossOrigin = 'anonymous';
             img.onload = function () {
                 onload(img);
@@ -184,8 +184,8 @@ var BABYLON;
                 }
                 request.onprogress = progressCallBack;
                 request.onreadystatechange = function () {
-                    if (request.readyState == 4) {
-                        if (request.status == 200 || BABYLON.Tools.ValidateXHRData(request, !useArrayBuffer ? 1 : 6)) {
+                    if (request.readyState === 4) {
+                        if (request.status === 200 || Tools.ValidateXHRData(request, !useArrayBuffer ? 1 : 6)) {
                             callback(!useArrayBuffer ? request.responseText : request.response);
                         }
                         else {
@@ -205,7 +205,7 @@ var BABYLON;
             };
             if (url.indexOf("file:") !== -1) {
                 var fileName = url.substring(5);
-                BABYLON.Tools.ReadFile(BABYLON.FilesInput.FilesToLoad[fileName], callback, progressCallBack, true);
+                Tools.ReadFile(BABYLON.FilesInput.FilesToLoad[fileName], callback, progressCallBack, true);
             }
             else {
                 // Caching all files
@@ -286,10 +286,10 @@ var BABYLON;
                 }
                 var sourceValue = source[prop];
                 var typeOfSourceValue = typeof sourceValue;
-                if (typeOfSourceValue == "function") {
+                if (typeOfSourceValue === "function") {
                     continue;
                 }
-                if (typeOfSourceValue == "object") {
+                if (typeOfSourceValue === "object") {
                     if (sourceValue instanceof Array) {
                         destination[prop] = [];
                         if (sourceValue.length > 0) {
@@ -468,7 +468,7 @@ var BABYLON;
                 if (dataType & 4) {
                     // Check for the "DDS" magic number
                     var ddsHeader = new Uint8Array(xhr.response, 0, 3);
-                    if (ddsHeader[0] == 68 && ddsHeader[1] == 68 && ddsHeader[2] == 83) {
+                    if (ddsHeader[0] === 68 && ddsHeader[1] === 68 && ddsHeader[2] === 83) {
                         return true;
                     }
                     else {

+ 2 - 2
Babylon/babylon.engine.js

@@ -725,7 +725,7 @@ var BABYLON;
             this._measureFps();
         };
         Engine.prototype.endFrame = function () {
-            this.flushFramebuffer();
+            //this.flushFramebuffer();
         };
         /**
          * resize the view according to the canvas' size.
@@ -765,7 +765,7 @@ var BABYLON;
             this._gl.bindFramebuffer(this._gl.FRAMEBUFFER, null);
         };
         Engine.prototype.flushFramebuffer = function () {
-            //   this._gl.flush();
+            this._gl.flush();
         };
         Engine.prototype.restoreDefaultFramebuffer = function () {
             this._currentRenderTarget = null;

+ 2 - 0
Babylon/babylon.scene.js

@@ -1060,6 +1060,7 @@ var BABYLON;
             // Customs render targets
             var beforeRenderTargetDate = BABYLON.Tools.Now;
             var engine = this.getEngine();
+            var currentActiveCamera = this.activeCamera;
             if (this.renderTargetsEnabled) {
                 BABYLON.Tools.StartPerformanceCounter("Custom render targets", this.customRenderTargets.length > 0);
                 for (var customIndex = 0; customIndex < this.customRenderTargets.length; customIndex++) {
@@ -1083,6 +1084,7 @@ var BABYLON;
                 engine.restoreDefaultFramebuffer();
             }
             this._renderTargetsDuration += BABYLON.Tools.Now - beforeRenderTargetDate;
+            this.activeCamera = currentActiveCamera;
             // Procedural textures
             if (this.proceduralTexturesEnabled) {
                 BABYLON.Tools.StartPerformanceCounter("Procedural textures", this._proceduralTextures.length > 0);

+ 2 - 0
Babylon/babylon.scene.ts

@@ -1361,6 +1361,7 @@
             // Customs render targets
             var beforeRenderTargetDate = Tools.Now;
             var engine = this.getEngine();
+            var currentActiveCamera = this.activeCamera;
             if (this.renderTargetsEnabled) {
                 Tools.StartPerformanceCounter("Custom render targets", this.customRenderTargets.length > 0);
                 for (var customIndex = 0; customIndex < this.customRenderTargets.length; customIndex++) {
@@ -1391,6 +1392,7 @@
                 engine.restoreDefaultFramebuffer();
             }
             this._renderTargetsDuration += Tools.Now - beforeRenderTargetDate;
+            this.activeCamera = currentActiveCamera;
 
             // Procedural textures
             if (this.proceduralTexturesEnabled) {

Разлика између датотеке није приказан због своје велике величине
+ 104 - 51
babylon.2.0-beta.debug.js


Разлика између датотеке није приказан због своје велике величине
+ 14 - 14
babylon.2.0-beta.js