Pārlūkot izejas kodu

add grain to default pipeline external to image processing

Trevor Baron 7 gadi atpakaļ
vecāks
revīzija
dd35c940b6

+ 13 - 1
Tools/Gulp/config.json

@@ -804,6 +804,17 @@
                 "chromaticAberration.fragment"
             ]
         },
+        "additionalPostProcess_grain": {
+            "files": [
+                "../../src/PostProcess/babylon.grainPostProcess.js"
+            ],
+            "dependUpon": [
+                "postProcesses"
+            ],
+            "shaders": [
+                "grain.fragment"
+            ]
+        },
         "additionalPostProcess_defaultPipelineMerge": {
             "files": [
                 "../../src/PostProcess/babylon.defaultPipelineMergePostProcess.js"
@@ -888,6 +899,7 @@
                 "../../src/PostProcess/babylon.convolutionPostProcess.js",
                 "../../src/PostProcess/babylon.sharpenPostProcess.js",
                 "../../src/PostProcess/babylon.chromaticAberrationPostProcess.js",
+                "../../src/PostProcess/babylon.grainPostProcess.js",
                 "../../src/PostProcess/babylon.filterPostProcess.js",
                 "../../src/PostProcess/babylon.fxaaPostProcess.js",
                 "../../src/PostProcess/babylon.volumetricLightScatteringPostProcess.js",
@@ -942,7 +954,6 @@
                 "ssao.fragment",
                 "ssao2.fragment",
                 "ssaoCombine.fragment",
-                "chromaticAberration.fragment",
                 "lensHighlights.fragment",
                 "depthOfField.fragment",
                 "standard.fragment"
@@ -956,6 +967,7 @@
                 "renderingPipeline",
                 "additionalPostProcess_fxaa",
                 "additionalPostProcess_chromaticAberration",
+                "additionalPostProcess_grain",
                 "additionalPostProcess_sharpen",
                 "additionalPostProcess_depthOfFieldEffect",
                 "additionalPostProcess_bloomEffect"

+ 43 - 0
src/PostProcess/RenderPipeline/Pipelines/babylon.defaultRenderingPipeline.ts

@@ -22,6 +22,10 @@
 		 * ID of the chromatic aberration post process,
 		 */
         readonly ChromaticAberrationPostProcessId: string = "ChromaticAberrationPostProcessEffect";
+        /**
+		 * ID of the grain post process,
+		 */
+        readonly GrainPostProcessId: string = "GrainPostProcessEffect";
 
         // Post-processes
         /**
@@ -49,6 +53,11 @@
 		 */
         public chromaticAberration: ChromaticAberrationPostProcess;
         private _chromaticAberrationEffect: PostProcessRenderEffect;
+        /**
+		 * Grain post process which add noise to the image
+		 */
+        public grain: GrainPostProcess;
+        private _grainEffect: PostProcessRenderEffect;
 
         /**
          * Animations which can be used to tweak settings over a period of time
@@ -65,6 +74,7 @@
         private _defaultPipelineTextureType: number;
         private _bloomScale: number = 0.6;
         private _chromaticAberrationEnabled:boolean = false;  
+        private _grainEnabled:boolean = false;  
 
         private _buildAllowed = true;
 
@@ -311,6 +321,22 @@
         public get chromaticAberrationEnabled(): boolean {
             return this._chromaticAberrationEnabled;
         }
+        /**
+         * Enable or disable the grain process from the pipeline
+         */
+        public set grainEnabled(enabled: boolean) {
+            if (this._grainEnabled === enabled) {
+                return;
+            }
+            this._grainEnabled = enabled;
+
+            this._buildPipeline();
+        }
+
+        @serialize()
+        public get grainEnabled(): boolean {
+            return this._grainEnabled;
+        }
 
         /**
          * @constructor
@@ -363,6 +389,9 @@
             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.grain = new GrainPostProcess("Grain", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType, true);
+            this._grainEffect = new PostProcessRenderEffect(engine, this.GrainPostProcessId, () => { return this.grain; }, true);
+
             this._resizeObserver = engine.onResizeObservable.add(()=>{
                 this._hardwareScaleLevel = engine.getHardwareScalingLevel();
                 this.bloomKernel = this.bloomKernel
@@ -495,6 +524,14 @@
                 this._setAutoClearAndTextureSharing(this._defaultPipelineMerge, true);
             }
 
+            if (this.grainEnabled) {
+                if(!this.grain.isReady()){
+                    this.grain.updateEffect();
+                }
+                this.addEffect(this._grainEffect);
+                this._setAutoClearAndTextureSharing(this.grain);
+            }
+
             if (this.chromaticAberrationEnabled) {
                 if(!this.chromaticAberration.isReady()){
                     this.chromaticAberration.updateEffect();
@@ -543,6 +580,10 @@
                         this.chromaticAberration.dispose(camera);
                     }
 
+                    if(this.grain){
+                        this.grain.dispose(camera);
+                    }
+
                     if(this._defaultPipelineMerge){
                         this._defaultPipelineMerge.dispose(camera);
                     }
@@ -559,6 +600,8 @@
                 (<any>this.bloom) = null;
                 (<any>this.chromaticAberration) = null;
                 (<any>this._chromaticAberrationEffect) = null;
+                (<any>this.grain) = null;
+                (<any>this._grainEffect) = null;
             } 
         }
 

+ 34 - 0
src/PostProcess/babylon.grainPostProcess.ts

@@ -0,0 +1,34 @@
+module BABYLON {
+    /**
+     * The GrainPostProcess adds noise to the image at mid luminance levels
+     */
+    export class GrainPostProcess extends PostProcess {
+        /**
+         * The intensity of the grain added (default: 30)
+         */
+        public intensity:number = 30;
+        /**
+         * If the grain should be randomized on every frame
+         */
+        public animated:boolean = false;
+        
+        /**
+         * Creates a new instance of @see GrainPostProcess
+         * @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)
+         * @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(name: string, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT, blockCompilation = false) {
+            super(name, "grain", ["intensity", "animatedSeed"], [], options, camera, samplingMode, engine, reusable, null, textureType, undefined, null, blockCompilation);
+            this.onApplyObservable.add((effect: Effect) => {
+                effect.setFloat('intensity', this.intensity);
+                effect.setFloat('animatedSeed', this.animated ? Math.random() + 1 : 1);
+            })
+        }
+    }
+}

+ 25 - 0
src/Shaders/grain.fragment.fx

@@ -0,0 +1,25 @@
+#include<helperFunctions>
+
+// samplers
+uniform sampler2D textureSampler;	// original color
+
+// uniforms
+uniform float intensity;
+uniform float animatedSeed;
+
+// varyings
+varying vec2 vUV;
+
+void main(void)
+{
+    gl_FragColor = texture2D(textureSampler, vUV);
+	vec2 seed = vUV*(animatedSeed);
+    float grain = dither(seed, intensity);
+
+    // Add less grain when luminance is high or low
+    float lum = getLuminance(gl_FragColor.rgb);
+    float grainAmount = (cos(-PI + (lum*PI*2.))+1.)/2.;
+    gl_FragColor.rgb += grain * grainAmount;
+
+    gl_FragColor.rgb = max(gl_FragColor.rgb, 0.0);
+}