Trevor Baron 7 lat temu
rodzic
commit
c77e8dd423

+ 14 - 1
Tools/Gulp/config.json

@@ -819,7 +819,8 @@
             ],
             "dependUpon": [
                 "additionalPostProcess_blur",
-                "additionalPostProcess_defaultPipelineMerge"
+                "additionalPostProcess_defaultPipelineMerge",
+                "additionalPostProcess_extractHighlights"
             ]
         },
         "additionalPostProcess_fxaa": {
@@ -845,6 +846,17 @@
                 "highlights.fragment"
             ]
         },
+        "additionalPostProcess_extractHighlights": {
+            "files": [
+                "../../src/PostProcess/babylon.extractHighlightsPostProcess.js"
+            ],
+            "dependUpon": [
+                "postProcesses"
+            ],
+            "shaders": [
+                "extractHighlights.fragment"
+            ]
+        },
         "additionalPostProcess_imageProcessing": {
             "files": [
                 "../../src/PostProcess/babylon.imageProcessingPostProcess.js"
@@ -871,6 +883,7 @@
                 "../../src/PostProcess/babylon.tonemapPostProcess.js",
                 "../../src/PostProcess/babylon.displayPassPostProcess.js",
                 "../../src/PostProcess/babylon.highlightsPostProcess.js",
+                "../../src/PostProcess/babylon.extractHighlightsPostProcess.js",
                 "../../src/PostProcess/babylon.imageProcessingPostProcess.js"
             ],
             "dependUpon": [

+ 42 - 6
src/PostProcess/RenderPipeline/Pipelines/babylon.defaultRenderingPipeline.ts

@@ -87,17 +87,30 @@
         }
 
 
+        private _bloomKernel: number = 64;
         /**
 		 * Specifies the size of the bloom blur kernel, relative to the final output size
 		 */
         @serialize()
-        public bloomKernel: number = 64;
+        public get bloomKernel(): number{
+            return this._bloomKernel;
+        }
+        public set bloomKernel(value: number){
+            this._bloomKernel = value;
+            this._rebuildBloom();
+            this._buildPipeline();
+        }
 
         /**
 		 * Specifies the weight of the bloom in the final rendering
 		 */
         @serialize()
         private _bloomWeight: number = 0.15;
+        /**
+		 * Specifies the luma threshold for the area that will be blurred by the bloom
+		 */
+        @serialize()
+        private _bloomThreshold: number = 0.9;
 
         @serialize()
         private _hdr: boolean;
@@ -122,6 +135,23 @@
         }
 
         /**
+         * The strength of the bloom.
+         */
+        public set bloomThreshold(value: number) {
+            if (this._bloomThreshold === value) {
+                return;
+            }
+            this.bloom.threshold = value;
+            
+            this._bloomThreshold = value;
+        }
+
+        @serialize()
+        public get bloomThreshold(): number {
+            return this._bloomThreshold;
+        }
+
+        /**
          * The scale of the bloom, lower value will provide better performance.
          */
         public set bloomScale(value: number) {
@@ -131,11 +161,7 @@
             this._bloomScale = value;
 
             // 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, false);
-            for (var i = 0; i < this._cameras.length; i++) {
-                oldBloom.disposeEffects(this._cameras[i]);
-            }
+            this._rebuildBloom();
 
             this._buildPipeline();
         }
@@ -162,6 +188,16 @@
             return this._bloomEnabled;
         }
 
+        private _rebuildBloom(){
+            // 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, false);
+            this.bloom.threshold = oldBloom.threshold;
+            for (var i = 0; i < this._cameras.length; i++) {
+                oldBloom.disposeEffects(this._cameras[i]);
+            }
+        }
+
         /**
          * If the depth of field is enabled.
          */

+ 18 - 6
src/PostProcess/babylon.bloomEffect.ts

@@ -8,15 +8,24 @@ module BABYLON {
          */
         public _effects: Array<PostProcess> = [];
 
-        /**
-         * Internal
-         */
-        private _downscale:PassPostProcess;
+
+        private _downscale:ExtractHighlightsPostProcess;
         private _blurX:BlurPostProcess;
         private _blurY:BlurPostProcess;
+        private _upscale:PassPostProcess;
         private _merge:Nullable<DefaultPipelineMergeMergePostProcess>;
 
         /**
+         * The luminance threshold to find bright areas of the image to bloom. 
+         */
+        public get threshold():number{
+            return this._downscale.threshold;
+        }
+        public set threshold(value: number){
+            this._downscale.threshold = value;
+        }
+        
+        /**
          * Creates a new instance of @see BloomEffect
          * @param scene The scene the effect belongs to.
          * @param bloomScale The ratio of the blur texture to the input texture that should be used to compute the bloom.
@@ -29,10 +38,11 @@ module BABYLON {
             super(scene.getEngine(), "bloom", ()=>{
                 return this._effects;
             }, true);
-            this._downscale = new PassPostProcess("sceneRenderTarget", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
+            this._downscale = new ExtractHighlightsPostProcess("highlights", 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.autoClear = false;
             this._blurX.onActivateObservable.add(() => {
                 let dw = this._blurX.width / scene.getEngine().getRenderWidth(true);
                 this._blurX.kernel = bloomKernel * dw;
@@ -46,7 +56,9 @@ module BABYLON {
                 this._blurY.kernel = bloomKernel * dh;
             });
 
-            this._effects = [this._downscale, this._blurX, this._blurY];
+            this._upscale = new PassPostProcess("sceneRenderTarget", bloomScale, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
+            this._upscale.autoClear = false;
+            this._effects = [this._downscale, this._blurY, this._blurX, this._upscale];
 
             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);

+ 17 - 0
src/PostProcess/babylon.extractHighlightsPostProcess.ts

@@ -0,0 +1,17 @@
+module BABYLON {
+    /**
+     * The extract highlights post process sets all pixels to black except pixels above the specified luminance threshold. Used as the first step for a bloom effect.
+     */
+    export class ExtractHighlightsPostProcess extends PostProcess {
+        /**
+         * The luminance threshold, pixels below this value will be set to black.
+         */
+        public threshold = 0.9;
+        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, "extractHighlights", ["threshold"], null, options, camera, samplingMode, engine, reusable, null, textureType, undefined, null, blockCompilation);
+            this.onApplyObservable.add((effect: Effect) => {
+                effect.setFloat('threshold', this.threshold);
+            })
+        }
+    }
+} 

+ 1 - 1
src/Shaders/defaultPipelineMerge.fragment.fx

@@ -52,6 +52,6 @@ void main(void)
 #endif
 #ifdef BLOOM
     vec3 blurred = texture2D(bloomBlur, vUV).rgb;
-    gl_FragColor.rgb = mix(gl_FragColor.rgb, blurred, bloomWeight);
+    gl_FragColor.rgb = gl_FragColor.rgb + (blurred.rgb * bloomWeight);
 #endif
 }

+ 15 - 0
src/Shaders/extractHighlights.fragment.fx

@@ -0,0 +1,15 @@
+// Samplers
+varying vec2 vUV;
+uniform sampler2D textureSampler;
+uniform float threshold;
+const vec3 RGBLuminanceCoefficients = vec3(0.2126, 0.7152, 0.0722);
+
+void main(void) 
+{
+	gl_FragColor = texture2D(textureSampler, vUV);
+	vec3 c = gl_FragColor.rgb;
+	float luma = dot(c.rgb, RGBLuminanceCoefficients);
+	if(luma<threshold){
+        gl_FragColor.rgb = vec3(0.,0.,0.);
+    }
+}