From f5277e347df4228fc875acaa3acb9581a30ab43e Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Wed, 26 Jul 2017 00:39:41 -0300 Subject: [PATCH] Fixes to glow and auto exposure, closes #9797, closes #9106 --- drivers/gles3/rasterizer_scene_gles3.cpp | 11 +- drivers/gles3/rasterizer_storage_gles3.cpp | 9 +- drivers/gles3/rasterizer_storage_gles3.h | 9 +- drivers/gles3/shaders/tonemap.glsl | 139 +++++++++++++-------- scene/resources/environment.cpp | 1 + 5 files changed, 107 insertions(+), 62 deletions(-) diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 21bdb217fce..cd74c450f5a 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/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 diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 76df57d410b..4eb44197a79 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/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); diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 7d0f3e57456..b536c9841ce 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/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; diff --git a/drivers/gles3/shaders/tonemap.glsl b/drivers/gles3/shaders/tonemap.glsl index c6dfc6917d9..988e31d1eaa 100644 --- a/drivers/gles3/shaders/tonemap.glsl +++ b/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,8 +228,55 @@ void main() { glow *= glow_intensity; +#endif +#ifdef USE_REINDHART_TONEMAPPER + + color.rgb = tonemap_reindhart(color.rgb,white); + +# if defined(USING_GLOW) + glow = tonemap_reindhart(glow,white); +# endif + +#endif + +#ifdef USE_FILMIC_TONEMAPPER + + color.rgb = tonemap_filmic(color.rgb,white); + +# if defined(USING_GLOW) + glow = tonemap_filmic(glow,white); +# endif + +#endif + +#ifdef USE_ACES_TONEMAPPER + + color.rgb = tonemap_aces(color.rgb); + +# if defined(USING_GLOW) + glow = tonemap_aces(glow); +# endif + +#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) + + color.rgb = clamp(color.rgb,0.0,1.0); + +#if defined(USING_GLOW) + glow = clamp(glow,0.0,1.0); +#endif + #ifdef USE_GLOW_REPLACE color.rgb = glow; @@ -203,7 +285,7 @@ void main() { #ifdef USE_GLOW_SCREEN - color.rgb = clamp((color.rgb + glow) - (color.rgb * glow), 0.0, 1.0); + color.rgb = max((color.rgb + glow) - (color.rgb * glow), vec3(0.0)); #endif @@ -219,60 +301,11 @@ void main() { #endif -#if !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT) && !defined(USE_GLOW_REPLACE) +#if defined(USING_GLOW) && !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT) && !defined(USE_GLOW_REPLACE) + //additive color.rgb+=glow; #endif - -#endif - - -#ifdef USE_REINDHART_TONEMAPPER - - { - color.rgb = ( color.rgb * ( 1.0 + ( color.rgb / ( white) ) ) ) / ( 1.0 + color.rgb ); - - } -#endif - -#ifdef USE_FILMIC_TONEMAPPER - - { - - 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.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; - - color.rgb=coltn/whitetn; - - } -#endif - -#ifdef USE_ACES_TONEMAPPER - - { - 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)); - } - -#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))); - - #ifdef USE_BCS color.rgb = mix(vec3(0.0),color.rgb,bcs.x); diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index ae89d8ed941..accced404b5 100644 --- a/scene/resources/environment.cpp +++ b/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 {