瀏覽代碼

Updating local merge

Raanan Weber 10 年之前
父節點
當前提交
97612492d8
共有 30 個文件被更改,包括 424 次插入258 次删除
  1. 2 0
      Babylon/Audio/babylon.sound.js
  2. 2 0
      Babylon/Audio/babylon.sound.ts
  3. 3 1
      Babylon/Audio/babylon.soundtrack.js
  4. 4 1
      Babylon/Audio/babylon.soundtrack.ts
  5. 2 1
      Babylon/Cameras/babylon.gamepadCamera.js
  6. 3 1
      Babylon/Cameras/babylon.gamepadCamera.ts
  7. 9 9
      Babylon/Culling/babylon.BoundingBox.ts
  8. 1 1
      Babylon/Culling/babylon.boundingBox.js
  9. 7 2
      Babylon/Loading/Plugins/babylon.babylonFileLoader.js
  10. 7 2
      Babylon/Loading/Plugins/babylon.babylonFileLoader.ts
  11. 3 6
      Babylon/Materials/Textures/babylon.renderTargetTexture.js
  12. 4 9
      Babylon/Materials/Textures/babylon.renderTargetTexture.ts
  13. 2 2
      Babylon/PostProcess/babylon.postProcess.js
  14. 2 2
      Babylon/PostProcess/babylon.postProcess.ts
  15. 4 1
      Babylon/PostProcess/babylon.ssaoRenderingPipeline.js
  16. 4 1
      Babylon/PostProcess/babylon.ssaoRenderingPipeline.ts
  17. 73 37
      Babylon/PostProcess/babylon.volumetricLightScatteringPostProcess.js
  18. 89 47
      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. 1 0
      Babylon/Tools/babylon.filesInput.ts
  23. 8 8
      Babylon/Tools/babylon.tools.js
  24. 17 18
      Babylon/Tools/babylon.tools.ts
  25. 2 2
      Babylon/babylon.engine.js
  26. 2 2
      Babylon/babylon.engine.ts
  27. 2 0
      Babylon/babylon.scene.js
  28. 2 0
      Babylon/babylon.scene.ts
  29. 121 67
      babylon.2.0-beta.debug.js
  30. 17 17
      babylon.2.0-beta.js

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

@@ -90,6 +90,8 @@ var BABYLON;
                 }
                 }
             }
             }
             else {
             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) {
                 if (!BABYLON.Engine.audioEngine.WarnedWebAudioUnsupported) {
                     BABYLON.Tools.Error("Web Audio is not supported by your browser.");
                     BABYLON.Tools.Error("Web Audio is not supported by your browser.");
                     BABYLON.Engine.audioEngine.WarnedWebAudioUnsupported = true;
                     BABYLON.Engine.audioEngine.WarnedWebAudioUnsupported = true;

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

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

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

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

+ 4 - 1
Babylon/Audio/babylon.soundtrack.ts

@@ -42,7 +42,9 @@
         }
         }
 
 
         public AddSound(sound: BABYLON.Sound) {
         public AddSound(sound: BABYLON.Sound) {
-            sound.connectToSoundTrackAudioNode(this._trackGain);
+            if (Engine.audioEngine.canUseWebAudio) {
+                sound.connectToSoundTrackAudioNode(this._trackGain);
+            }
             if (sound.soundTrackId) {
             if (sound.soundTrackId) {
                 if (sound.soundTrackId === -1) {
                 if (sound.soundTrackId === -1) {
                     this._scene.mainSoundTrack.RemoveSound(sound);
                     this._scene.mainSoundTrack.RemoveSound(sound);
@@ -51,6 +53,7 @@
                     this._scene.soundTracks[sound.soundTrackId].RemoveSound(sound);
                     this._scene.soundTracks[sound.soundTrackId].RemoveSound(sound);
                 }
                 }
             }
             }
+
             this.soundCollection.push(sound);
             this.soundCollection.push(sound);
             sound.soundTrackId = this.id;
             sound.soundTrackId = this.id;
         }
         }

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

@@ -40,7 +40,8 @@ var BABYLON;
             RSValues.y = Math.abs(normalizedRY) > 0.001 ? 0 + normalizedRY : 0;
             RSValues.y = Math.abs(normalizedRY) > 0.001 ? 0 + normalizedRY : 0;
             ;
             ;
             var cameraTransform = BABYLON.Matrix.RotationYawPitchRoll(this.rotation.y, this.rotation.x, 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.cameraDirection = this.cameraDirection.add(deltaTransform);
             this.cameraRotation = this.cameraRotation.add(new BABYLON.Vector2(RSValues.y, RSValues.x));
             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;;
             RSValues.y = Math.abs(normalizedRY) > 0.001 ? 0 + normalizedRY : 0;;
 
 
             var cameraTransform = BABYLON.Matrix.RotationYawPitchRoll(this.rotation.y, this.rotation.x, 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.cameraDirection = this.cameraDirection.add(deltaTransform);
             this.cameraRotation = this.cameraRotation.add(new BABYLON.Vector2(RSValues.y, RSValues.x));
             this.cameraRotation = this.cameraRotation.add(new BABYLON.Vector2(RSValues.y, RSValues.x));
         }
         }

+ 9 - 9
Babylon/Culling/babylon.BoundingBox.ts

@@ -36,16 +36,16 @@
             // OBB
             // OBB
             this.center = this.maximum.add(this.minimum).scale(0.5);
             this.center = this.maximum.add(this.minimum).scale(0.5);
             this.extendSize = this.maximum.subtract(this.minimum).scale(0.5);
             this.extendSize = this.maximum.subtract(this.minimum).scale(0.5);
