Browse Source

Fixes to glow and auto exposure, closes #9797, closes #9106

Juan Linietsky 8 years ago
parent
commit
f5277e347d

+ 10 - 1
drivers/gles3/rasterizer_scene_gles3.cpp

@@ -3515,7 +3515,6 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
 		glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo); // copy to base level
 		_copy_screen();
 
-		state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_FAR_BLUR, false);
 		state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_FAR_BLUR, false);
 		state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_LOW, false);
 		state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_MEDIUM, false);
@@ -3611,6 +3610,16 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
 		composite_from = storage->frame.current_rt->effects.mip_maps[0].color;
 	}
 
+	if (env->dof_blur_near_enabled || env->dof_blur_far_enabled) {
+		//these needed to disable filtering, reenamble
+		glActiveTexture(GL_TEXTURE0);
+		glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+	}
+
 	if (env->auto_exposure) {
 
 		//compute auto exposure

+ 6 - 3
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -6189,6 +6189,8 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
 			glBindTexture(GL_TEXTURE_2D, rt->effects.mip_maps[i].color);
 
 			int level = 0;
+			int fb_w = w;
+			int fb_h = h;
 
 			while (true) {
 
@@ -6206,13 +6208,15 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
 				level++;
 			}
 
-			glTexStorage2DCustom(GL_TEXTURE_2D, level + 1, color_internal_format, rt->width, rt->height, color_format, color_type);
+			glTexStorage2DCustom(GL_TEXTURE_2D, level + 1, color_internal_format, fb_w, fb_h, color_format, color_type);
 
 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level);
 			glDisable(GL_SCISSOR_TEST);
 			glColorMask(1, 1, 1, 1);
