瀏覽代碼

dof and bloom to share merge post process

Trevor Baron 7 年之前
父節點
當前提交
7e05404ec6

+ 34 - 13
src/PostProcess/RenderPipeline/Pipelines/babylon.defaultRenderingPipeline.ts

@@ -30,6 +30,8 @@
         public sharpen: SharpenPostProcess;
         public sharpen: SharpenPostProcess;
         private _sharpenEffect: PostProcessRenderEffect;
         private _sharpenEffect: PostProcessRenderEffect;
         private bloom: BloomEffect;
         private bloom: BloomEffect;
+        private _defaultPipelineMerge:DefaultPipelineMergeMergePostProcess;
+        private _defaultPipelineMergeEffect: PostProcessRenderEffect;
         /**
         /**
          * Depth of field effect, applies a blur based on how far away objects are from the focus distance.
          * Depth of field effect, applies a blur based on how far away objects are from the focus distance.
          */
          */
@@ -107,8 +109,8 @@
             if (this._bloomWeight === value) {
             if (this._bloomWeight === value) {
                 return;
                 return;
             }
             }
-            if(this.bloom._merge._mergeOptions.bloom){
-                this.bloom._merge._mergeOptions.bloom.weight = value;
+            if(this._defaultPipelineMerge._mergeOptions && this._defaultPipelineMerge._mergeOptions.bloom){
+                this._defaultPipelineMerge._mergeOptions.bloom.weight = value;
             }
             }
             
             
             this._bloomWeight = value;
             this._bloomWeight = value;
@@ -130,7 +132,7 @@
 
 
             // recreate bloom and dispose old as this setting is not dynamic
             // recreate bloom and dispose old as this setting is not dynamic
             var oldBloom = this.bloom;
             var oldBloom = this.bloom;
-            this.bloom = new BloomEffect(this._scene, this.bloomScale, this.bloomKernel, this._defaultPipelineTextureType);
+            this.bloom = new BloomEffect(this._scene, this.bloomScale, this.bloomKernel, this._defaultPipelineTextureType, false);
             for (var i = 0; i < this._cameras.length; i++) {
             for (var i = 0; i < this._cameras.length; i++) {
                 oldBloom.disposeEffects(this._cameras[i]);
                 oldBloom.disposeEffects(this._cameras[i]);
             }
             }
@@ -194,7 +196,7 @@
             // recreate dof and dispose old as this setting is not dynamic
             // recreate dof and dispose old as this setting is not dynamic
             var oldDof = this.depthOfField;
             var oldDof = this.depthOfField;
             
             
-            this.depthOfField = new DepthOfFieldEffect(this._scene, null, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType);
+            this.depthOfField = new DepthOfFieldEffect(this._scene, null, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType, false);
             this.depthOfField.focalLength = oldDof.focalLength;
             this.depthOfField.focalLength = oldDof.focalLength;
             this.depthOfField.focusDistance = oldDof.focusDistance;
             this.depthOfField.focusDistance = oldDof.focusDistance;
             this.depthOfField.fStop = oldDof.fStop;
             this.depthOfField.fStop = oldDof.fStop;
@@ -316,9 +318,12 @@
             this.sharpen = new SharpenPostProcess("sharpen", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType, true);
             this.sharpen = new SharpenPostProcess("sharpen", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType, true);
             this._sharpenEffect = new PostProcessRenderEffect(engine, this.SharpenPostProcessId, () => { return this.sharpen; }, true);
             this._sharpenEffect = new PostProcessRenderEffect(engine, this.SharpenPostProcessId, () => { return this.sharpen; }, true);
 
 
-            this.depthOfField = new DepthOfFieldEffect(this._scene, null, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType, true);
+            this.depthOfField = new DepthOfFieldEffect(this._scene, null, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType, false, true);
             
             
-            this.bloom = new BloomEffect(this._scene, this.bloomScale, this.bloomKernel, this._defaultPipelineTextureType, true);
+            this.bloom = new BloomEffect(this._scene, this.bloomScale, this.bloomKernel, this._defaultPipelineTextureType, false, true);
+
+            this._defaultPipelineMerge = new DefaultPipelineMergeMergePostProcess("defaultPipelineMerge", {}, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, this._defaultPipelineTextureType, true);
+            this._defaultPipelineMergeEffect = new PostProcessRenderEffect(engine, "defaultPipelineMerge", () => { return this._defaultPipelineMerge; }, true);
 
 
             this.chromaticAberration = new ChromaticAberrationPostProcess("ChromaticAberration", engine.getRenderWidth(), engine.getRenderHeight(), 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType, true);
             this.chromaticAberration = new ChromaticAberrationPostProcess("ChromaticAberration", engine.getRenderWidth(), engine.getRenderHeight(), 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType, true);
             this._chromaticAberrationEffect = new PostProcessRenderEffect(engine, this.ChromaticAberrationPostProcessId, () => { return this.chromaticAberration; }, true);
             this._chromaticAberrationEffect = new PostProcessRenderEffect(engine, this.ChromaticAberrationPostProcessId, () => { return this.chromaticAberration; }, true);