-            this.directions = [BABYLON.Vector3.Zero(), BABYLON.Vector3.Zero(), BABYLON.Vector3.Zero()];
+            this.directions = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];
 
 
             // World
             // World
             for (var index = 0; index < this.vectors.length; index++) {
             for (var index = 0; index < this.vectors.length; index++) {
-                this.vectorsWorld[index] = BABYLON.Vector3.Zero();
+                this.vectorsWorld[index] = Vector3.Zero();
             }
             }
-            this.minimumWorld = BABYLON.Vector3.Zero();
-            this.maximumWorld = BABYLON.Vector3.Zero();
+            this.minimumWorld = Vector3.Zero();
+            this.maximumWorld = Vector3.Zero();
 
 
-            this._update(BABYLON.Matrix.Identity());
+            this._update(Matrix.Identity());
         }
         }
 
 
         // Methods
         // Methods
@@ -59,7 +59,7 @@
 
 
             for (var index = 0; index < this.vectors.length; index++) {
             for (var index = 0; index < this.vectors.length; index++) {
                 var v = this.vectorsWorld[index];
                 var v = this.vectorsWorld[index];
-                BABYLON.Vector3.TransformCoordinatesToRef(this.vectors[index], world, v);
+                Vector3.TransformCoordinatesToRef(this.vectors[index], world, v);
 
 
                 if (v.x < this.minimumWorld.x)
                 if (v.x < this.minimumWorld.x)
                     this.minimumWorld.x = v.x;
                     this.minimumWorld.x = v.x;
@@ -142,8 +142,8 @@
         }
         }
 
 
         public static IntersectsSphere(minPoint: Vector3, maxPoint: Vector3, sphereCenter: Vector3, sphereRadius: number): boolean {
         public static IntersectsSphere(minPoint: Vector3, maxPoint: Vector3, sphereCenter: Vector3, sphereRadius: number): boolean {
-            var vector = BABYLON.Vector3.Clamp(sphereCenter, minPoint, maxPoint);
-            var num = BABYLON.Vector3.DistanceSquared(sphereCenter, vector);
+            var vector = Vector3.Clamp(sphereCenter, minPoint, maxPoint);
+            var num = Vector3.DistanceSquared(sphereCenter, vector);
             return (num <= (sphereRadius * sphereRadius));
             return (num <= (sphereRadius * sphereRadius));
         }
         }
 
 
@@ -169,7 +169,7 @@
                         break;
                         break;
                     }
                     }
                 }
                 }
-                if (inCount == 0)
+                if (inCount === 0)
                     return false;
                     return false;
             }
             }
             return true;
             return true;

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

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

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

@@ -1165,10 +1165,15 @@ var BABYLON;
                     }
                     }
                 }
                 }
                 // Sounds
                 // Sounds