-			glDepthMask(GL_TRUE);
+			if (rt->buffers.active == false) {
+				glDepthMask(GL_TRUE);
+			}
 
 			for (int j = 0; j < rt->effects.mip_maps[i].sizes.size(); j++) {
 
@@ -6235,7 +6239,6 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
 
 				float zero[4] = { 1, 0, 1, 0 };
 				glViewport(0, 0, rt->effects.mip_maps[i].sizes[j].width, rt->effects.mip_maps[i].sizes[j].height);
-
 				glClearBufferfv(GL_COLOR, 0, zero);
 				if (used_depth) {
 					glClearBufferfi(GL_DEPTH_STENCIL, 0, 1.0, 0);

+ 4 - 5
drivers/gles3/rasterizer_storage_gles3.h

@@ -1285,12 +1285,11 @@ public:
 			buffers.fbo = 0;
 			used_in_frame = false;
 
-			flags[RENDER_TARGET_VFLIP] = false;
-			flags[RENDER_TARGET_TRANSPARENT] = false;
-			flags[RENDER_TARGET_NO_3D_EFFECTS] = false;
-			flags[RENDER_TARGET_NO_3D] = false;
-			flags[RENDER_TARGET_NO_SAMPLING] = false;
+			for (int i = 0; i < RENDER_TARGET_FLAG_MAX; i++) {
+				flags[i] = false;
+			}
 			flags[RENDER_TARGET_HDR] = true;
+
 			buffers.active = false;
 			buffers.effects_active = false;
 

+ 78 - 45
drivers/gles3/shaders/tonemap.glsl

@@ -144,6 +144,38 @@ vec4 texture2D_bicubic(sampler2D tex, vec2 uv,int p_lod)
 #endif
 
 
+vec3 tonemap_filmic(vec3 color,float white) {
+
+	float A = 0.15;
+	float B = 0.50;
+	float C = 0.10;
+	float D = 0.20;
+	float E = 0.02;
+	float F = 0.30;
+	float W = 11.2;
+
+	vec3 coltn = ((color*(A*color+C*B)+D*E)/(color*(A*color+B)+D*F))-E/F;
+	float whitetn = ((white*(A*white+C*B)+D*E)/(white*(A*white+B)+D*F))-E/F;
+
+	return coltn/whitetn;
+
+}
+
+vec3 tonemap_aces(vec3 color) {
+	float a = 2.51f;
+	float b = 0.03f;
+	float c = 2.43f;
+	float d = 0.59f;
+	float e = 0.14f;
+	return color = clamp((color*(a*color+b))/(color*(c*color+d)+e),vec3(0.0),vec3(1.0));
+}
+
+vec3 tonemap_reindhart(vec3 color,vec3 white) {
+
+	return ( color * ( 1.0 + ( color / ( white) ) ) ) / ( 1.0 + color );
+}
+
+
 void main() {
 
 	ivec2 coord = ivec2(gl_FragCoord.xy);
@@ -157,8 +189,11 @@ void main() {
 
 	color*=exposure;
 
-
 #if defined(USE_GLOW_LEVEL1) || defined(USE_GLOW_LEVEL2) || defined(USE_GLOW_LEVEL3) || defined(USE_GLOW_LEVEL4) || defined(USE_GLOW_LEVEL5) || defined(USE_GLOW_LEVEL6) || defined(USE_GLOW_LEVEL7)
+#define USING_GLOW
+#endif
+
+#if defined(USING_GLOW)
 	vec3 glow = vec3(0.0);
 
 #ifdef USE_GLOW_LEVEL1
@@ -193,85 +228,83 @@ void main() {
 
 	glow *= glow_intensity;
 
+#endif
 
 
-#ifdef USE_GLOW_REPLACE
+#ifdef USE_REINDHART_TONEMAPPER
 
-	color.rgb = glow;
+	color.rgb = tonemap_reindhart(color.rgb,white);
+
+# if defined(USING_GLOW)
+	glow = tonemap_reindhart(glow,white);
+# endif
 
 #endif
 
-#ifdef USE_GLOW_SCREEN
+#ifdef USE_FILMIC_TONEMAPPER
 
-	color.rgb = clamp((color.rgb + glow) - (color.rgb * glow), 0.0, 1.0);
+	color.rgb = tonemap_filmic(color.rgb,white);
+
+# if defined(USING_GLOW)
+	glow = tonemap_filmic(glow,white);
+# endif
 
 #endif
 
-#ifdef USE_GLOW_SOFTLIGHT
+#ifdef USE_ACES_TONEMAPPER
 
-	{
+	color.rgb = tonemap_aces(color.rgb);
 
-		glow = (glow * 0.5) + 0.5;
-		color.r =  (glow.r <= 0.5) ? (color.r - (1.0 - 2.0 * glow.r) * color.r * (1.0 - color.r)) : (((glow.r > 0.5) && (color.r <= 0.25)) ? (color.r + (2.0 * glow.r - 1.0) * (4.0 * color.r * (4.0 * color.r + 1.0) * (color.r - 1.0) + 7.0 * color.r)) : (color.r + (2.0 * glow.r - 1.0) * (sqrt(color.r) - color.r)));
-		color.g =  (glow.g <= 0.5) ? (color.g - (1.0 - 2.0 * glow.g) * color.g * (1.0 - color.g)) : (((glow.g > 0.5) && (color.g <= 0.25)) ? (color.g + (2.0 * glow.g - 1.0) * (4.0 * color.g * (4.0 * color.g + 1.0) * (color.g - 1.0) + 7.0 * color.g)) : (color.g + (2.0 * glow.g - 1.0) * (sqrt(color.g) - color.g)));
-		color.b =  (glow.b <= 0.5) ? (color.b - (1.0 - 2.0 * glow.b) * color.b * (1.0 - color.b)) : (((glow.b > 0.5) && (color.b <= 0.25)) ? (color.b + (2.0 * glow.b - 1.0) * (4.0 * color.b * (4.0 * color.b + 1.0) * (color.b - 1.0) + 7.0 * color.b)) : (color.b + (2.0 * glow.b - 1.0) * (sqrt(color.b) - color.b)));
-	}
+# if defined(USING_GLOW)
+	glow = tonemap_aces(glow);
+# endif
 
 #endif
 
-#if !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT) && !defined(USE_GLOW_REPLACE)
-	color.rgb+=glow;
-#endif
-
+	//regular Linear -> SRGB conversion
+	vec3 a = vec3(0.055);
+	color.rgb = mix( (vec3(1.0)+a)*pow(color.rgb,vec3(1.0/2.4))-a , 12.92*color.rgb , lessThan(color.rgb,vec3(0.0031308)));
 
+#if defined(USING_GLOW)
+	glow = mix( (vec3(1.0)+a)*pow(glow,vec3(1.0/2.4))-a , 12.92*glow , lessThan(glow,vec3(0.0031308)));
 #endif
 
+//glow needs to be added in SRGB space (together with image space effects)
 
-#ifdef USE_REINDHART_TONEMAPPER
+	color.rgb = clamp(color.rgb,0.0,1.0);
 
-	{
-		color.rgb = ( color.rgb * ( 1.0 + ( color.rgb / ( white) ) ) ) / ( 1.0 + color.rgb );
-
-	}
+#if defined(USING_GLOW)
+	glow = clamp(glow,0.0,1.0);
 #endif
 
-#ifdef USE_FILMIC_TONEMAPPER
+#ifdef USE_GLOW_REPLACE
 
-	{
+	color.rgb = glow;
 
-		float A = 0.15;
-		float B = 0.50;
-		float C = 0.10;
-		float D = 0.20;
-		float E = 0.02;
-		float F = 0.30;
-		float W = 11.2;
+#endif
 
-		vec3 coltn = ((color.rgb*(A*color.rgb+C*B)+D*E)/(color.rgb*(A*color.rgb+B)+D*F))-E/F;
-		float whitetn = ((white*(A*white+C*B)+D*E)/(white*(A*white+B)+D*F))-E/F;
+#ifdef USE_GLOW_SCREEN
 
-		color.rgb=coltn/whitetn;
+	color.rgb = max((color.rgb + glow) - (color.rgb * glow), vec3(0.0));
 
-	}
 #endif
 
-#ifdef USE_ACES_TONEMAPPER
+#ifdef USE_GLOW_SOFTLIGHT
 
 	{
-		float a = 2.51f;
-		float b = 0.03f;
-		float c = 2.43f;
-		float d = 0.59f;
-		float e = 0.14f;
-		color.rgb = clamp((color.rgb*(a*color.rgb+b))/(color.rgb*(c*color.rgb+d)+e),vec3(0.0),vec3(1.0));
+
+		glow = (glow * 0.5) + 0.5;
+		color.r =  (glow.r <= 0.5) ? (color.r - (1.0 - 2.0 * glow.r) * color.r * (1.0 - color.r)) : (((glow.r > 0.5) && (color.r <= 0.25)) ? (color.r + (2.0 * glow.r - 1.0) * (4.0 * color.r * (4.0 * color.r + 1.0) * (color.r - 1.0) + 7.0 * color.r)) : (color.r + (2.0 * glow.r - 1.0) * (sqrt(color.r) - color.r)));
+		color.g =  (glow.g <= 0.5) ? (color.g - (1.0 - 2.0 * glow.g) * color.g * (1.0 - color.g)) : (((glow.g > 0.5) && (color.g <= 0.25)) ? (color.g + (2.0 * glow.g - 1.0) * (4.0 * color.g * (4.0 * color.g + 1.0) * (color.g - 1.0) + 7.0 * color.g)) : (color.g + (2.0 * glow.g - 1.0) * (sqrt(color.g) - color.g)));
+		color.b =  (glow.b <= 0.5) ? (color.b - (1.0 - 2.0 * glow.b) * color.b * (1.0 - color.b)) : (((glow.b > 0.5) && (color.b <= 0.25)) ? (color.b + (2.0 * glow.b - 1.0) * (4.0 * color.b * (4.0 * color.b + 1.0) * (color.b - 1.0) + 7.0 * color.b)) : (color.b + (2.0 * glow.b - 1.0) * (sqrt(color.b) - color.b)));
 	}
 
 #endif
 
-	//regular Linear -> SRGB conversion
-	vec3 a = vec3(0.055);
-	color.rgb = mix( (vec3(1.0)+a)*pow(color.rgb,vec3(1.0/2.4))-a , 12.92*color.rgb , lessThan(color.rgb,vec3(0.0031308)));
-
+#if defined(USING_GLOW) && !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT) && !defined(USE_GLOW_REPLACE)
+	//additive
+	color.rgb+=glow;
+#endif
 
 #ifdef USE_BCS
 

+ 1 - 0
scene/resources/environment.cpp

@@ -167,6 +167,7 @@ void Environment::set_tonemap_auto_exposure(bool p_enabled) {
 
 	tonemap_auto_exposure = p_enabled;
 	VS::get_singleton()->environment_set_tonemap(environment, VS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey);
+	_change_notify();
 }
 bool Environment::get_tonemap_auto_exposure() const {