@@ -364,7 +369,7 @@
             if (!this._buildAllowed) {
             if (!this._buildAllowed) {
                 return;
                 return;
             }
             }
-
+            
             var engine = this._scene.getEngine();
             var engine = this._scene.getEngine();
 
 
             this._disposePostProcesses();
             this._disposePostProcesses();
@@ -377,6 +382,8 @@
             this._prevPostProcess = null;
             this._prevPostProcess = null;
             this._prevPrevPostProcess = null;
             this._prevPrevPostProcess = null;
 
 
+            var mergeOptions = new DefaultPipelineMergePostProcessOptions();
+
             if (this.sharpenEnabled) {
             if (this.sharpenEnabled) {
                 if(!this.sharpen.isReady()){
                 if(!this.sharpen.isReady()){
                     this.sharpen.updateEffect();
                     this.sharpen.updateEffect();
@@ -391,16 +398,30 @@
                 if(!this.depthOfField._isReady()){
                 if(!this.depthOfField._isReady()){
                     this.depthOfField._updateEffects();
                     this.depthOfField._updateEffects();
                 }
                 }
+                mergeOptions.depthOfField = {circleOfConfusion: this.depthOfField._effects[0], blurSteps: this.depthOfField._depthOfFieldBlurX};
+                if(!mergeOptions.originalFromInput){
+                    mergeOptions.originalFromInput=this.depthOfField._effects[0];
+                }
                 this.addEffect(this.depthOfField);
                 this.addEffect(this.depthOfField);
-                this._setAutoClearAndTextureSharing(this.depthOfField._defaultPipelineMerge);
+                this._setAutoClearAndTextureSharing(this.depthOfField._effects[this.depthOfField._effects.length-1]);
             }
             }
-
+            
             if (this.bloomEnabled) {
             if (this.bloomEnabled) {
                 if(!this.bloom._isReady()){
                 if(!this.bloom._isReady()){
                     this.bloom._updateEffects();
                     this.bloom._updateEffects();
                 }
                 }
+                mergeOptions.bloom = {blurred: this.bloom._effects[this.bloom._effects.length-1], weight: this.bloomWeight}
+                if(!mergeOptions.originalFromInput){
+                    mergeOptions.originalFromInput=this.bloom._effects[0];
+                }
                 this.addEffect(this.bloom);
                 this.addEffect(this.bloom);
             }
             }
+            
+            if(mergeOptions.originalFromInput){
+                this._defaultPipelineMerge._mergeOptions = mergeOptions;
+                this._defaultPipelineMerge.updateEffect();
+                this.addEffect(this._defaultPipelineMergeEffect);
+            }
 
 
             if (this.fxaaEnabled) {
             if (this.fxaaEnabled) {
                 this.fxaa = new FxaaPostProcess("fxaa", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
                 this.fxaa = new FxaaPostProcess("fxaa", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
@@ -408,10 +429,10 @@
                 this._setAutoClearAndTextureSharing(this.fxaa);
                 this._setAutoClearAndTextureSharing(this.fxaa);
             }
             }
 
 
-            if (this._imageProcessingEnabled) {	
-                this.imageProcessing = new ImageProcessingPostProcess("imageProcessing", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);	
-                if (this._hdr) {	
-                    this.addEffect(new PostProcessRenderEffect(engine, this.ImageProcessingPostProcessId, () => { return this.imageProcessing; }, true));	
+            if (this._imageProcessingEnabled) {
+                this.imageProcessing = new ImageProcessingPostProcess("imageProcessing", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
+                if (this._hdr) {
+                    this.addEffect(new PostProcessRenderEffect(engine, this.ImageProcessingPostProcessId, () => { return this.imageProcessing; }, true));
                 } else {	
                 } else {	
                     this._scene.imageProcessingConfiguration.applyByPostProcess = false;	
                     this._scene.imageProcessingConfiguration.applyByPostProcess = false;	
                 }	
                 }	

+ 4 - 0
src/PostProcess/RenderPipeline/babylon.postProcessRenderPipeline.ts

@@ -1,4 +1,8 @@
 module BABYLON {
 module BABYLON {
+    class PipelineChain{
+        effects: Array<PostProcessRenderEffect> = []
+        next: Array<PipelineChain> = []
+    }
     export class PostProcessRenderPipeline {
     export class PostProcessRenderPipeline {
 
 
         private _renderEffects: {[key: string]: PostProcessRenderEffect};
         private _renderEffects: {[key: string]: PostProcessRenderEffect};

+ 35 - 26
src/PostProcess/babylon.bloomEffect.ts

@@ -3,14 +3,18 @@ module BABYLON {
      * The bloom effect spreads bright areas of an image to simulate artifacts seen in cameras
      * The bloom effect spreads bright areas of an image to simulate artifacts seen in cameras
      */
      */
     export class BloomEffect extends PostProcessRenderEffect{
     export class BloomEffect extends PostProcessRenderEffect{
-        private _effects: Array<PostProcess> = [];
-        private blurX:BlurPostProcess;
-        private blurY:BlurPostProcess;
-        
         /**
         /**
          * Internal
          * Internal
          */
          */
-        public _merge:DefaultPipelineMergeMergePostProcess;
+        public _effects: Array<PostProcess> = [];
+
+        /**
+         * Internal
+         */
+        private _downscale:PassPostProcess;
+        private _blurX:BlurPostProcess;
+        private _blurY:BlurPostProcess;
+        private _merge:Nullable<DefaultPipelineMergeMergePostProcess>;
 
 
         /**
         /**
          * Creates a new instance of @see BloomEffect
          * Creates a new instance of @see BloomEffect
@@ -18,32 +22,37 @@ module BABYLON {
          * @param bloomScale The ratio of the blur texture to the input texture that should be used to compute the bloom.
          * @param bloomScale The ratio of the blur texture to the input texture that should be used to compute the bloom.
          * @param bloomKernel The size of the kernel to be used when applying the blur.
          * @param bloomKernel The size of the kernel to be used when applying the blur.
          * @param pipelineTextureType The type of texture to be used when performing the post processing.
          * @param pipelineTextureType The type of texture to be used when performing the post processing.
+         * @param performMerge If the finalization merge should be performed by this effect.
          * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
          * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
          */
          */
-        constructor(scene: Scene, bloomScale:number, bloomKernel:number, pipelineTextureType = 0, blockCompilation = false) {
-            super(scene.getEngine(), "depth of field", ()=>{
+        constructor(scene: Scene, bloomScale:number, bloomKernel:number, pipelineTextureType = 0, performMerge = true, blockCompilation = false) {
+            super(scene.getEngine(), "bloom", ()=>{
                 return this._effects;
                 return this._effects;
             }, true);
             }, true);
-            
-            this.blurX = new BlurPostProcess("horizontal blur", new Vector2(1.0, 0), 10.0, bloomScale, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, undefined, blockCompilation);
-            this.blurX.alwaysForcePOT = true;
-            this.blurX.onActivateObservable.add(() => {
-                let dw = this.blurX.width / scene.getEngine().getRenderWidth(true);
-                this.blurX.kernel = bloomKernel * dw;
+            this._downscale = new PassPostProcess("sceneRenderTarget", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
+
+            this._blurX = new BlurPostProcess("horizontal blur", new Vector2(1.0, 0), 10.0, bloomScale, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, undefined, blockCompilation);
+            this._blurX.alwaysForcePOT = true;
+            this._blurX.onActivateObservable.add(() => {
+                let dw = this._blurX.width / scene.getEngine().getRenderWidth(true);
+                this._blurX.kernel = bloomKernel * dw;
             });
             });
 
 
-            this.blurY = new BlurPostProcess("vertical blur", new Vector2(0, 1.0), 10.0, bloomScale, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, undefined, blockCompilation);
-            this.blurY.alwaysForcePOT = true;
-            this.blurY.autoClear = false;
-            this.blurY.onActivateObservable.add(() => {
-                let dh = this.blurY.height / scene.getEngine().getRenderHeight(true);
-                this.blurY.kernel = bloomKernel * dh;
+            this._blurY = new BlurPostProcess("vertical blur", new Vector2(0, 1.0), 10.0, bloomScale, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, undefined, blockCompilation);
+            this._blurY.alwaysForcePOT = true;
+            this._blurY.autoClear = false;
+            this._blurY.onActivateObservable.add(() => {
+                let dh = this._blurY.height / scene.getEngine().getRenderHeight(true);
+                this._blurY.kernel = bloomKernel * dh;
             });
             });
-            
-            this._merge = new DefaultPipelineMergeMergePostProcess("defaultPipelineMerge", {originalFromInput: this.blurX, bloom: {blurred: this.blurY, weight: 0}}, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
-            this._merge.autoClear = false;
 
 
-            this._effects = [this.blurX, this.blurY, this._merge]
+            this._effects = [this._downscale, this._blurX, this._blurY];
+
+            if(performMerge){
+                this._merge = new DefaultPipelineMergeMergePostProcess("defaultPipelineMerge", {originalFromInput: this._blurX, bloom: {blurred: this._blurY, weight: 0}}, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
+                this._merge.autoClear = false;
+                this._effects.push(this._merge);
+            }
         }
         }
 
 
         /**
         /**
@@ -51,9 +60,9 @@ module BABYLON {
          * @param camera The camera to dispose the effect on.
          * @param camera The camera to dispose the effect on.
          */
          */
         public disposeEffects(camera:Camera){
         public disposeEffects(camera:Camera){
-            this.blurX.dispose(camera);
-            this.blurY.dispose(camera);
-            this._merge.dispose(camera);
+            for(var effect in this._effects){
+                this._effects[effect].dispose(camera);
+            }
         }
         }
         
         
         /**
         /**

+ 9 - 9
src/PostProcess/babylon.defaultPipelineMergePostProcess.ts

@@ -48,18 +48,18 @@ module BABYLON {
             super(name, "defaultPipelineMerge", ["bloomWeight"], ["circleOfConfusionSampler", "blurStep0", "blurStep1", "blurStep2", "bloomBlur"], options, camera, samplingMode, engine, reusable, null, textureType, undefined, null, true);
             super(name, "defaultPipelineMerge", ["bloomWeight"], ["circleOfConfusionSampler", "blurStep0", "blurStep1", "blurStep2", "bloomBlur"], options, camera, samplingMode, engine, reusable, null, textureType, undefined, null, true);
             this._mergeOptions = mergeOptions;
             this._mergeOptions = mergeOptions;
             this.onApplyObservable.add((effect: Effect) => {
             this.onApplyObservable.add((effect: Effect) => {
-                if(mergeOptions.originalFromInput){
-                    effect.setTextureFromPostProcess("textureSampler", mergeOptions.originalFromInput);
+                if(this._mergeOptions.originalFromInput){
+                    effect.setTextureFromPostProcess("textureSampler", this._mergeOptions.originalFromInput);
                 }
                 }
-                if(mergeOptions.depthOfField){
-                    effect.setTextureFromPostProcessOutput("circleOfConfusionSampler", mergeOptions.depthOfField.circleOfConfusion);
-                    mergeOptions.depthOfField.blurSteps.forEach((step,index)=>{
-                        effect.setTextureFromPostProcessOutput("blurStep"+(mergeOptions.depthOfField!.blurSteps.length-index-1), step);
+                if(this._mergeOptions.depthOfField){
+                    effect.setTextureFromPostProcessOutput("circleOfConfusionSampler", this._mergeOptions.depthOfField.circleOfConfusion);
+                    this._mergeOptions.depthOfField.blurSteps.forEach((step,index)=>{
+                        effect.setTextureFromPostProcessOutput("blurStep"+(this._mergeOptions.depthOfField!.blurSteps.length-index-1), step);
                     });
                     });
                 }
                 }
-                if(mergeOptions.bloom){
-                    effect.setTextureFromPostProcessOutput("bloomBlur", mergeOptions.bloom.blurred);
-                    effect.setFloat("bloomWeight", mergeOptions.bloom.weight);
+                if(this._mergeOptions.bloom){
+                    effect.setTextureFromPostProcessOutput("bloomBlur", this._mergeOptions.bloom.blurred);
+                    effect.setFloat("bloomWeight", this._mergeOptions.bloom.weight);
                 }        
                 }        
             });
             });
 
 

+ 20 - 19
src/PostProcess/babylon.depthOfFieldEffect.ts

@@ -21,14 +21,17 @@ module BABYLON {
      */
      */
     export class DepthOfFieldEffect extends PostProcessRenderEffect{
     export class DepthOfFieldEffect extends PostProcessRenderEffect{
         private _circleOfConfusion: CircleOfConfusionPostProcess;
         private _circleOfConfusion: CircleOfConfusionPostProcess;
-        private _depthOfFieldBlurX: Array<DepthOfFieldBlurPostProcess>;
-        private _depthOfFieldBlurY: Array<DepthOfFieldBlurPostProcess>;
         /**
         /**
-         * Private, last post process of dof
+         * Internal, blurs from high to low
          */
          */
-        public _defaultPipelineMerge: DefaultPipelineMergeMergePostProcess;
+        public _depthOfFieldBlurX: Array<DepthOfFieldBlurPostProcess>;
+        private _depthOfFieldBlurY: Array<DepthOfFieldBlurPostProcess>;
+        private _defaultPipelineMerge: Nullable<DefaultPipelineMergeMergePostProcess>;
 
 
-        private _effects: Array<PostProcess> = [];
+        /**
+         * Internal post processes in depth of field effect
+         */
+        public _effects: Array<PostProcess> = [];
 
 
         /**
         /**
          * The focal the length of the camera used in the effect
          * The focal the length of the camera used in the effect
@@ -72,9 +75,10 @@ module BABYLON {
          * @param scene The scene the effect belongs to.
          * @param scene The scene the effect belongs to.
          * @param depthTexture The depth texture of the scene to compute the circle of confusion.This must be set in order for this to function but may be set after initialization if needed.
          * @param depthTexture The depth texture of the scene to compute the circle of confusion.This must be set in order for this to function but may be set after initialization if needed.
          * @param pipelineTextureType The type of texture to be used when performing the post processing.
          * @param pipelineTextureType The type of texture to be used when performing the post processing.
+         * @param performMerge If the finalization merge should be performed by this effect.
          * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
          * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
          */
          */
-        constructor(scene: Scene, depthTexture: Nullable<RenderTargetTexture>, blurLevel: DepthOfFieldEffectBlurLevel = DepthOfFieldEffectBlurLevel.Low, pipelineTextureType = 0, blockCompilation = false) {
+        constructor(scene: Scene, depthTexture: Nullable<RenderTargetTexture>, blurLevel: DepthOfFieldEffectBlurLevel = DepthOfFieldEffectBlurLevel.Low, pipelineTextureType = 0, performMerge = true, blockCompilation = false) {
             super(scene.getEngine(), "depth of field", ()=>{
             super(scene.getEngine(), "depth of field", ()=>{
                 return this._effects;
                 return this._effects;
             }, true);
             }, true);
@@ -114,10 +118,6 @@ module BABYLON {
                 this._depthOfFieldBlurY.push(blurY);
                 this._depthOfFieldBlurY.push(blurY);
                 this._depthOfFieldBlurX.push(blurX);
                 this._depthOfFieldBlurX.push(blurX);
             }
             }
-
-            // Merge blurred images with original image based on circleOfConfusion
-            this._defaultPipelineMerge = new DefaultPipelineMergeMergePostProcess("defaultPipelineMerge", {originalFromInput: this._circleOfConfusion, depthOfField: {circleOfConfusion: this._circleOfConfusion, blurSteps: this._depthOfFieldBlurX}}, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
-            this._defaultPipelineMerge.autoClear = false;
             
             
             // Set all post processes on the effect.
             // Set all post processes on the effect.
             this._effects= [this._circleOfConfusion];
             this._effects= [this._circleOfConfusion];
@@ -125,7 +125,13 @@ module BABYLON {
                 this._effects.push(this._depthOfFieldBlurY[i]);
                 this._effects.push(this._depthOfFieldBlurY[i]);
                 this._effects.push(this._depthOfFieldBlurX[i]);
                 this._effects.push(this._depthOfFieldBlurX[i]);
             }
             }
-            this._effects.push(this._defaultPipelineMerge);
+
+            if(performMerge){
+                // Merge blurred images with original image based on circleOfConfusion
+                this._defaultPipelineMerge = new DefaultPipelineMergeMergePostProcess("defaultPipelineMerge", {originalFromInput: this._circleOfConfusion, depthOfField: {circleOfConfusion: this._circleOfConfusion, blurSteps: this._depthOfFieldBlurX}}, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
+                this._defaultPipelineMerge.autoClear = false;
+                this._effects.push(this._defaultPipelineMerge);
+            }
         }
         }
 
 
         /**
         /**
@@ -140,14 +146,9 @@ module BABYLON {
          * @param camera The camera to dispose the effect on.
          * @param camera The camera to dispose the effect on.
          */
          */
         public disposeEffects(camera:Camera){
         public disposeEffects(camera:Camera){
-            this._circleOfConfusion.dispose(camera);
-            this._depthOfFieldBlurX.forEach(element => {
-                element.dispose(camera);
-            });
-            this._depthOfFieldBlurY.forEach(element => {
-                element.dispose(camera);
-            });
-            this._defaultPipelineMerge.dispose(camera);
+            for(var effect in this._effects){
+                this._effects[effect].dispose(camera);
+            }            
         }
         }
 
 
         /**
         /**