瀏覽代碼

add msaa and sharpness effect to default pipeline

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

+ 2 - 1
Tools/Gulp/config.json

@@ -823,6 +823,7 @@
                 "../../src/PostProcess/babylon.refractionPostProcess.js",
                 "../../src/PostProcess/babylon.blackAndWhitePostProcess.js",
                 "../../src/PostProcess/babylon.convolutionPostProcess.js",
+                "../../src/PostProcess/babylon.sharpenPostProcess.js",
                 "../../src/PostProcess/babylon.filterPostProcess.js",
                 "../../src/PostProcess/babylon.fxaaPostProcess.js",
                 "../../src/PostProcess/babylon.volumetricLightScatteringPostProcess.js",
@@ -838,7 +839,7 @@
             "shaders": [
                 "refraction.fragment",
                 "blackAndWhite.fragment",
-                "convolution.fragment",
+                "sharpen.fragment",
                 "filter.fragment",
                 "fxaa.fragment",
                 "volumetricLightScattering.fragment",

+ 7 - 84
dist/preview release/typedocValidationBaseline.json

@@ -1,7 +1,7 @@
 {
-  "errors": 7231,
+  "errors": 7218,
   "babylon.typedoc.json": {
-    "errors": 7231,
+    "errors": 7218,
     "AnimationKeyInterpolation": {
       "Enumeration": {
         "Comments": {
@@ -8113,50 +8113,6 @@
         }
       }
     },
-    "ConvolutionPostProcess": {
-      "Class": {
-        "Comments": {
-          "MissingText": true
-        }
-      },
-      "Property": {
-        "kernel": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "EdgeDetect0Kernel": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "EdgeDetect1Kernel": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "EdgeDetect2Kernel": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "EmbossKernel": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "GaussianKernel": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "SharpenKernel": {
-          "Comments": {
-            "MissingText": true
-          }
-        }
-      }
-    },
     "CubeTexture": {
       "Class": {
         "Comments": {
@@ -8870,6 +8826,11 @@
           "Naming": {
             "NotCamelCase": true
           }
+        },
+        "SharpenPostProcessId": {
+          "Naming": {
+            "NotCamelCase": true
+          }
         }
       }
     },
@@ -14211,13 +14172,6 @@
             "MissingText": true
           }
         }
-      },
-      "Method": {
-        "handleButtonChange": {
-          "Naming": {
-            "NotUnderscoreCamelCase": true
-          }
-        }
       }
     },
     "GenericController": {
@@ -14237,13 +14191,6 @@
             "MissingText": true
           }
         }
-      },
-      "Method": {
-        "handleButtonChange": {
-          "Naming": {
-            "NotUnderscoreCamelCase": true
-          }
-        }
       }
     },
     "GenericPad": {
@@ -20416,13 +20363,6 @@
             "MissingText": true
           }
         }
-      },
-      "Method": {
-        "handleButtonChange": {
-          "Naming": {
-            "NotUnderscoreCamelCase": true
-          }
-        }
       }
     },
     "OimoJSPlugin": {
@@ -37366,13 +37306,6 @@
             "MissingText": true
           }
         }