-                if (parsedData.sounds && BABYLON.Engine.audioEngine.canUseWebAudio) {
+                if (parsedData.sounds) {
                     for (index = 0; index < parsedData.sounds.length; index++) {
                     for (index = 0; index < parsedData.sounds.length; index++) {
                         var parsedSound = parsedData.sounds[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++) {
                 for (index = 0; index < scene.meshes.length; index++) {

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

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

+ 3 - 6
Babylon/Materials/Textures/babylon.renderTargetTexture.js

@@ -81,9 +81,6 @@ var BABYLON;
         RenderTargetTexture.prototype.render = function (useCameraPostProcess) {
         RenderTargetTexture.prototype.render = function (useCameraPostProcess) {
             var scene = this.getScene();
             var scene = this.getScene();
             var engine = scene.getEngine();
             var engine = scene.getEngine();
-            if (!this.activeCamera) {
-                this.activeCamera = scene.activeCamera;
-            }
             if (this._waitingRenderList) {
             if (this._waitingRenderList) {
                 this.renderList = [];
                 this.renderList = [];
                 for (var index = 0; index < this._waitingRenderList.length; index++) {
                 for (var index = 0; index < this._waitingRenderList.length; index++) {
@@ -132,14 +129,14 @@ var BABYLON;
             if (useCameraPostProcess) {
             if (useCameraPostProcess) {
                 scene.postProcessManager._finalizeFrame(false, this._texture);
                 scene.postProcessManager._finalizeFrame(false, this._texture);
             }
             }
+            if (!this._doNotChangeAspectRatio) {
+                scene.updateTransformMatrix(true);
+            }
             if (this.onAfterRender) {
             if (this.onAfterRender) {
                 this.onAfterRender();
                 this.onAfterRender();
             }
             }
             // Unbind
             // Unbind
             engine.unBindFramebuffer(this._texture);
             engine.unBindFramebuffer(this._texture);
-            if (!this._doNotChangeAspectRatio) {
-                scene.updateTransformMatrix(true);
-            }
         };
         };
         RenderTargetTexture.prototype.clone = function () {
         RenderTargetTexture.prototype.clone = function () {
             var textureSize = this.getSize();
             var textureSize = this.getSize();

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

@@ -91,10 +91,6 @@
             var scene = this.getScene();
             var scene = this.getScene();
             var engine = scene.getEngine();
             var engine = scene.getEngine();
 
 
-            if (!this.activeCamera) {
-                this.activeCamera = scene.activeCamera;
-            }
-
             if (this._waitingRenderList) {
             if (this._waitingRenderList) {
                 this.renderList = [];
                 this.renderList = [];
                 for (var index = 0; index < this._waitingRenderList.length; index++) {
                 for (var index = 0; index < this._waitingRenderList.length; index++) {
@@ -147,7 +143,6 @@
             // Clear
             // Clear
             engine.clear(scene.clearColor, true, true);
             engine.clear(scene.clearColor, true, true);
 
 
-
             if (!this._doNotChangeAspectRatio) {
             if (!this._doNotChangeAspectRatio) {
                 scene.updateTransformMatrix(true);
                 scene.updateTransformMatrix(true);
             }
             }
@@ -159,16 +154,16 @@
                 scene.postProcessManager._finalizeFrame(false, this._texture);
                 scene.postProcessManager._finalizeFrame(false, this._texture);
             }
             }
 
 
+            if (!this._doNotChangeAspectRatio) {
+                scene.updateTransformMatrix(true);
+            }
+
             if (this.onAfterRender) {
             if (this.onAfterRender) {
                 this.onAfterRender();
                 this.onAfterRender();
             }
             }
 
 
             // Unbind
             // Unbind
             engine.unBindFramebuffer(this._texture);
             engine.unBindFramebuffer(this._texture);
-
-            if (!this._doNotChangeAspectRatio) {
-                scene.updateTransformMatrix(true);
-            }
         }
         }
 
 
         public clone(): RenderTargetTexture {
         public clone(): RenderTargetTexture {

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

@@ -1,7 +1,7 @@
 var BABYLON;
 var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
     var PostProcess = (function () {
     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.name = name;
             this.width = -1;
             this.width = -1;
             this.height = -1;
             this.height = -1;
@@ -22,7 +22,7 @@ var BABYLON;
             this._reusable = reusable || false;
             this._reusable = reusable || false;
             samplers = samplers || [];
             samplers = samplers || [];
             samplers.push("textureSampler");
             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 () {
         PostProcess.prototype.isReusable = function () {
             return this._reusable;
             return this._reusable;

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

@@ -17,7 +17,7 @@
         public _currentRenderTextureInd = 0;
         public _currentRenderTextureInd = 0;
         private _effect: Effect;
         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) {
             if (camera != null) {
                 this._camera = camera;
                 this._camera = camera;
                 this._scene = camera.getScene();
                 this._scene = camera.getScene();
@@ -38,7 +38,7 @@
             this._effect = this._engine.createEffect({ vertex: "postprocess", fragment: fragmentUrl },
             this._effect = this._engine.createEffect({ vertex: "postprocess", fragment: fragmentUrl },
                 ["position"],
                 ["position"],
                 parameters || [],
                 parameters || [],
-                samplers, "");
+                samplers, defines !== undefined ? defines : "");
         }
         }
 
 
         public isReusable(): boolean {
         public isReusable(): boolean {

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

@@ -94,7 +94,8 @@ var BABYLON;
         /**
         /**
          * Removes the internal pipeline assets and detatches the pipeline from the scene cameras
          * Removes the internal pipeline assets and detatches the pipeline from the scene cameras
          */
          */
-        SSAORenderingPipeline.prototype.dispose = function () {
+        SSAORenderingPipeline.prototype.dispose = function (disableDepthRender) {
+            if (disableDepthRender === void 0) { disableDepthRender = false; }
             this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._scene.cameras);
             this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._scene.cameras);
             this._originalColorPostProcess = undefined;
             this._originalColorPostProcess = undefined;
             this._ssaoPostProcess = undefined;
             this._ssaoPostProcess = undefined;
@@ -102,6 +103,8 @@ var BABYLON;
             this._blurVPostProcess = undefined;
             this._blurVPostProcess = undefined;
             this._ssaoCombinePostProcess = undefined;
             this._ssaoCombinePostProcess = undefined;
             this._randomTexture.dispose();
             this._randomTexture.dispose();
+            if (disableDepthRender)
+                this._scene.disableDepthRenderer();
         };
         };
         // Private Methods
         // Private Methods
         SSAORenderingPipeline.prototype._createSSAOPostProcess = function (ratio) {
         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
          * 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._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._scene.cameras);
 
 
             this._originalColorPostProcess = undefined;
             this._originalColorPostProcess = undefined;
@@ -105,6 +105,9 @@
             this._ssaoCombinePostProcess = undefined;
             this._ssaoCombinePostProcess = undefined;
 
 
             this._randomTexture.dispose();
             this._randomTexture.dispose();
+
+            if (disableDepthRender)
+                this._scene.disableDepthRenderer();
         }
         }
 
 
         // Private Methods
         // Private Methods

+ 73 - 37
Babylon/PostProcess/babylon.volumetricLightScatteringPostProcess.js

@@ -6,6 +6,7 @@ var __extends = this.__extends || function (d, b) {
 };
 };
 var BABYLON;
 var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
+    // Inspired by http://http.developer.nvidia.com/GPUGems3/gpugems3_ch13.html
     var VolumetricLightScatteringPostProcess = (function (_super) {
     var VolumetricLightScatteringPostProcess = (function (_super) {
         __extends(VolumetricLightScatteringPostProcess, _super);
         __extends(VolumetricLightScatteringPostProcess, _super);
         /**
         /**
@@ -18,45 +19,61 @@ var BABYLON;
          * @param {BABYLON.Engine} engine - The babylon engine
          * @param {BABYLON.Engine} engine - The babylon engine
          * @param {boolean} reusable - If the post-process is reusable
          * @param {boolean} reusable - If the post-process is reusable
          */
          */
-        function VolumetricLightScatteringPostProcess(name, ratio, camera, mesh, samplingMode, engine, reusable) {
+        function VolumetricLightScatteringPostProcess(name, ratio, camera, mesh, samples, samplingMode, engine, reusable) {
             var _this = this;
             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();
             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)
             * Set if the post-process should use a custom position for the light source (true) or the internal mesh position (false)
             * @type {boolean}
             * @type {boolean}
             */
             */
-            this.useCustomLightPosition = false;
+            this.useCustomMeshPosition = false;
             /**
             /**
             * If the post-process should inverse the light scattering direction
             * If the post-process should inverse the light scattering direction
             * @type {boolean}
             * @type {boolean}
             */
             */
             this.invert = true;
             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();
             var scene = camera.getScene();
             this._viewPort = new BABYLON.Viewport(0, 0, 1, 1).toGlobal(scene.getEngine());
             this._viewPort = new BABYLON.Viewport(0, 0, 1, 1).toGlobal(scene.getEngine());
             // Configure mesh
             // Configure mesh
             this.mesh = (mesh !== null) ? mesh : VolumetricLightScatteringPostProcess.CreateDefaultMesh("VolumetricLightScatteringMesh", scene);
             this.mesh = (mesh !== null) ? mesh : VolumetricLightScatteringPostProcess.CreateDefaultMesh("VolumetricLightScatteringMesh", scene);
             // Configure
             // Configure
-            this._createPass(scene);
+            this._createPass(scene, 0.5);
             this.onApply = function (effect) {
             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);
             };
             };
         }
         }
         VolumetricLightScatteringPostProcess.prototype.isReady = function (subMesh, useInstances) {
         VolumetricLightScatteringPostProcess.prototype.isReady = function (subMesh, useInstances) {
             var mesh = subMesh.getMesh();
             var mesh = subMesh.getMesh();
-            var scene = mesh.getScene();
             var defines = [];
             var defines = [];
             var attribs = [BABYLON.VertexBuffer.PositionKind];
             var attribs = [BABYLON.VertexBuffer.PositionKind];
             var material = subMesh.getMaterial();
             var material = subMesh.getMaterial();
             // Render this.mesh as default
             // Render this.mesh as default
-            if (mesh === this.mesh)
+            if (mesh === this.mesh) {
                 defines.push("#define BASIC_RENDER");
                 defines.push("#define BASIC_RENDER");
+            }
             // Alpha test
             // Alpha test
             if (material) {
             if (material) {
                 if (material.needAlphaTesting() || mesh === this.mesh)
                 if (material.needAlphaTesting() || mesh === this.mesh)
                     defines.push("#define ALPHATEST");
                     defines.push("#define ALPHATEST");
+                if (material.opacityTexture !== undefined)
+                    defines.push("#define OPACITY");
                 if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
                 if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
                     attribs.push(BABYLON.VertexBuffer.UVKind);
                     attribs.push(BABYLON.VertexBuffer.UVKind);
                     defines.push("#define UV1");
                     defines.push("#define UV1");
@@ -85,29 +102,33 @@ var BABYLON;
             var join = defines.join("\n");
             var join = defines.join("\n");
             if (this._cachedDefines !== join) {
             if (this._cachedDefines !== join) {
                 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
          * Sets the new light position for light scattering effect
          * @param {BABYLON.Vector3} The new custom light position
          * @param {BABYLON.Vector3} The new custom light position
          */
          */
-        VolumetricLightScatteringPostProcess.prototype.setLightPosition = function (position) {
-            this._customLightPosition = position;
+        VolumetricLightScatteringPostProcess.prototype.setCustomMeshPosition = function (position) {
+            this._customMeshPosition = position;
         };
         };
         /**
         /**
          * Returns the light position for light scattering effect
          * Returns the light position for light scattering effect
          * @return {BABYLON.Vector3} The custom light position
          * @return {BABYLON.Vector3} The custom light position
          */
          */
-        VolumetricLightScatteringPostProcess.prototype.getLightPosition = function () {
-            return this._customLightPosition;
+        VolumetricLightScatteringPostProcess.prototype.getCustomMeshPosition = function () {
+            return this._customMeshPosition;
         };
         };
         /**
         /**
          * Disposes the internal assets and detaches the post-process from the camera
          * Disposes the internal assets and detaches the post-process from the camera
          */
          */
         VolumetricLightScatteringPostProcess.prototype.dispose = function (camera) {
         VolumetricLightScatteringPostProcess.prototype.dispose = function (camera) {
-            this._godRaysRTT.dispose();
+            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);
             _super.prototype.dispose.call(this, camera);
         };
         };
         /**
         /**
@@ -115,21 +136,30 @@ var BABYLON;
          * @return {BABYLON.RenderTargetTexture} 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 () {
         VolumetricLightScatteringPostProcess.prototype.getPass = function () {
-            return this._godRaysRTT;
+            return this._volumetricLightScatteringRTT;
         };
         };
         // Private methods
         // Private methods
-        VolumetricLightScatteringPostProcess.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 _this = this;
             var engine = scene.getEngine();
             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
             // Custom render function for submeshes
             var renderSubMesh = function (subMesh) {
             var renderSubMesh = function (subMesh) {
                 var mesh = subMesh.getRenderingMesh();
                 var mesh = subMesh.getRenderingMesh();
+                if (_this._meshExcluded(mesh)) {
+                    return;
+                }
                 var scene = mesh.getScene();
                 var scene = mesh.getScene();
                 var engine = scene.getEngine();
                 var engine = scene.getEngine();
                 // Culling
                 // Culling
@@ -141,35 +171,38 @@ var BABYLON;
                 }
                 }
                 var hardwareInstancedRendering = (engine.getCaps().instancedArrays !== null) && (batch.visibleInstances[subMesh._id] !== null);
                 var hardwareInstancedRendering = (engine.getCaps().instancedArrays !== null) && (batch.visibleInstances[subMesh._id] !== null);
                 if (_this.isReady(subMesh, hardwareInstancedRendering)) {
                 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();
                     var material = subMesh.getMaterial();
-                    _this._godRaysPass.setMatrix("viewProjection", scene.getTransformMatrix());
+                    _this._volumetricLightScatteringPass.setMatrix("viewProjection", scene.getTransformMatrix());
                     // Alpha test
                     // Alpha test
-                    if (material && (mesh === _this.mesh || material.needAlphaTesting())) {
+                    if (material && (mesh === _this.mesh || material.needAlphaTesting() || material.opacityTexture !== undefined)) {
                         var alphaTexture = material.getAlphaTestTexture();
                         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
                     // Bones
                     if (mesh.useBones) {
                     if (mesh.useBones) {
-                        _this._godRaysPass.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                        _this._volumetricLightScatteringPass.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
                     }
                     }
                     // Draw
                     // 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
             // Render target texture callbacks
             var savedSceneClearColor;
             var savedSceneClearColor;
             var sceneClearColor = new BABYLON.Color3(0.0, 0.0, 0.0);
             var sceneClearColor = new BABYLON.Color3(0.0, 0.0, 0.0);
-            this._godRaysRTT.onBeforeRender = function () {
+            this._volumetricLightScatteringRTT.onBeforeRender = function () {
                 savedSceneClearColor = scene.clearColor;
                 savedSceneClearColor = scene.clearColor;
                 scene.clearColor = sceneClearColor;
                 scene.clearColor = sceneClearColor;
             };
             };
-            this._godRaysRTT.onAfterRender = function () {
+            this._volumetricLightScatteringRTT.onAfterRender = function () {
                 scene.clearColor = savedSceneClearColor;
                 scene.clearColor = savedSceneClearColor;
             };
             };
-            this._godRaysRTT.customRenderFunction = function (opaqueSubMeshes, alphaTestSubMeshes) {
+            this._volumetricLightScatteringRTT.customRenderFunction = function (opaqueSubMeshes, alphaTestSubMeshes, transparentSubMeshes) {
                 var index;
                 var index;
                 for (index = 0; index < opaqueSubMeshes.length; index++) {
                 for (index = 0; index < opaqueSubMeshes.length; index++) {
                     renderSubMesh(opaqueSubMeshes.data[index]);
                     renderSubMesh(opaqueSubMeshes.data[index]);
@@ -177,11 +210,14 @@ var BABYLON;
                 for (index = 0; index < alphaTestSubMeshes.length; index++) {
                 for (index = 0; index < alphaTestSubMeshes.length; index++) {
                     renderSubMesh(alphaTestSubMeshes.data[index]);
                     renderSubMesh(alphaTestSubMeshes.data[index]);
                 }
                 }
+                for (index = 0; index < transparentSubMeshes.length; index++) {
+                    renderSubMesh(transparentSubMeshes.data[index]);
+                }
             };
             };
         };
         };
-        VolumetricLightScatteringPostProcess.prototype._updateScreenCoordinates = function (scene) {
+        VolumetricLightScatteringPostProcess.prototype._updateMeshScreenCoordinates = function (scene) {
             var transform = scene.getTransformMatrix();
             var transform = scene.getTransformMatrix();
-            var pos = BABYLON.Vector3.Project(this.useCustomLightPosition ? this._customLightPosition : 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.x = pos.x / this._viewPort.width;
             this._screenCoordinates.y = pos.y / this._viewPort.height;
             this._screenCoordinates.y = pos.y / this._viewPort.height;
             if (this.invert)
             if (this.invert)

+ 89 - 47
Babylon/PostProcess/babylon.volumetricLightScatteringPostProcess.ts

@@ -1,18 +1,19 @@
 module BABYLON {
 module BABYLON {
+    // Inspired by http://http.developer.nvidia.com/GPUGems3/gpugems3_ch13.html
     export class VolumetricLightScatteringPostProcess extends PostProcess {
     export class VolumetricLightScatteringPostProcess extends PostProcess {
         // Members
         // Members
-        private _godRaysPass: Effect;
-        private _godRaysRTT: RenderTargetTexture;
+        private _volumetricLightScatteringPass: Effect;
+        private _volumetricLightScatteringRTT: RenderTargetTexture;
         private _viewPort: Viewport;
         private _viewPort: Viewport;
         private _screenCoordinates: Vector2 = Vector2.Zero();
         private _screenCoordinates: Vector2 = Vector2.Zero();
         private _cachedDefines: string;
         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)
         * Set if the post-process should use a custom position for the light source (true) or the internal mesh position (false)
         * @type {boolean}
         * @type {boolean}
         */
         */
-        public useCustomLightPosition: boolean = false;
+        public useCustomMeshPosition: boolean = false;
         /**
         /**
         * If the post-process should inverse the light scattering direction
         * If the post-process should inverse the light scattering direction
         * @type {boolean}
         * @type {boolean}
@@ -25,6 +26,16 @@
         public mesh: Mesh;
         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
          * @constructor
          * @param {string} name - The post-process name
          * @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 {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 {BABYLON.Engine} engine - The babylon engine
          * @param {boolean} reusable - If the post-process is reusable
          * @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();
             var scene = camera.getScene();
 
 
             this._viewPort = new Viewport(0, 0, 1, 1).toGlobal(scene.getEngine());
             this._viewPort = new Viewport(0, 0, 1, 1).toGlobal(scene.getEngine());
@@ -44,33 +55,40 @@
             this.mesh = (mesh !== null) ? mesh : VolumetricLightScatteringPostProcess.CreateDefaultMesh("VolumetricLightScatteringMesh", scene);
             this.mesh = (mesh !== null) ? mesh : VolumetricLightScatteringPostProcess.CreateDefaultMesh("VolumetricLightScatteringMesh", scene);
 
 
             // Configure
             // Configure
-            this._createPass(scene);
+            this._createPass(scene, 0.5);
 
 
             this.onApply = (effect: Effect) => {
             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);
             };
             };
         }
         }
 
 
         public isReady(subMesh: SubMesh, useInstances: boolean): boolean {
         public isReady(subMesh: SubMesh, useInstances: boolean): boolean {
             var mesh = subMesh.getMesh();
             var mesh = subMesh.getMesh();
-            var scene = mesh.getScene();
 
 
             var defines = [];
             var defines = [];
             var attribs = [VertexBuffer.PositionKind];
             var attribs = [VertexBuffer.PositionKind];
-            var material = subMesh.getMaterial();
+            var material: any = subMesh.getMaterial();
 
 
             // Render this.mesh as default
             // Render this.mesh as default
-            if (mesh === this.mesh)
+            if (mesh === this.mesh) {
                 defines.push("#define BASIC_RENDER");
                 defines.push("#define BASIC_RENDER");
+            }
 
 
             // Alpha test
             // Alpha test
             if (material) {
             if (material) {
                 if (material.needAlphaTesting() || mesh === this.mesh)
                 if (material.needAlphaTesting() || mesh === this.mesh)
                     defines.push("#define ALPHATEST");
                     defines.push("#define ALPHATEST");
 
 
+                if (material.opacityTexture !== undefined)
+                    defines.push("#define OPACITY");
+
                 if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {
                 if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {
                     attribs.push(VertexBuffer.UVKind);
                     attribs.push(VertexBuffer.UVKind);
                     defines.push("#define UV1");
                     defines.push("#define UV1");
@@ -102,37 +120,42 @@
             var join = defines.join("\n");
             var join = defines.join("\n");
             if (this._cachedDefines !== join) {
             if (this._cachedDefines !== join) {
                 this._cachedDefines = join;
                 this._cachedDefines = join;
-                this._godRaysPass = mesh.getScene().getEngine().createEffect(
+                this._volumetricLightScatteringPass = mesh.getScene().getEngine().createEffect(
                     { vertexElement: "depth", fragmentElement: "volumetricLightScatteringPass" },
                     { vertexElement: "depth", fragmentElement: "volumetricLightScatteringPass" },
                     attribs,
                     attribs,
                     ["world", "mBones", "viewProjection", "diffuseMatrix", "far"],
                     ["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
          * Sets the new light position for light scattering effect
          * @param {BABYLON.Vector3} The new custom light position
          * @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
          * Returns the light position for light scattering effect
          * @return {BABYLON.Vector3} The custom light position
          * @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
          * Disposes the internal assets and detaches the post-process from the camera
          */
          */
         public dispose(camera: Camera): void {
         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);
             super.dispose(camera);
         }
         }
 
 
@@ -141,23 +164,35 @@
          * @return {BABYLON.RenderTargetTexture} The render target texture used by the post-process
          * @return {BABYLON.RenderTargetTexture} The render target texture used by the post-process
          */
          */
         public getPass(): RenderTargetTexture {
         public getPass(): RenderTargetTexture {
-            return this._godRaysRTT;
+            return this._volumetricLightScatteringRTT;
         }
         }
 
 
         // Private methods
         // 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();
             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
             // Custom render function for submeshes
             var renderSubMesh = (subMesh: SubMesh): void => {
             var renderSubMesh = (subMesh: SubMesh): void => {
                 var mesh = subMesh.getRenderingMesh();
                 var mesh = subMesh.getRenderingMesh();
+                if (this._meshExcluded(mesh)) {
+                    return;
+                }
+
                 var scene = mesh.getScene();
                 var scene = mesh.getScene();
                 var engine = scene.getEngine();
                 var engine = scene.getEngine();
 
 
@@ -174,27 +209,31 @@
                 var hardwareInstancedRendering = (engine.getCaps().instancedArrays !== null) && (batch.visibleInstances[subMesh._id] !== null);
                 var hardwareInstancedRendering = (engine.getCaps().instancedArrays !== null) && (batch.visibleInstances[subMesh._id] !== null);
 
 
                 if (this.isReady(subMesh, hardwareInstancedRendering)) {
                 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
                     // Alpha test
-                    if (material && (mesh === this.mesh || material.needAlphaTesting())) {
+                    if (material && (mesh === this.mesh || material.needAlphaTesting() || material.opacityTexture !== undefined)) {
                         var alphaTexture = material.getAlphaTestTexture();
                         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
                     // Bones
                     if (mesh.useBones) {
                     if (mesh.useBones) {
-                        this._godRaysPass.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                        this._volumetricLightScatteringPass.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
                     }
                     }
 
 
                     // Draw
                     // 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 savedSceneClearColor: Color3;
             var sceneClearColor = new Color3(0.0, 0.0, 0.0);
             var sceneClearColor = new Color3(0.0, 0.0, 0.0);
 
 
-            this._godRaysRTT.onBeforeRender = (): void => {
+            this._volumetricLightScatteringRTT.onBeforeRender = (): void => {
                 savedSceneClearColor = scene.clearColor;
                 savedSceneClearColor = scene.clearColor;
                 scene.clearColor = sceneClearColor;
                 scene.clearColor = sceneClearColor;
             };
             };
 
 
-            this._godRaysRTT.onAfterRender = (): void => {
+            this._volumetricLightScatteringRTT.onAfterRender = (): void => {
                 scene.clearColor = savedSceneClearColor;
                 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;
                 var index;
 
 
                 for (index = 0; index < opaqueSubMeshes.length; index++) {
                 for (index = 0; index < opaqueSubMeshes.length; index++) {
@@ -221,12 +260,16 @@
                 for (index = 0; index < alphaTestSubMeshes.length; index++) {
                 for (index = 0; index < alphaTestSubMeshes.length; index++) {
                     renderSubMesh(alphaTestSubMeshes.data[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 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.x = pos.x / this._viewPort.width;
             this._screenCoordinates.y = pos.y / this._viewPort.height;
             this._screenCoordinates.y = pos.y / this._viewPort.height;
@@ -243,10 +286,9 @@
         * @return {BABYLON.Mesh} the default mesh
         * @return {BABYLON.Mesh} the default mesh
         */
         */
         public static CreateDefaultMesh(name: string, scene: Scene): Mesh {
         public static CreateDefaultMesh(name: string, scene: Scene): Mesh {
-            var mesh = BABYLON.Mesh.CreatePlane(name, 1, scene);
+            var mesh = Mesh.CreatePlane(name, 1, scene);
             mesh.billboardMode = AbstractMesh.BILLBOARDMODE_ALL;
             mesh.billboardMode = AbstractMesh.BILLBOARDMODE_ALL;
             mesh.material = new StandardMaterial(name + "Material", scene);
             mesh.material = new StandardMaterial(name + "Material", scene);
-
             return mesh;
             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
 #endif
 
 
 uniform sampler2D textureSampler;
 uniform sampler2D textureSampler;
 uniform sampler2D lightScatteringSampler;
 uniform sampler2D lightScatteringSampler;
 
 
-uniform vec2 lightPositionOnScreen;
+uniform float decay;
+uniform float exposure;
+uniform float weight;
+uniform float density;
+uniform vec2 meshPositionOnScreen;
 
 
 varying vec2 vUV;
 varying vec2 vUV;
 
 
 void main(void) {
 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 tc = vUV;
-    vec2 deltaTexCoord = (tc - lightPositionOnScreen.xy);
+	vec2 deltaTexCoord = (tc - meshPositionOnScreen.xy);
     deltaTexCoord *= 1.0 / float(NUM_SAMPLES) * density;
     deltaTexCoord *= 1.0 / float(NUM_SAMPLES) * density;
 
 
     float illuminationDecay = 1.0;
     float illuminationDecay = 1.0;
 
 
 	vec4 color = texture2D(lightScatteringSampler, tc) * 0.4;
 	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;
         tc -= deltaTexCoord;
 		vec4 sample = texture2D(lightScatteringSampler, tc) * 0.4;
 		vec4 sample = texture2D(lightScatteringSampler, tc) * 0.4;
         sample *= illuminationDecay * weight;
         sample *= illuminationDecay * weight;

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

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

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

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

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

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

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

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

+ 17 - 18
Babylon/Tools/babylon.tools.ts

@@ -56,7 +56,7 @@
             var child = element.firstChild;
             var child = element.firstChild;
 
 
             while (child) {
             while (child) {
-                if (child.nodeType == 3) {
+                if (child.nodeType === 3) {
                     result += child.textContent;
                     result += child.textContent;
                 }
                 }
                 child = child.nextSibling;
                 child = child.nextSibling;
@@ -80,8 +80,8 @@
             for (var index = indexStart; index < indexStart + indexCount; index++) {
             for (var index = indexStart; index < indexStart + indexCount; index++) {
                 var current = new Vector3(positions[indices[index] * 3], positions[indices[index] * 3 + 1], positions[indices[index] * 3 + 2]);
                 var current = new Vector3(positions[indices[index] * 3], positions[indices[index] * 3 + 1], positions[indices[index] * 3 + 2]);
 
 
-                minimum = BABYLON.Vector3.Minimize(current, minimum);
-                maximum = BABYLON.Vector3.Maximize(current, maximum);
+                minimum = Vector3.Minimize(current, minimum);
+                maximum = Vector3.Maximize(current, maximum);
             }
             }
 
 
             return {
             return {
@@ -97,8 +97,8 @@
             for (var index = start; index < start + count; index++) {
             for (var index = start; index < start + count; index++) {
                 var current = new Vector3(positions[index * 3], positions[index * 3 + 1], positions[index * 3 + 2]);
                 var current = new Vector3(positions[index * 3], positions[index * 3 + 1], positions[index * 3 + 2]);
 
 
-                minimum = BABYLON.Vector3.Minimize(current, minimum);
-                maximum = BABYLON.Vector3.Maximize(current, maximum);
+                minimum = Vector3.Minimize(current, minimum);
+                maximum = Vector3.Maximize(current, maximum);
             }
             }
 
 
             return {
             return {
@@ -179,7 +179,7 @@
 
 
             var img = new Image();
             var img = new Image();
 
 
-            if (url.substr(0, 5) != "data:")
+            if (url.substr(0, 5) !== "data:")
                 img.crossOrigin = 'anonymous';
                 img.crossOrigin = 'anonymous';
 
 
             img.onload = () => {
             img.onload = () => {
@@ -200,7 +200,7 @@
 
 
 
 
             //ANY database to do!
             //ANY database to do!
-            if (database && database.enableTexturesOffline && BABYLON.Database.isUASupportingBlobStorage) {
+            if (database && database.enableTexturesOffline && Database.isUASupportingBlobStorage) {
                 database.openAsync(loadFromIndexedDB, noIndexedDB);
                 database.openAsync(loadFromIndexedDB, noIndexedDB);
             }
             }
             else {
             else {
@@ -212,11 +212,11 @@
                         var textureName = url.substring(5);
                         var textureName = url.substring(5);
                         var blobURL;
                         var blobURL;
                         try {
                         try {
-                            blobURL = URL.createObjectURL(BABYLON.FilesInput.FilesTextures[textureName], { oneTimeOnly: true });
+                            blobURL = URL.createObjectURL(FilesInput.FilesTextures[textureName], { oneTimeOnly: true });
                         }
                         }
                         catch (ex) {
                         catch (ex) {
                             // Chrome doesn't support oneTimeOnly parameter
                             // Chrome doesn't support oneTimeOnly parameter
-                            blobURL = URL.createObjectURL(BABYLON.FilesInput.FilesTextures[textureName]);
+                            blobURL = URL.createObjectURL(FilesInput.FilesTextures[textureName]);
                         }
                         }
                         img.src = blobURL;
                         img.src = blobURL;
                     }
                     }
@@ -246,8 +246,8 @@
                 request.onprogress = progressCallBack;
                 request.onprogress = progressCallBack;
 
 
                 request.onreadystatechange = () => {
                 request.onreadystatechange = () => {
-                    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);
                             callback(!useArrayBuffer ? request.responseText : request.response);
                         } else { // Failed
                         } else { // Failed
                             if (onError) {
                             if (onError) {
@@ -269,7 +269,7 @@
 
 
             if (url.indexOf("file:") !== -1) {
             if (url.indexOf("file:") !== -1) {
                 var fileName = url.substring(5);
                 var fileName = url.substring(5);
-                BABYLON.Tools.ReadFile(BABYLON.FilesInput.FilesToLoad[fileName], callback, progressCallBack, true);
+                Tools.ReadFile(FilesInput.FilesToLoad[fileName], callback, progressCallBack, true);
             }
             }
             else {
             else {
                 // Caching all files
                 // Caching all files
@@ -319,7 +319,7 @@
             if (value === 0 || isNaN(value))
             if (value === 0 || isNaN(value))
                 return value;
                 return value;
 
 
-            return value > 0 ? 1 : -1
+            return value > 0 ? 1 : -1;
         }
         }
 
 
         public static Format(value: number, decimals: number = 2): string {
         public static Format(value: number, decimals: number = 2): string {
@@ -360,11 +360,11 @@
                 var sourceValue = source[prop];
                 var sourceValue = source[prop];
                 var typeOfSourceValue = typeof sourceValue;
                 var typeOfSourceValue = typeof sourceValue;
 
 
-                if (typeOfSourceValue == "function") {
+                if (typeOfSourceValue === "function") {
                     continue;
                     continue;
                 }
                 }
 
 
-                if (typeOfSourceValue == "object") {
+                if (typeOfSourceValue === "object") {
                     if (sourceValue instanceof Array) {
                     if (sourceValue instanceof Array) {
                         destination[prop] = [];
                         destination[prop] = [];
 
 
@@ -483,7 +483,6 @@
                 //Reading datas from WebGL
                 //Reading datas from WebGL
                 var data = engine.readPixels(0, 0, width, height);
                 var data = engine.readPixels(0, 0, width, height);
 
 
-
                 //To flip image on Y axis.
                 //To flip image on Y axis.
                 for (var i = 0; i < halfHeight; i++) {
                 for (var i = 0; i < halfHeight; i++) {
                     for (var j = 0; j < numberOfChannelsByLine; j++) {
                     for (var j = 0; j < numberOfChannelsByLine; j++) {
@@ -561,7 +560,7 @@
 
 
                 if (dataType & 2) {
                 if (dataType & 2) {
                     // Check header width and height since there is no "TGA" magic number
                     // Check header width and height since there is no "TGA" magic number
-                    var tgaHeader = BABYLON.Internals.TGATools.GetTGAHeader(xhr.response);
+                    var tgaHeader = Internals.TGATools.GetTGAHeader(xhr.response);
 
 
                     if (tgaHeader.width && tgaHeader.height && tgaHeader.width > 0 && tgaHeader.height > 0) {
                     if (tgaHeader.width && tgaHeader.height && tgaHeader.width > 0 && tgaHeader.height > 0) {
                         return true;
                         return true;
@@ -574,7 +573,7 @@
                     // Check for the "DDS" magic number
                     // Check for the "DDS" magic number
                     var ddsHeader = new Uint8Array(xhr.response, 0, 3);
                     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;
                         return true;
                     } else {
                     } else {
                         return false;
                         return false;

+ 2 - 2
Babylon/babylon.engine.js

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

+ 2 - 2
Babylon/babylon.engine.ts

@@ -846,7 +846,7 @@
         }
         }
 
 
         public endFrame(): void {
         public endFrame(): void {
-            this.flushFramebuffer();
+            //this.flushFramebuffer();
         }
         }
 
 
         /**
         /**
@@ -895,7 +895,7 @@
         }
         }
 
 
         public flushFramebuffer(): void {
         public flushFramebuffer(): void {
-            //   this._gl.flush();
+            this._gl.flush();
         }
         }
 
 
         public restoreDefaultFramebuffer(): void {
         public restoreDefaultFramebuffer(): void {

+ 2 - 0
Babylon/babylon.scene.js

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

+ 2 - 0
Babylon/babylon.scene.ts

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

文件差異過大導致無法顯示
+ 121 - 67
babylon.2.0-beta.debug.js


文件差異過大導致無法顯示
+ 17 - 17
babylon.2.0-beta.js