瀏覽代碼

Merge pull request #1121 from Palmer-JC/master

Enabled other post processes to be used when also using a 3D Rig
David Catuhe 9 年之前
父節點
當前提交
3d6e675814

+ 2 - 0
dist/preview release/what's new.md

@@ -17,6 +17,7 @@
     - StandardMaterial.maxSimultaneousLights can define how many dynamic lights the material can handle ([deltakosh](https://github.com/deltakosh))
   - **Updates**
     - Added postprocess.enablePixelPerfectMode to avoid texture scaling/stretching when dealing with non-power of 2 resolutions. cannot be used on post-processes chain ([deltakosh](https://github.com/deltakosh))
+    - Enabled other post processes to be used when also using a 3D Rig ([jcpalmer](https://github.com/Palmer-JC))
     - Added skeleton.getBoneIndexByName(boneName: string) ([dad72](https://github.com/dad72))
     - Added node._children to track children hierarchy ([deltakosh](https://github.com/deltakosh))
     - Added Camera.ForceAttachControlToAlwaysPreventDefault to help embedding Babylon.js in iFrames ([deltakosh](https://github.com/deltakosh))
@@ -39,6 +40,7 @@
   - **Exporters**
     - Support for 3dsmax 2017 ([deltakosh](https://github.com/deltakosh))
     - Added support for up to 8 bones influences per vertex for 3dsmax exporter ([deltakosh](https://github.com/deltakosh))
+    - Added console logging for .babylon file loading ([jcpalmer](https://github.com/Palmer-JC))
   - **API doc**
     - class `SolidParticleSystem` documented ([jerome](https://github.com/jbousquie))
     - class `MeshBuilder` documented ([jerome](https://github.com/jbousquie))

+ 21 - 13
src/Cameras/babylon.arcRotateCamera.ts

@@ -514,18 +514,21 @@
          * Override Camera.createRigCamera
          */
         public createRigCamera(name: string, cameraIndex: number): Camera {
+            var alphaShift : number;
             switch (this.cameraRigMode) {
                 case Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
                 case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
-                case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
                 case Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:
                 case Camera.RIG_MODE_VR:
-                    var alphaShift = this._cameraRigParams.stereoHalfAngle * (cameraIndex === 0 ? 1 : -1);
-                    var rigCam = new ArcRotateCamera(name, this.alpha + alphaShift, this.beta, this.radius, this.target, this.getScene());
-                    rigCam._cameraRigParams = {};
-                    return rigCam;
-            }
-            return null;
+                    alphaShift = this._cameraRigParams.stereoHalfAngle * (cameraIndex === 0 ? 1 : -1);
+                    break;
+                case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
+                    alphaShift = this._cameraRigParams.stereoHalfAngle * (cameraIndex === 0 ? -1 : 1);
+                    break;
+           }
+            var rigCam = new ArcRotateCamera(name, this.alpha + alphaShift, this.beta, this.radius, this.target, this.getScene());
+            rigCam._cameraRigParams = {};
+            return rigCam;
         }
         
         /**
@@ -533,18 +536,23 @@
          * Override Camera._updateRigCameras
          */
         public _updateRigCameras() {
+            var camLeft  = <ArcRotateCamera>this._rigCameras[0];
+            var camRight = <ArcRotateCamera>this._rigCameras[1];
+            
+            camLeft.beta = camRight.beta = this.beta;
+            camLeft.radius = camRight.radius = this.radius;
+
             switch (this.cameraRigMode) {
                 case Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
                 case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
-                case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
                 case Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:
                 case Camera.RIG_MODE_VR:
-                    var camLeft = <ArcRotateCamera>this._rigCameras[0];
-                    var camRight = <ArcRotateCamera>this._rigCameras[1];
-                    camLeft.alpha = this.alpha - this._cameraRigParams.stereoHalfAngle;
+                    camLeft.alpha  = this.alpha - this._cameraRigParams.stereoHalfAngle;
                     camRight.alpha = this.alpha + this._cameraRigParams.stereoHalfAngle;
-                    camLeft.beta = camRight.beta = this.beta;
-                    camLeft.radius = camRight.radius = this.radius;
+                    break;
+                case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
+                    camLeft.alpha  = this.alpha + this._cameraRigParams.stereoHalfAngle;
+                    camRight.alpha = this.alpha - this._cameraRigParams.stereoHalfAngle;
                     break;
             }
             super._updateRigCameras();

+ 70 - 116
src/Cameras/babylon.camera.ts

@@ -113,14 +113,13 @@
 
         public _cameraRigParams: any;
         public _rigCameras = new Array<Camera>();
-
+        public _rigPostProcess : PostProcess;
 
         // Cache
         private _computedViewMatrix = Matrix.Identity();
         public _projectionMatrix = new Matrix();
         private _worldMatrix: Matrix;
         public _postProcesses = new Array<PostProcess>();
-        public _postProcessesTakenIndices = [];
 
         public _activeMeshes = new SmartArray<Mesh>(256);
 
@@ -275,95 +274,72 @@
 
         public _checkInputs(): void {
         }
+        
+        private _cascadePostProcessesToRigCams() : void {
+            // invalidate framebuffer
+            if (this._postProcesses.length > 0){
+                this._postProcesses[0].markTextureDirty();
+            }
+            
+            // glue the rigPostProcess to the end of the user postprocesses & assign to each sub-camera
+            for(var i = 0, len = this._rigCameras.length; i < len; i++){
+                var cam = this._rigCameras[i];
+                var rigPostProcess = cam._rigPostProcess;
+                
+                // for VR rig, there does not have to be a post process 
+                if (rigPostProcess){
+                    var isPass = rigPostProcess instanceof PassPostProcess;
+                    if (isPass){
+                        // any rig which has a PassPostProcess for rig[0], cannot be isIntermediate when there are also user postProcesses
+                        cam.isIntermediate = this._postProcesses.length === 0;
+                    }               
+                    cam._postProcesses = this._postProcesses.slice(0).concat(rigPostProcess);
+                    rigPostProcess.markTextureDirty();
+                }
+            }
+        }
 
         public attachPostProcess(postProcess: PostProcess, insertAt: number = null): number {
             if (!postProcess.isReusable() && this._postProcesses.indexOf(postProcess) > -1) {
                 Tools.Error("You're trying to reuse a post process not defined as reusable.");
                 return 0;
             }
-
+            
             if (insertAt == null || insertAt < 0) {
                 this._postProcesses.push(postProcess);
-                this._postProcessesTakenIndices.push(this._postProcesses.length - 1);
-
-                return this._postProcesses.length - 1;
-            }
-
-            var add = 0;
-            var i: number;
-            var start: number;
-            if (this._postProcesses[insertAt]) {
-                start = this._postProcesses.length - 1;
-                for (i = start; i >= insertAt + 1; --i) {
-                    this._postProcesses[i + 1] = this._postProcesses[i];
-                }
-
-                add = 1;
-            }
-
-            for (i = 0; i < this._postProcessesTakenIndices.length; ++i) {
-                if (this._postProcessesTakenIndices[i] < insertAt) {
-                    continue;
-                }
-
-                start = this._postProcessesTakenIndices.length - 1;
-                for (var j = start; j >= i; --j) {
-                    this._postProcessesTakenIndices[j + 1] = this._postProcessesTakenIndices[j] + add;
-                }
-                this._postProcessesTakenIndices[i] = insertAt;
-                break;
+                
+            }else{
+                this._postProcesses.splice(insertAt, 0, postProcess);
             }
-
-            if (!add && this._postProcessesTakenIndices.indexOf(insertAt) === -1) {
-                this._postProcessesTakenIndices.push(insertAt);
-            }
-
-            var result = insertAt + add;
-
-            this._postProcesses[result] = postProcess;
-
-            return result;
+            this._cascadePostProcessesToRigCams(); // also ensures framebuffer invalidated            
+            return this._postProcesses.indexOf(postProcess);
         }
-
+        
         public detachPostProcess(postProcess: PostProcess, atIndices: any = null): number[] {
             var result = [];
             var i: number;
             var index: number;
-            if (!atIndices) {
-
-                var length = this._postProcesses.length;
 
-                for (i = 0; i < length; i++) {
-
-                    if (this._postProcesses[i] !== postProcess) {
-                        continue;
-                    }
-
-                    delete this._postProcesses[i];
-                    index = this._postProcessesTakenIndices.indexOf(i);
-                    this._postProcessesTakenIndices.splice(index, 1);
+            if (!atIndices) {
+                var idx = this._postProcesses.indexOf(postProcess);
+                if (idx !== -1){
+                    this._postProcesses.splice(idx, 1);
                 }
-
-            }
-            else {
+            } else {
                 atIndices = (atIndices instanceof Array) ? atIndices : [atIndices];
-                for (i = 0; i < atIndices.length; i++) {
-                    var foundPostProcess = this._postProcesses[atIndices[i]];
-
-                    if (foundPostProcess !== postProcess) {
+                // iterate descending, so can just splice as we go
+                for (i = atIndices.length - 1; i >= 0; i--) {
+                    if ( this._postProcesses[atIndices[i]] !== postProcess) {
                         result.push(i);
                         continue;
                     }
-
-                    delete this._postProcesses[atIndices[i]];
-
-                    index = this._postProcessesTakenIndices.indexOf(atIndices[i]);
-                    this._postProcessesTakenIndices.splice(index, 1);
+                    this._postProcesses.splice(index, 1);
                 }
             }
+            this._cascadePostProcessesToRigCams(); // also ensures framebuffer invalidated
             return result;
         }
-
+        
         public getWorldMatrix(): Matrix {
             if (!this._worldMatrix) {
                 this._worldMatrix = Matrix.Identity();
@@ -452,8 +428,8 @@
             }
 
             // Postprocesses
-            for (var i = 0; i < this._postProcessesTakenIndices.length; ++i) {
-                this._postProcesses[this._postProcessesTakenIndices[i]].dispose(this);
+            for (var i = 0; i < this._postProcesses.length; ++i) {
+                this._postProcesses[i].dispose(this);
             }
 
             super.dispose();
@@ -466,82 +442,57 @@
             }
             this.cameraRigMode = mode;
             this._cameraRigParams = {};
+            //we have to implement stereo camera calcultating left and right viewpoints from interaxialDistance and target, 
+            //not from a given angle as it is now, but until that complete code rewriting provisional stereoHalfAngle value is introduced
+            this._cameraRigParams.interaxialDistance = rigParams.interaxialDistance || 0.0637;
+            this._cameraRigParams.stereoHalfAngle = BABYLON.Tools.ToRadians(this._cameraRigParams.interaxialDistance / 0.0637);
 
-            switch (this.cameraRigMode) {
-                case Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
-                case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
-                case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
-                case Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:
-                    this._cameraRigParams.interaxialDistance = rigParams.interaxialDistance || 0.0637;
-                    //we have to implement stereo camera calcultating left and right viewpoints from interaxialDistance and target, 
-                    //not from a given angle as it is now, but until that complete code rewriting provisional stereoHalfAngle value is introduced
-                    this._cameraRigParams.stereoHalfAngle = Tools.ToRadians(this._cameraRigParams.interaxialDistance / 0.0637);
-
-                    this._rigCameras.push(this.createRigCamera(this.name + "_L", 0));
-                    this._rigCameras.push(this.createRigCamera(this.name + "_R", 1));
-                    break;
+            // create the rig cameras, unless none
+            if (this.cameraRigMode !== Camera.RIG_MODE_NONE){
+                this._rigCameras.push(this.createRigCamera(this.name + "_L", 0));
+                this._rigCameras.push(this.createRigCamera(this.name + "_R", 1));
             }
 
-            var postProcesses = new Array<PostProcess>();
-
             switch (this.cameraRigMode) {
                 case Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
-                    postProcesses.push(new PassPostProcess(this.name + "_passthru", 1.0, this._rigCameras[0]));
-                    this._rigCameras[0].isIntermediate = true;
-
-                    postProcesses.push(new AnaglyphPostProcess(this.name + "_anaglyph", 1.0, this._rigCameras[1]));
-                    postProcesses[1].onApply = effect => {
-                        effect.setTextureFromPostProcess("leftSampler", postProcesses[0]);
-                    };
+                    this._rigCameras[0]._rigPostProcess = new PassPostProcess(this.name + "_passthru", 1.0, this._rigCameras[0]);
+                    this._rigCameras[1]._rigPostProcess = new AnaglyphPostProcess(this.name + "_anaglyph", 1.0, this._rigCameras);
                     break;
 
                 case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
                 case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
                 case Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:
-                    var isStereoscopicHoriz = (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL || this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED);
-                    var firstCamIndex = (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? 1 : 0;
-                    var secondCamIndex = 1 - firstCamIndex;
-
-                    postProcesses.push(new PassPostProcess(this.name + "_passthru", 1.0, this._rigCameras[firstCamIndex]));
-                    this._rigCameras[firstCamIndex].isIntermediate = true;
-
-                    postProcesses.push(new StereoscopicInterlacePostProcess(this.name + "_stereoInterlace", this._rigCameras[secondCamIndex], postProcesses[0], isStereoscopicHoriz));
+                    var isStereoscopicHoriz = this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL || this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED;
+                    
+                    this._rigCameras[0]._rigPostProcess = new PassPostProcess(this.name + "_passthru", 1.0, this._rigCameras[0]);
+                    this._rigCameras[1]._rigPostProcess = new StereoscopicInterlacePostProcess(this.name + "_stereoInterlace", this._rigCameras, isStereoscopicHoriz);
                     break;
 
                 case Camera.RIG_MODE_VR:
-                    this._cameraRigParams.interaxialDistance = rigParams.interaxialDistance || 0.0637;
-                    this._cameraRigParams.stereoHalfAngle = BABYLON.Tools.ToRadians(this._cameraRigParams.interaxialDistance / 0.0637);
-
-                    this._rigCameras.push(this.createRigCamera(this.name + "_L", 0));
-                    this._rigCameras.push(this.createRigCamera(this.name + "_R", 1));
-
                     var metrics = rigParams.vrCameraMetrics || VRCameraMetrics.GetDefault();
+                    
                     this._rigCameras[0]._cameraRigParams.vrMetrics = metrics;
                     this._rigCameras[0].viewport = new Viewport(0, 0, 0.5, 1.0);
                     this._rigCameras[0]._cameraRigParams.vrWorkMatrix = new Matrix();
-
                     this._rigCameras[0]._cameraRigParams.vrHMatrix = metrics.leftHMatrix;
                     this._rigCameras[0]._cameraRigParams.vrPreViewMatrix = metrics.leftPreViewMatrix;
                     this._rigCameras[0].getProjectionMatrix = this._rigCameras[0]._getVRProjectionMatrix;
 
-                    if (metrics.compensateDistortion) {
-                        postProcesses.push(new VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Left", this._rigCameras[0], false, metrics));
-                    }
-
-                    this._rigCameras[1]._cameraRigParams.vrMetrics = this._rigCameras[0]._cameraRigParams.vrMetrics;
+                    this._rigCameras[1]._cameraRigParams.vrMetrics = metrics;
                     this._rigCameras[1].viewport = new Viewport(0.5, 0, 0.5, 1.0);
                     this._rigCameras[1]._cameraRigParams.vrWorkMatrix = new Matrix();
                     this._rigCameras[1]._cameraRigParams.vrHMatrix = metrics.rightHMatrix;
                     this._rigCameras[1]._cameraRigParams.vrPreViewMatrix = metrics.rightPreViewMatrix;
-
                     this._rigCameras[1].getProjectionMatrix = this._rigCameras[1]._getVRProjectionMatrix;
 
                     if (metrics.compensateDistortion) {
-                        postProcesses.push(new VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Right", this._rigCameras[1], true, metrics));
+                        this._rigCameras[0]._rigPostProcess = new VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Left", this._rigCameras[0], false, metrics);
+                        this._rigCameras[1]._rigPostProcess = new VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Right", this._rigCameras[1], true, metrics);
                     }
                     break;
             }
 
+            this._cascadePostProcessesToRigCams(); 
             this._update();
         }
 
@@ -552,6 +503,9 @@
         }
 
         public setCameraRigParameter(name: string, value: any) {
+            if (!this._cameraRigParams){
+               this._cameraRigParams = {}; 
+            }
             this._cameraRigParams[name] = value;
             //provisionnally:
             if (name === "interaxialDistance") {
@@ -560,14 +514,14 @@
         }
         
         /**
-         * May needs to be overridden by children so sub has required properties to be copied
+         * needs to be overridden by children so sub has required properties to be copied
          */
         public createRigCamera(name: string, cameraIndex: number): Camera {
-            return null;
+           return null;
         }
         
         /**
-         * May needs to be overridden by children
+         * May need to be overridden by children
          */
         public _updateRigCameras() {
             for (var i = 0; i < this._rigCameras.length; i++) {

+ 18 - 17
src/Cameras/babylon.targetCamera.ts

@@ -259,31 +259,32 @@
          * Override Camera._updateRigCameras
          */
         public _updateRigCameras() {
+            var camLeft = <TargetCamera>this._rigCameras[0];
+            var camRight = <TargetCamera>this._rigCameras[1];
+
             switch (this.cameraRigMode) {
                 case Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
                 case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
                 case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
                 case Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:
+                    //provisionnaly using _cameraRigParams.stereoHalfAngle instead of calculations based on _cameraRigParams.interaxialDistance:
+                    var leftSign  = (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ?  1 : -1;
+                    var rightSign = (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? -1 :  1;
+                    this._getRigCamPosition(this._cameraRigParams.stereoHalfAngle * leftSign , camLeft.position);
+                    this._getRigCamPosition(this._cameraRigParams.stereoHalfAngle * rightSign, camRight.position);
+
+                    camLeft.setTarget(this.getTarget());
+                    camRight.setTarget(this.getTarget());
+                    break;
+                    
                 case Camera.RIG_MODE_VR:
-                    var camLeft = <TargetCamera>this._rigCameras[0];
-                    var camRight = <TargetCamera>this._rigCameras[1];
-
-                    if (this.cameraRigMode === Camera.RIG_MODE_VR) {
-                        camLeft.rotation.x = camRight.rotation.x = this.rotation.x;
-                        camLeft.rotation.y = camRight.rotation.y = this.rotation.y;
-                        camLeft.rotation.z = camRight.rotation.z = this.rotation.z;
-
-                        camLeft.position.copyFrom(this.position);
-                        camRight.position.copyFrom(this.position);
+                    camLeft.rotation.x = camRight.rotation.x = this.rotation.x;
+                    camLeft.rotation.y = camRight.rotation.y = this.rotation.y;
+                    camLeft.rotation.z = camRight.rotation.z = this.rotation.z;
 
-                    } else {
-                        //provisionnaly using _cameraRigParams.stereoHalfAngle instead of calculations based on _cameraRigParams.interaxialDistance:
-                        this._getRigCamPosition(-this._cameraRigParams.stereoHalfAngle, camLeft.position);
-                        this._getRigCamPosition(this._cameraRigParams.stereoHalfAngle, camRight.position);
+                    camLeft.position.copyFrom(this.position);
+                    camRight.position.copyFrom(this.position);
 
-                        camLeft.setTarget(this.getTarget());
-                        camRight.setTarget(this.getTarget());
-                    }
                     break;
             }
             super._updateRigCameras();

+ 9 - 2
src/PostProcess/babylon.anaglyphPostProcess.ts

@@ -1,7 +1,14 @@
 module BABYLON {
     export class AnaglyphPostProcess extends PostProcess {
-        constructor(name: string, ratio: number, camera: Camera, samplingMode?: number, engine?: Engine, reusable?: boolean) {
-            super(name, "anaglyph", null, ["leftSampler"], ratio, camera, samplingMode, engine, reusable);
+        private _passedProcess : PostProcess;
+
+        constructor(name: string, ratio: number,  rigCameras: Camera[], samplingMode?: number, engine?: Engine, reusable?: boolean) {
+            super(name, "anaglyph", null, ["leftSampler"], ratio, rigCameras[1], samplingMode, engine, reusable);
+            this._passedProcess = rigCameras[0]._rigPostProcess;
+
+            this.onApply = (effect: Effect) => {
+                effect.setTextureFromPostProcess("leftSampler", this._passedProcess);
+            };
         }
     }
 } 

+ 11 - 6
src/PostProcess/babylon.postProcess.ts

@@ -56,7 +56,7 @@
 
             this.updateEffect(defines);
         }
-
+        
         public updateEffect(defines?: string) {
             this._effect = this._engine.createEffect({ vertex: "postprocess", fragment: this._fragmentUrl },
                 ["position"],
@@ -67,6 +67,11 @@
         public isReusable(): boolean {
             return this._reusable;
         }
+        
+        /** invalidate frameBuffer to hint the postprocess to create a depth buffer */
+        public markTextureDirty() : void{
+            this.width = -1;
+        }
 
         public activate(camera: Camera, sourceTexture?: WebGLTexture): void {
             camera = camera || this._camera;
@@ -96,13 +101,13 @@
                         this._engine._releaseTexture(this._textures.data[i]);
                     }
                     this._textures.reset();
-                }
+                }         
                 this.width = desiredWidth;
                 this.height = desiredHeight;
-                this._textures.push(this._engine.createRenderTargetTexture({ width: this.width, height: this.height }, { generateMipMaps: false, generateDepthBuffer: camera._postProcesses.indexOf(this) === camera._postProcessesTakenIndices[0], samplingMode: this.renderTargetSamplingMode, type: this._textureType }));
+                this._textures.push(this._engine.createRenderTargetTexture({ width: this.width, height: this.height }, { generateMipMaps: false, generateDepthBuffer: camera._postProcesses.indexOf(this) === 0, samplingMode: this.renderTargetSamplingMode, type: this._textureType }));
 
                 if (this._reusable) {
-                    this._textures.push(this._engine.createRenderTargetTexture({ width: this.width, height: this.height }, { generateMipMaps: false, generateDepthBuffer: camera._postProcesses.indexOf(this) === camera._postProcessesTakenIndices[0], samplingMode: this.renderTargetSamplingMode, type: this._textureType }));
+                    this._textures.push(this._engine.createRenderTargetTexture({ width: this.width, height: this.height }, { generateMipMaps: false, generateDepthBuffer: camera._postProcesses.indexOf(this) === 0, samplingMode: this.renderTargetSamplingMode, type: this._textureType }));
                 }
 
                 if (this.onSizeChanged) {
@@ -179,8 +184,8 @@
             camera.detachPostProcess(this);
 
             var index = camera._postProcesses.indexOf(this);
-            if (index === camera._postProcessesTakenIndices[0] && camera._postProcessesTakenIndices.length > 0) {
-                this._camera._postProcesses[camera._postProcessesTakenIndices[0]].width = -1; // invalidate frameBuffer to hint the postprocess to create a depth buffer
+            if (index === 0 && camera._postProcesses.length > 0) {
+                this._camera._postProcesses[0].markTextureDirty(); 
             }
         }
     }

+ 7 - 10
src/PostProcess/babylon.postProcessManager.ts

@@ -39,14 +39,12 @@
         // Methods
         public _prepareFrame(sourceTexture?: WebGLTexture): boolean {
             var postProcesses = this._scene.activeCamera._postProcesses;
-            var postProcessesTakenIndices = this._scene.activeCamera._postProcessesTakenIndices;
 
-            if (postProcessesTakenIndices.length === 0 || !this._scene.postProcessesEnabled) {
+            if (postProcesses.length === 0 || !this._scene.postProcessesEnabled) {
                 return false;
             }
 
-            postProcesses[this._scene.activeCamera._postProcessesTakenIndices[0]].activate(this._scene.activeCamera, sourceTexture);
-
+            postProcesses[0].activate(this._scene.activeCamera, sourceTexture);
             return true;
         }
 
@@ -92,15 +90,14 @@
 
         public _finalizeFrame(doNotPresent?: boolean, targetTexture?: WebGLTexture, faceIndex?: number, postProcesses?: PostProcess[]): void {
             postProcesses = postProcesses || this._scene.activeCamera._postProcesses;
-            var postProcessesTakenIndices = this._scene.activeCamera._postProcessesTakenIndices;
-            if (postProcessesTakenIndices.length === 0 || !this._scene.postProcessesEnabled) {
+            if (postProcesses.length === 0 || !this._scene.postProcessesEnabled) {
                 return;
             }
             var engine = this._scene.getEngine();
 
-            for (var index = 0; index < postProcessesTakenIndices.length; index++) {
-                if (index < postProcessesTakenIndices.length - 1) {
-                    postProcesses[postProcessesTakenIndices[index + 1]].activate(this._scene.activeCamera, targetTexture);
+            for (var index = 0, len = postProcesses.length; index < len; index++) {
+                if (index < len - 1) {
+                    postProcesses[index + 1].activate(this._scene.activeCamera, targetTexture);
                 } else {
                     if (targetTexture) {
                         engine.bindFramebuffer(targetTexture, faceIndex);
@@ -113,7 +110,7 @@
                     break;
                 }
 
-                var pp = postProcesses[postProcessesTakenIndices[index]];
+                var pp = postProcesses[index];
                 var effect = pp.apply();
 
                 if (effect) {

+ 5 - 3
src/PostProcess/babylon.stereoscopicInterlacePostProcess.ts

@@ -1,17 +1,19 @@
 module BABYLON {
     export class StereoscopicInterlacePostProcess extends PostProcess {
         private _stepSize : Vector2;
+        private _passedProcess : PostProcess;
 
-        constructor(name: string, camB: Camera, postProcessA : PostProcess, isStereoscopicHoriz: boolean, samplingMode?: number) {
-            super(name, "stereoscopicInterlace", ['stepSize'], ['camASampler'], 1, camB, samplingMode, camB.getScene().getEngine(), false, isStereoscopicHoriz ? "#define IS_STEREOSCOPIC_HORIZ 1" : undefined);
+        constructor(name: string, rigCameras: Camera[], isStereoscopicHoriz: boolean, samplingMode?: number, engine?: Engine, reusable?: boolean) {
+            super(name, "stereoscopicInterlace", ['stepSize'], ['camASampler'], 1, rigCameras[1], samplingMode, engine, reusable, isStereoscopicHoriz ? "#define IS_STEREOSCOPIC_HORIZ 1" : undefined);
             
+            this._passedProcess = rigCameras[0]._rigPostProcess;
             this._stepSize = new Vector2(1 / this.width, 1 / this.height);
 
             this.onSizeChanged = () => {
                 this._stepSize = new Vector2(1 / this.width, 1 / this.height);
             };
             this.onApply = (effect: Effect) => {
-                effect.setTextureFromPostProcess("camASampler", postProcessA);
+                effect.setTextureFromPostProcess("camASampler", this._passedProcess);
                 effect.setFloat2("stepSize", this._stepSize.x, this._stepSize.y);
             };
         }