-      },
-      "Method": {
-        "handleButtonChange": {
-          "Naming": {
-            "NotUnderscoreCamelCase": true
-          }
-        }
       }
     },
     "VolumetricLightScatteringPostProcess": {
@@ -37468,11 +37401,6 @@
         }
       },
       "Method": {
-        "handleButtonChange": {
-          "Naming": {
-            "NotUnderscoreCamelCase": true
-          }
-        },
         "initControllerMesh": {
           "Comments": {
             "MissingText": true
@@ -37578,11 +37506,6 @@
         }
       },
       "Method": {
-        "handleButtonChange": {
-          "Naming": {
-            "NotUnderscoreCamelCase": true
-          }
-        },
         "lerpAxisTransform": {
           "Naming": {
             "NotUnderscoreCamelCase": true

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

@@ -80,7 +80,8 @@
 - Support depth maps for multiple active cameras for post processes like depth of field ([trevordev](https://github.com/trevordev))
 - Integrates depth texture support in the engine ([sebavan](https://github.com/sebavan))
 - NPM package now has a dependency system, updated during build. ([RaananW](https://github.com/RaananW))
-- Default pipeline will use webGL 2.0 anti aliasing by default if supported, default fragment shader will clamp negative values to avoid underflow, webVR post processing will render to eye texture size ([trevordev](https://github.com/trevordev))
+- Default fragment shader will clamp negative values to avoid underflow, webVR post processing will render to eye texture size ([trevordev](https://github.com/trevordev))
+- Add msaa and sharpening options to the default pipeline ([trevordev](https://github.com/trevordev))
 
 ## Bug fixes
 

+ 62 - 3
src/PostProcess/RenderPipeline/Pipelines/babylon.defaultRenderingPipeline.ts

@@ -7,6 +7,10 @@
         private _scene: Scene;
 
         /**
+		 * ID of the sharpen post process,
+		 */
+        readonly SharpenPostProcessId: string = "SharpenPostProcessEffect";
+        /**
 		 * ID of the pass post process used for bloom,
 		 */
         readonly PassPostProcessId: string = "PassPostProcessEffect";
@@ -41,6 +45,10 @@
 
         // Post-processes
         /**
+		 * Sharpen post process which will apply a sharpen convolution to enhance edges
+		 */
+        public sharpen: SharpenPostProcess;
+        /**
 		 * First pass of bloom to capture the original image texture for later use.
 		 */
         public pass: PassPostProcess;
@@ -82,11 +90,13 @@
          */
         public animations: Animation[] = [];
 
-        // Values       
+        // Values   
+        private _sharpenEnabled:boolean = false;    
         private _bloomEnabled: boolean = false;
         private _depthOfFieldEnabled: boolean = false;
         private _depthOfFieldBlurLevel = DepthOfFieldEffectBlurLevel.Low;
         private _fxaaEnabled: boolean = false;
+        private _msaaEnabled: boolean = false;
         private _imageProcessingEnabled: boolean = true;
         private _defaultPipelineTextureType: number;
         private _bloomScale: number = 0.6;
@@ -94,6 +104,24 @@
         private _buildAllowed = true;
 
         /**
+         * Enable or disable the sharpen process from the pipeline
+         */
+        public set sharpenEnabled(enabled: boolean) {
+            if (this._sharpenEnabled === enabled) {
+                return;
+            }
+            this._sharpenEnabled = enabled;
+
+            this._buildPipeline();
+        }
+
+        @serialize()
+        public get sharpenEnabled(): boolean {
+            return this._sharpenEnabled;
+        }
+
+
+        /**
 		 * Specifies the size of the bloom blur kernel, relative to the final output size
 		 */
         @serialize()
@@ -212,6 +240,23 @@
         }
 
         /**
+         * If the multisample anti-aliasing is enabled.
+         */
+        public set msaaEnabled(enabled: boolean) {
+            if (this._msaaEnabled === enabled) {
+                return;
+            }
+            this._msaaEnabled = enabled;
+
+            this._buildPipeline();
+        }
+
+        @serialize()
+        public get msaaEnabled(): boolean {
+            return this._msaaEnabled;
+        }
+
+        /**
          * If image processing is enabled.
          */
         public set imageProcessingEnabled(enabled: boolean) {
@@ -285,6 +330,11 @@
             this._disposePostProcesses();
             this._reset();
 
+            if (this.sharpenEnabled) {
+                this.sharpen = new SharpenPostProcess("sharpen", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
+                this.addEffect(new PostProcessRenderEffect(engine, this.SharpenPostProcessId, () => { return this.sharpen; }, true));
+            }
+
             if(this.depthOfFieldEnabled){
                 // Enable and get current depth map
                 var depthTexture = this._scene.enableDepthRenderer(this._cameras[0]).getDepthMap();
@@ -382,14 +432,22 @@
             if (this._cameras !== null) {
                 this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
             }
-
-            this._enableMSAAOnFirstPostProcess();
+            
+            if(this.msaaEnabled){
+                if(!this._enableMSAAOnFirstPostProcess()){
+                    BABYLON.Tools.Warn("MSAA failed to enable, MSAA is only supported in browsers that support webGL >= 2.0");
+                }
+            }
         }
 
         private _disposePostProcesses(): void {
             for (var i = 0; i < this._cameras.length; i++) {
                 var camera = this._cameras[i];
 
+                if (this.sharpen) {
+                    this.sharpen.dispose(camera);
+                }
+
                 if (this.pass) {
                     this.pass.dispose(camera);
                 }
@@ -427,6 +485,7 @@
                 }
             }
 
+            (<any>this.sharpen) = null;
             (<any>this.pass) = null;
             (<any>this.highlights) = null;
             (<any>this.blurX) = null;

+ 36 - 3
src/PostProcess/babylon.convolutionPostProcess.ts

@@ -1,7 +1,23 @@
 module BABYLON {
+    /**
+     * The ConvolutionPostProcess applies a 3x3 kernel to every pixel of the
+     * input texture to perform effects such as edge detection or sharpening
+     * See http://en.wikipedia.org/wiki/Kernel_(image_processing)
+     */
     export class ConvolutionPostProcess extends PostProcess{
-        constructor(name: string, public kernel: number[], options: number | PostProcessOptions, camera: Camera, samplingMode?: number, engine?: Engine, reusable?: boolean) {
-            super(name, "convolution", ["kernel", "screenSize"], null, options, camera, samplingMode, engine, reusable);
+        /**
+         * Creates a new instance of @see ConvolutionPostProcess
+         * @param name The name of the effect.
+         * @param kernel Array of 9 values corrisponding to the 3x3 kernel to be applied
+         * @param options The required width/height ratio to downsize to before computing the render pass.
+         * @param camera The camera to apply the render pass to.
+         * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
+         * @param engine The engine which the post process will be applied. (default: current engine)
+         * @param reusable If the post process can be reused on the same frame. (default: false)
+         * @param textureType Type of textures used when performing the post process. (default: 0)
+         */
+        constructor(name: string, /** Array of 9 values corrisponding to the 3x3 kernel to be applied */ public kernel: number[], options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT) {
+            super(name, "convolution", ["kernel", "screenSize"], null, options, camera, samplingMode, engine, reusable, null, textureType);
 
             this.onApply = (effect: Effect) => {
                 effect.setFloat2("screenSize", this.width, this.height);
@@ -10,12 +26,29 @@
         }
 
     // Statics
-    // Based on http://en.wikipedia.org/wiki/Kernel_(image_processing)
+    /**
+     * Edge detection 0 see https://en.wikipedia.org/wiki/Kernel_(image_processing)
+     */
     public static EdgeDetect0Kernel = [1, 0, -1, 0, 0, 0, -1, 0, 1];
+    /**
+     * Edge detection 1 see https://en.wikipedia.org/wiki/Kernel_(image_processing)
+     */
     public static EdgeDetect1Kernel = [0, 1, 0, 1, -4, 1, 0, 1, 0];
+    /**
+     * Edge detection 2 see https://en.wikipedia.org/wiki/Kernel_(image_processing)
+     */
     public static EdgeDetect2Kernel = [-1, -1, -1, -1, 8, -1, -1, -1, -1];
+    /**
+     * Kernel to sharpen an image see https://en.wikipedia.org/wiki/Kernel_(image_processing)
+     */
     public static SharpenKernel = [0, -1, 0, -1, 5, -1, 0, -1, 0];
+    /**
+     * Kernel to emboss an image see https://en.wikipedia.org/wiki/Kernel_(image_processing)
+     */
     public static EmbossKernel = [-2, -1, 0, -1, 1, 1, 0, 1, 2];
+    /**
+     * Kernel to blur an image see https://en.wikipedia.org/wiki/Kernel_(image_processing)
+     */
     public static GaussianKernel = [0, 1, 0, 1, 1, 1, 0, 1, 0];
     }
 }

+ 30 - 0
src/PostProcess/babylon.sharpenPostProcess.ts

@@ -0,0 +1,30 @@
+module BABYLON {
+    /**
+     * The SharpenPostProcess applies a sharpen kernel to every pixel
+     * See http://en.wikipedia.org/wiki/Kernel_(image_processing)
+     */
+    export class SharpenPostProcess extends PostProcess{
+        /**
+         * How much sharpness should be applied (default: 0.3)
+         */
+        public amount:number = 0.3;
+        /**
+         * Creates a new instance of @see ConvolutionPostProcess
+         * @param name The name of the effect.
+         * @param options The required width/height ratio to downsize to before computing the render pass.
+         * @param camera The camera to apply the render pass to.
+         * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
+         * @param engine The engine which the post process will be applied. (default: current engine)
+         * @param reusable If the post process can be reused on the same frame. (default: false)
+         * @param textureType Type of textures used when performing the post process. (default: 0)
+         */
+        constructor(name: string, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT) {
+            super(name, "sharpen", ["amount", "screenSize"], null, options, camera, samplingMode, engine, reusable, null, textureType);
+
+            this.onApply = (effect: Effect) => {
+                effect.setFloat2("screenSize", this.width, this.height);
+                effect.setFloat("amount", this.amount);
+            };
+        }
+    }
+}

+ 18 - 0
src/Shaders/sharpen.fragment.fx

@@ -0,0 +1,18 @@
+// Samplers
+varying vec2 vUV;
+uniform sampler2D textureSampler;
+uniform vec2 screenSize;
+uniform float amount;
+
+void main(void)
+{
+	vec2 onePixel = vec2(1.0, 1.0) / screenSize;
+    vec4 color = texture2D(textureSampler, vUV);
+	vec4 edgeDetection = texture2D(textureSampler, vUV + onePixel * vec2(0, -1)) +
+		texture2D(textureSampler, vUV + onePixel * vec2(-1, 0)) +
+		texture2D(textureSampler, vUV + onePixel * vec2(1, 0)) +
+		texture2D(textureSampler, vUV + onePixel * vec2(0, 1)) -
+        color * 4.0;
+	
+	gl_FragColor = max(color - (amount * vec4(edgeDetection.rgb, 0)), 0.);
+}