Преглед на файлове

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;
         private _sharpenEffect: PostProcessRenderEffect;
         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.
          */
@@ -107,8 +109,8 @@
             if (this._bloomWeight === value) {
                 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;
@@ -130,7 +132,7 @@
 
             // recreate bloom and dispose old as this setting is not dynamic
             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++) {
                 oldBloom.disposeEffects(this._cameras[i]);
             }
@@ -194,7 +196,7 @@
             // recreate dof and dispose old as this setting is not dynamic
             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.focusDistance = oldDof.focusDistance;
             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._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._chromaticAberrationEffect = new PostProcessRenderEffect(engine, this.ChromaticAberrationPostProcessId, () => { return this.chromaticAberration; }, true);
@@ -364,7 +369,7 @@
             if (!this._buildAllowed) {
                 return;
             }
-
+            
             var engine = this._scene.getEngine();
 
             this._disposePostProcesses();
@@ -377,6 +382,8 @@
             this._prevPostProcess = null;
             this._prevPrevPostProcess = null;
 
+            var mergeOptions = new DefaultPipelineMergePostProcessOptions();
+
             if (this.sharpenEnabled) {
                 if(!this.sharpen.isReady()){
                     this.sharpen.updateEffect();
@@ -391,16 +398,30 @@
                 if(!this.depthOfField._isReady()){
                     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._setAutoClearAndTextureSharing(this.depthOfField._defaultPipelineMerge);
+                this._setAutoClearAndTextureSharing(this.depthOfField._effects[this.depthOfField._effects.length-1]);
             }
-
+            
             if (this.bloomEnabled) {
                 if(!this.bloom._isReady()){
                     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);
             }
+            
+            if(mergeOptions.originalFromInput){
+                this._defaultPipelineMerge._mergeOptions = mergeOptions;
+                this._defaultPipelineMerge.updateEffect();
+                this.addEffect(this._defaultPipelineMergeEffect);
+            }
 
             if (this.fxaaEnabled) {
                 this.fxaa = new FxaaPostProcess("fxaa", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
@@ -408,10 +429,10 @@
                 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 {	
                     this._scene.imageProcessingConfiguration.applyByPostProcess = false;	
                 }	

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

@@ -1,4 +1,8 @@
 module BABYLON {
+    class PipelineChain{
+        effects: Array<PostProcessRenderEffect> = []
+        next: Array<PipelineChain> = []
+    }
     export class PostProcessRenderPipeline {
 
         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
      */
     export class BloomEffect extends PostProcessRenderEffect{
-        private _effects: Array<PostProcess> = [];
-        private blurX:BlurPostProcess;
-        private blurY:BlurPostProcess;
-        
         /**
          * 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
@@ -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 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 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)
          */
-        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;
             }, 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.
          */
         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);
             this._mergeOptions = mergeOptions;
             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{
         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
@@ -72,9 +75,10 @@ module BABYLON {
          * @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 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)
          */
-        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", ()=>{
                 return this._effects;
             }, true);
@@ -114,10 +118,6 @@ module BABYLON {
                 this._depthOfFieldBlurY.push(blurY);
                 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.
             this._effects= [this._circleOfConfusion];
@@ -125,7 +125,13 @@ module BABYLON {
                 this._effects.push(this._depthOfFieldBlurY[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.
          */
         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);
+            }            
         }
 
         /**