Browse Source

Merge pull request #4063 from TrevorDev/reflectionLinearFix

convert back to gamma to avoid multiple toLinear conversions
David Catuhe 7 years ago
parent
commit
c136f46844

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

@@ -133,6 +133,7 @@
 - Add onLoadObservable on VideoTexture - [#3845](https://github.com/BabylonJS/Babylon.js/issues/3845) ([sebavan](https://github.com/sebavan))
 - beforeRender is now triggered after the camera updated its state - [#3873](https://github.com/BabylonJS/Babylon.js/issues/3873) ([RaananW](https://github.com/RaananW))
 - Tools.DeepCopy no longer copying getter-only elements - [#3929](https://github.com/BabylonJS/Babylon.js/issues/3929) ([RaananW](https://github.com/RaananW))
+- Reflection and refraction no longer apply a toLinear conversion twice when applying image processing as a post process - [#4060](https://github.com/BabylonJS/Babylon.js/issues/4060) ([trevordev](https://github.com/trevordev))
 - Fix ember.js compatibility in ```PostProcessRenderEffect``` ([sebavan](https://github.com/sebavan))
 
 ## Breaking changes

+ 13 - 1
src/Materials/Textures/babylon.mirrorTexture.ts

@@ -83,11 +83,18 @@
                 this._autoComputeBlurKernel();
             }
         }
+        private _updateGammaSpace(){
+            this.gammaSpace = !this.scene.imageProcessingConfiguration.isEnabled || !this.scene.imageProcessingConfiguration.applyByPostProcess;
+        }
 
-        constructor(name: string, size: number | { width: number, height: number } | { ratio: number }, scene: Scene, generateMipMaps?: boolean, type: number = Engine.TEXTURETYPE_UNSIGNED_INT, samplingMode = Texture.BILINEAR_SAMPLINGMODE, generateDepthBuffer = true) {
+        private _imageProcessingConfigChangeObserver:Nullable<Observer<ImageProcessingConfiguration>>;
+        constructor(name: string, size: number | { width: number, height: number } | { ratio: number }, private scene: Scene, generateMipMaps?: boolean, type: number = Engine.TEXTURETYPE_UNSIGNED_INT, samplingMode = Texture.BILINEAR_SAMPLINGMODE, generateDepthBuffer = true) {
             super(name, size, scene, generateMipMaps, true, type, false, samplingMode, generateDepthBuffer);
 
             this.ignoreCameraViewport = true;
+            
+            this._updateGammaSpace();
+            this._imageProcessingConfigChangeObserver = scene.imageProcessingConfiguration.onUpdateParameters.add(this._updateGammaSpace)
 
             this.onBeforeRenderObservable.add(() => {
                 Matrix.ReflectionToRef(this.mirrorPlane, this._mirrorMatrix);
@@ -193,5 +200,10 @@
 
             return serializationObject;
         }
+
+        public dispose(){
+            super.dispose();
+            this.scene.imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingConfigChangeObserver);
+        }
     }
 } 

+ 13 - 0
src/Materials/babylon.standardMaterial.ts

@@ -87,6 +87,16 @@ module BABYLON {
         public SAMPLER3DGREENDEPTH = false;
         public SAMPLER3DBGRMAP = false;
         public IMAGEPROCESSINGPOSTPROCESS = false;
+        /**
+         * If the reflection texture on this material is in linear color space
+         * @ignore
+         */
+        public IS_REFLECTION_LINEAR = false;
+        /**
+         * If the refraction texture on this material is in linear color space
+         * @ignore
+         */
+        public IS_REFRACTION_LINEAR = false;
         public EXPOSURE = false;
 
         constructor() {
@@ -724,6 +734,9 @@ module BABYLON {
                 }
 
                 this._imageProcessingConfiguration.prepareDefines(defines);
+
+                defines.IS_REFLECTION_LINEAR = (this.reflectionTexture != null && !this.reflectionTexture.gammaSpace);
+                defines.IS_REFRACTION_LINEAR = (this.refractionTexture != null && !this.refractionTexture.gammaSpace);
             }
 
             if (defines._areFresnelDirty) {

+ 58 - 55
src/Shaders/default.fragment.fx

@@ -259,73 +259,76 @@ void main(void) {
 
 #ifdef REFRACTION
 	vec3 refractionVector = normalize(refract(-viewDirectionW, normalW, vRefractionInfos.y));
-#ifdef REFRACTIONMAP_3D
-
-	refractionVector.y = refractionVector.y * vRefractionInfos.w;
+	#ifdef REFRACTIONMAP_3D
+		refractionVector.y = refractionVector.y * vRefractionInfos.w;
 
-	if (dot(refractionVector, viewDirectionW) < 1.0)
-	{
-		refractionColor = textureCube(refractionCubeSampler, refractionVector).rgb * vRefractionInfos.x;
-	}
-#else
-	vec3 vRefractionUVW = vec3(refractionMatrix * (view * vec4(vPositionW + refractionVector * vRefractionInfos.z, 1.0)));
-
-	vec2 refractionCoords = vRefractionUVW.xy / vRefractionUVW.z;
+		if (dot(refractionVector, viewDirectionW) < 1.0) {
+			refractionColor = textureCube(refractionCubeSampler, refractionVector).rgb;
+		}
+	#else
+		vec3 vRefractionUVW = vec3(refractionMatrix * (view * vec4(vPositionW + refractionVector * vRefractionInfos.z, 1.0)));
 
-	refractionCoords.y = 1.0 - refractionCoords.y;
+		vec2 refractionCoords = vRefractionUVW.xy / vRefractionUVW.z;
 
-	refractionColor = texture2D(refraction2DSampler, refractionCoords).rgb * vRefractionInfos.x;
-#endif
+		refractionCoords.y = 1.0 - refractionCoords.y;
+		
+		refractionColor = texture2D(refraction2DSampler, refractionCoords).rgb;
+	#endif
+	#ifdef IS_REFRACTION_LINEAR
+		refractionColor = toGammaSpace(refractionColor);
+	#endif
+	refractionColor *= vRefractionInfos.x;
 #endif
 
-	// Reflection
-	vec3 reflectionColor = vec3(0., 0., 0.);
+// Reflection
+vec3 reflectionColor = vec3(0., 0., 0.);
 
 #ifdef REFLECTION
 	vec3 vReflectionUVW = computeReflectionCoords(vec4(vPositionW, 1.0), normalW);
 
-#ifdef REFLECTIONMAP_3D
-#ifdef ROUGHNESS
-	float bias = vReflectionInfos.y;
-
-#ifdef SPECULARTERM
-	#ifdef SPECULAR
-		#ifdef GLOSSINESS
-			bias *= (1.0 - specularMapColor.a);
+	#ifdef REFLECTIONMAP_3D
+		#ifdef ROUGHNESS
+			float bias = vReflectionInfos.y;
+
+			#ifdef SPECULARTERM
+				#ifdef SPECULAR
+					#ifdef GLOSSINESS
+						bias *= (1.0 - specularMapColor.a);
+					#endif
+				#endif
+			#endif
+
+			reflectionColor = textureCube(reflectionCubeSampler, vReflectionUVW, bias).rgb;
+		#else
+			reflectionColor = textureCube(reflectionCubeSampler, vReflectionUVW).rgb;
 		#endif
-	#endif
-#endif
-
-	reflectionColor = textureCube(reflectionCubeSampler, vReflectionUVW, bias).rgb * vReflectionInfos.x;
-#else
-	reflectionColor = textureCube(reflectionCubeSampler, vReflectionUVW).rgb * vReflectionInfos.x;
-#endif
-
-#else
-	vec2 coords = vReflectionUVW.xy;
-
-#ifdef REFLECTIONMAP_PROJECTION
-	coords /= vReflectionUVW.z;
-#endif
-
-	coords.y = 1.0 - coords.y;
-
-	reflectionColor = texture2D(reflection2DSampler, coords).rgb * vReflectionInfos.x;
-#endif
+	#else
+		vec2 coords = vReflectionUVW.xy;
 
-#ifdef REFLECTIONFRESNEL
-	float reflectionFresnelTerm = computeFresnelTerm(viewDirectionW, normalW, reflectionRightColor.a, reflectionLeftColor.a);
+		#ifdef REFLECTIONMAP_PROJECTION
+			coords /= vReflectionUVW.z;
+		#endif
 
-#ifdef REFLECTIONFRESNELFROMSPECULAR
-#ifdef SPECULARTERM
-	reflectionColor *= specularColor.rgb * (1.0 - reflectionFresnelTerm) + reflectionFresnelTerm * reflectionRightColor.rgb;
-#else
-	reflectionColor *= reflectionLeftColor.rgb * (1.0 - reflectionFresnelTerm) + reflectionFresnelTerm * reflectionRightColor.rgb;
-#endif
-#else
-	reflectionColor *= reflectionLeftColor.rgb * (1.0 - reflectionFresnelTerm) + reflectionFresnelTerm * reflectionRightColor.rgb;
-#endif
-#endif
+		coords.y = 1.0 - coords.y;
+		reflectionColor = texture2D(reflection2DSampler, coords).rgb;
+	#endif
+	#ifdef IS_REFLECTION_LINEAR
+		reflectionColor = toGammaSpace(reflectionColor);
+	#endif
+	reflectionColor *= vReflectionInfos.x;
+	#ifdef REFLECTIONFRESNEL
+		float reflectionFresnelTerm = computeFresnelTerm(viewDirectionW, normalW, reflectionRightColor.a, reflectionLeftColor.a);
+
+		#ifdef REFLECTIONFRESNELFROMSPECULAR
+			#ifdef SPECULARTERM
+				reflectionColor *= specularColor.rgb * (1.0 - reflectionFresnelTerm) + reflectionFresnelTerm * reflectionRightColor.rgb;
+			#else
+				reflectionColor *= reflectionLeftColor.rgb * (1.0 - reflectionFresnelTerm) + reflectionFresnelTerm * reflectionRightColor.rgb;
+			#endif
+		#else
+			reflectionColor *= reflectionLeftColor.rgb * (1.0 - reflectionFresnelTerm) + reflectionFresnelTerm * reflectionRightColor.rgb;
+		#endif
+	#endif
 #endif
 
 #ifdef REFRACTIONFRESNEL