瀏覽代碼

Add non linear mode for imageprocessing

David Catuhe 8 年之前
父節點
當前提交
b7389e19dd

File diff suppressed because it is too large
+ 5725 - 5718
dist/preview release/babylon.d.ts


File diff suppressed because it is too large
+ 5725 - 5718
dist/preview release/babylon.module.d.ts


+ 1 - 1
gui/src/controls/control.ts

@@ -879,7 +879,7 @@ module BABYLON.GUI {
         public static AddHeader(control: Control, text: string, size: string | number, options: { isHorizontal: boolean, controlFirst: boolean }): StackPanel {
             let panel = new BABYLON.GUI.StackPanel("panel");        
             let isHorizontal = options ? options.isHorizontal : true;
-            let controlFirst = options ? options.controlFirst : false;
+            let controlFirst = options ? options.controlFirst : true;
 
             panel.isVertical = !isHorizontal;
 

+ 35 - 11
src/PostProcess/RenderPipeline/Pipelines/babylon.defaultRenderingPipeline.ts

@@ -27,7 +27,7 @@
         // Values       
         private _bloomEnabled: boolean = false;
         private _fxaaEnabled: boolean = false;
-        private _imageProcessingEnabled: boolean = false;
+        private _imageProcessingEnabled: boolean = true;
         private _defaultPipelineTextureType: number;
         private _bloomScale: number = 0.6;
 
@@ -104,6 +104,20 @@
             return this._fxaaEnabled;
         }
 
+        public set imageProcessingEnabled(enabled: boolean) {
+            if (this._imageProcessingEnabled === enabled) {
+                return;
+            }
+            this._imageProcessingEnabled = enabled;
+
+            this._buildPipeline();
+        }
+
+        @serialize()
+        public get imageProcessingEnabled(): boolean {
+            return this._imageProcessingEnabled;
+        }        
+
         /**
          * @constructor
          * @param {string} name - The rendering pipeline name
@@ -176,26 +190,36 @@
 				this.copyBack.autoClear = false;
 			}
 
-			this.imageProcessing = new BABYLON.ImageProcessingPostProcess("imageProcessing",  1.0, null, BABYLON.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 BABYLON.ImageProcessingPostProcess("imageProcessing",  1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
+                if (this._hdr) {
+                    this.addEffect(new PostProcessRenderEffect(engine, this.ImageProcessingPostProcessId, () => { return this.imageProcessing; }, true));
+                }
+            }
 
 			if (this.fxaaEnabled) {
                 this.fxaa = new FxaaPostProcess("fxaa", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
-                this.addEffect(new PostProcessRenderEffect(engine, this.FxaaPostProcessId, () => { return this.fxaa; }, true));               
-				this.fxaa.autoClear = false;
+                this.addEffect(new PostProcessRenderEffect(engine, this.FxaaPostProcessId, () => { return this.fxaa; }, true));  
+
+				this.fxaa.autoClear = !this.bloomEnabled && !this.imageProcessing;
 			} else {
 				this.finalMerge = new BABYLON.PassPostProcess("finalMerge", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
                 this.addEffect(new PostProcessRenderEffect(engine, this.FinalMergePostProcessId, () => { return this.finalMerge; }, true)); 
-				this.finalMerge.autoClear = false;
+                
+				this.finalMerge.autoClear = !this.bloomEnabled && !this.imageProcessing;
 			}
 
 			if (this.bloomEnabled) {
 				if (this._hdr) { // Share render targets to save memory
-					this.copyBack.shareOutputWith(this.blurX);		
-					this.imageProcessing.shareOutputWith(this.pass);			
-					this.imageProcessing.autoClear = false;
+					this.copyBack.shareOutputWith(this.blurX);	
+                    if (this.imageProcessing) {	
+					    this.imageProcessing.shareOutputWith(this.pass);			
+					    this.imageProcessing.autoClear = false;
+                    } else if (this.fxaa) {
+						this.fxaa.shareOutputWith(this.pass);		
+					} else {
+						this.finalMerge.shareOutputWith(this.pass);	
+					} 
 				} else  {
 					if (this.fxaa) {
 						this.fxaa.shareOutputWith(this.pass);		

+ 76 - 17
src/PostProcess/babylon.imageProcessingPostProcess.ts

@@ -3,6 +3,7 @@
 		private _colorGradingTexture: BaseTexture;
 		public colorGradingWeight: number = 1.0;
 		public colorCurves = new ColorCurves();
+        private _colorCurvesEnabled = true;
 
         public cameraFov = 0.5;
 
@@ -12,11 +13,14 @@
 		public vignetteWeight = 1.5;
 		public vignetteColor: BABYLON.Color4 = new BABYLON.Color4(0, 0, 0, 0);
 		private _vignetteBlendMode = ImageProcessingPostProcess.VIGNETTEMODE_MULTIPLY;
+        private _vignetteEnabled = true;
 
 		public cameraContrast = 1.0;
-		public cameraExposureValue = 1.5;
+		public cameraExposure = 1.68;
 		private _cameraToneMappingEnabled = true;
 
+        private _fromLinearSpace = false;
+
         public get colorGradingTexture(): BaseTexture {
             return this._colorGradingTexture;
         }
@@ -41,7 +45,46 @@
 
             this._vignetteBlendMode = value;
             this._updateParameters();
-        }     
+        }  
+
+        public get colorCurvesEnabled(): boolean {
+            return this._colorCurvesEnabled;
+        }
+
+        public set colorCurvesEnabled(value: boolean) {
+            if (this._colorCurvesEnabled === value) {
+                return;
+            }
+
+            this._colorCurvesEnabled = value;
+            this._updateParameters();
+        }           
+
+        public get vignetteEnabled(): boolean {
+            return this._vignetteEnabled;
+        }
+
+        public set vignetteEnabled(value: boolean) {
+            if (this._vignetteEnabled === value) {
+                return;
+            }
+
+            this._vignetteEnabled = value;
+            this._updateParameters();
+        }      
+
+        public get fromLinearSpace(): boolean {
+            return this._fromLinearSpace;
+        }
+
+        public set fromLinearSpace(value: boolean) {
+            if (this._fromLinearSpace === value) {
+                return;
+            }
+
+            this._fromLinearSpace = value;
+            this._updateParameters();
+        }              
 
         public get cameraToneMappingEnabled(): boolean {
             return this._cameraToneMappingEnabled;
@@ -75,24 +118,28 @@
                 let aspectRatio = this.aspectRatio;
                 
                 // Color 
-                ColorCurves.Bind(this.colorCurves, effect);
+                if (this._colorCurvesEnabled) {
+                    ColorCurves.Bind(this.colorCurves, effect);
+                }
 
-                // Vignette
-                let vignetteScaleY = Math.tan(this.cameraFov * 0.5);
-                let vignetteScaleX = vignetteScaleY * aspectRatio;
+                if (this._vignetteEnabled) {
+                    // Vignette
+                    let vignetteScaleY = Math.tan(this.cameraFov * 0.5);
+                    let vignetteScaleX = vignetteScaleY * aspectRatio;
 
-                let vignetteScaleGeometricMean = Math.sqrt(vignetteScaleX * vignetteScaleY);
-                vignetteScaleX = Tools.Mix(vignetteScaleX, vignetteScaleGeometricMean, this.vignetteStretch);
-                vignetteScaleY = Tools.Mix(vignetteScaleY, vignetteScaleGeometricMean, this.vignetteStretch);
+                    let vignetteScaleGeometricMean = Math.sqrt(vignetteScaleX * vignetteScaleY);
+                    vignetteScaleX = Tools.Mix(vignetteScaleX, vignetteScaleGeometricMean, this.vignetteStretch);
+                    vignetteScaleY = Tools.Mix(vignetteScaleY, vignetteScaleGeometricMean, this.vignetteStretch);
 
-                effect.setFloat4('vignetteSettings1', vignetteScaleX, vignetteScaleY, -vignetteScaleX * this.vignetteCentreX, -vignetteScaleY * this.vignetteCentreY);
+                    effect.setFloat4('vignetteSettings1', vignetteScaleX, vignetteScaleY, -vignetteScaleX * this.vignetteCentreX, -vignetteScaleY * this.vignetteCentreY);
 
-                let vignettePower = -2.0 * this.vignetteWeight;
-                effect.setFloat4('vignetteSettings2', this.vignetteColor.r, this.vignetteColor.g, this.vignetteColor.b, vignettePower);
+                    let vignettePower = -2.0 * this.vignetteWeight;
+                    effect.setFloat4('vignetteSettings2', this.vignetteColor.r, this.vignetteColor.g, this.vignetteColor.b, vignettePower);
+                }
 
                 // Contrast and exposure
                 effect.setFloat('contrast', this.cameraContrast);
-                effect.setFloat('cameraExposureLinear', Math.pow(2.0, -this.cameraExposureValue) * Math.PI);
+                effect.setFloat('cameraExposureLinear', Math.pow(2.0, -this.cameraExposure) * Math.PI);
                 
                 // Color transform settings
                 if (this._colorGradingTexture) {
@@ -118,16 +165,28 @@
                 samplers.push("txColorTransform");
             }
 
-            if (this.vignetteBlendMode === ImageProcessingPostProcess._VIGNETTEMODE_MULTIPLY) {
-                defines += "#define VIGNETTEBLENDMODEMULTIPLY\r\n";
-            } else {
-                defines += "#define VIGNETTEBLENDMODEOPAQUE\r\n";
+            if (this._vignetteEnabled) {
+                defines += "#define VIGNETTE\r\n";
+
+                if (this.vignetteBlendMode === ImageProcessingPostProcess._VIGNETTEMODE_MULTIPLY) {
+                    defines += "#define VIGNETTEBLENDMODEMULTIPLY\r\n";
+                } else {
+                    defines += "#define VIGNETTEBLENDMODEOPAQUE\r\n";
+                }
             }
 
             if (this.cameraToneMappingEnabled) {
                 defines += "#define TONEMAPPING\r\n";
             }
 
+            if (this._colorCurvesEnabled && this.colorCurves) {
+                defines += "#define COLORCURVES\r\n";
+            }
+
+            if (this._fromLinearSpace) {
+                defines += "#define FROMLINEARSPACE\r\n";
+            }
+
             this.updateEffect(defines, null, samplers);
         }
 

+ 25 - 12
src/Shaders/imageProcessing.fragment.fx

@@ -3,6 +3,7 @@ varying vec2 vUV;
 uniform sampler2D textureSampler;
 
 const float GammaEncodePowerApprox = 1.0 / 2.2;
+const float LinearEncodePowerApprox = 2.2;
 const vec3 RGBLuminanceCoefficients = vec3(0.2126, 0.7152, 0.0722);
 
 uniform float contrast;
@@ -53,23 +54,31 @@ vec3 sampleTexture3D(sampler2D colorTransform, vec3 color)
 
 vec4 applyImageProcessing(vec4 result, vec2 viewportXY){
 
+#ifndef FROMLINEARSPACE
+	// Need to move to linear space for subsequent operations
+	result.rgb = pow(result.rgb, vec3(LinearEncodePowerApprox));
+#endif
+
 	result.rgb *= cameraExposureLinear;
 
-	//vignette
-	vec3 vignetteXY1 = vec3(viewportXY * vignetteSettings1.xy + vignetteSettings1.zw, 1.0);
-	float vignetteTerm = dot(vignetteXY1, vignetteXY1);
-	float vignette = pow(vignetteTerm, vignetteSettings2.w);
+#ifdef VIGNETTE
+		//vignette
+		vec3 vignetteXY1 = vec3(viewportXY * vignetteSettings1.xy + vignetteSettings1.zw, 1.0);
+		float vignetteTerm = dot(vignetteXY1, vignetteXY1);
+		float vignette = pow(vignetteTerm, vignetteSettings2.w);
 
-	// Interpolate between the artist 'color' and white based on the physical transmission value 'vignette'.
-	vec3 vignetteColor = vignetteSettings2.rgb;
+		// Interpolate between the artist 'color' and white based on the physical transmission value 'vignette'.
+		vec3 vignetteColor = vignetteSettings2.rgb;
 
-#ifdef VIGNETTEBLENDMODEMULTIPLY
-	vec3 vignetteColorMultiplier = mix(vignetteColor, vec3(1, 1, 1), vignette);
-	result.rgb *= vignetteColorMultiplier;
-#endif
+	#ifdef VIGNETTEBLENDMODEMULTIPLY
+		vec3 vignetteColorMultiplier = mix(vignetteColor, vec3(1, 1, 1), vignette);
+		result.rgb *= vignetteColorMultiplier;
+	#endif
+
+	#ifdef VIGNETTEBLENDMODEOPAQUE
+		result.rgb = mix(vignetteColor, result.rgb, vignette);
+	#endif
 
-#ifdef VIGNETTEBLENDMODEOPAQUE
-	result.rgb = mix(vignetteColor, result.rgb, vignette);
 #endif
 	
 #ifdef TONEMAPPING	
@@ -77,9 +86,11 @@ vec4 applyImageProcessing(vec4 result, vec2 viewportXY){
 	result.rgb = 1.0 - exp2(-tonemappingCalibration * result.rgb);
 #endif
 
+	// Going back to gamma space
 	result.rgb = pow(result.rgb, vec3(GammaEncodePowerApprox));
 	result.rgb = clamp(result.rgb, 0.0, 1.0);
 
+	// Contrast
 	vec3 resultHighContrast = applyEaseInOut(result.rgb);
 
 	if (contrast < 1.0) {
@@ -96,6 +107,7 @@ vec4 applyImageProcessing(vec4 result, vec2 viewportXY){
 	result.rgb = mix(result.rgb, colorTransformOutput, colorTransformSettings.www);
 #endif
 
+#ifdef COLORCURVES
 	// Apply Color Curves
 	float luma = dot(result.rgb, RGBLuminanceCoefficients);
 	vec2 curveMix = clamp(vec2(luma * 3.0 - 1.5, luma * -3.0 + 1.5), vec2(0.0), vec2(1.0));
@@ -103,6 +115,7 @@ vec4 applyImageProcessing(vec4 result, vec2 viewportXY){
 
 	result.rgb *= colorCurve.rgb;
 	result.rgb = mix(vec3(luma), result.rgb, colorCurve.a);
+#endif
 
 	return result;
 }