From eb3840a3f88dd9902ff1c5ea50d90a7f33e08d82 Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Mon, 25 Jan 2016 13:33:22 +0100 Subject: [PATCH] Filmic HDR tone mapping --- builtin/settingtypes.txt | 5 ++ .../shaders/nodes_shader/opengl_fragment.glsl | 48 ++++++++++++++--- .../water_surface_shader/opengl_fragment.glsl | 52 ++++++++++++++++--- minetest.conf.example | 6 +++ src/defaultsettings.cpp | 1 + src/shader.cpp | 3 ++ 6 files changed, 101 insertions(+), 14 deletions(-) diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 79a64c2db..eebccf784 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -326,6 +326,11 @@ fsaa (FSAA) enum 0 0,1,2,4,8,16 # Thy only work with the OpenGL video backend. enable_shaders (Shaders) bool true +[****Tone Mapping] + +# Enables filmic tone mapping +tone_mapping (Filmic tone mapping) bool false + [****Bumpmapping] # Enables bumpmapping for textures. Normalmaps need to be supplied by the texture pack diff --git a/client/shaders/nodes_shader/opengl_fragment.glsl b/client/shaders/nodes_shader/opengl_fragment.glsl index b3789e1cb..49befa8d4 100644 --- a/client/shaders/nodes_shader/opengl_fragment.glsl +++ b/client/shaders/nodes_shader/opengl_fragment.glsl @@ -20,6 +20,38 @@ bool normalTexturePresent = false; const float e = 2.718281828459; const float BS = 10.0; +#ifdef ENABLE_TONE_MAPPING + +/* Hable's UC2 Tone mapping parameters + A = 0.22; + B = 0.30; + C = 0.10; + D = 0.20; + E = 0.01; + F = 0.30; + W = 11.2; + equation used: ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F +*/ + +vec3 uncharted2Tonemap(vec3 x) +{ + return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03334; +} + +vec4 applyToneMapping(vec4 color) +{ + color = vec4(pow(color.rgb, vec3(2.2)), color.a); + const float gamma = 1.6; + const float exposureBias = 5.5; + color.rgb = uncharted2Tonemap(exposureBias * color.rgb); + // Precalculated white_scale from + //vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W)); + vec3 whiteScale = vec3(1.036015346); + color.rgb *= whiteScale; + return vec4(pow(color.rgb, vec3(1.0 / gamma)), color.a); +} +#endif + void get_texture_flags() { vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0)); @@ -160,22 +192,26 @@ void main(void) color = base.rgb; #endif + vec4 col = vec4(color.rgb * gl_Color.rgb, 1.0); + #if MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE float alpha = gl_Color.a; - vec4 col = vec4(color.rgb, alpha); - col *= gl_Color; if (fogDistance != 0.0) { float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0)); alpha = mix(alpha, 0.0, d); } - gl_FragColor = vec4(col.rgb, alpha); + col = vec4(col.rgb, alpha); #else - vec4 col = vec4(color.rgb, base.a); - col *= gl_Color; if (fogDistance != 0.0) { float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0)); col = mix(col, skyBgColor, d); } - gl_FragColor = vec4(col.rgb, base.a); + col = vec4(col.rgb, base.a); +#endif + +#ifdef ENABLE_TONE_MAPPING + gl_FragColor = applyToneMapping(col); +#else + gl_FragColor = col; #endif } diff --git a/client/shaders/water_surface_shader/opengl_fragment.glsl b/client/shaders/water_surface_shader/opengl_fragment.glsl index 75751e243..1fa669541 100644 --- a/client/shaders/water_surface_shader/opengl_fragment.glsl +++ b/client/shaders/water_surface_shader/opengl_fragment.glsl @@ -22,6 +22,38 @@ bool texSeamless = false; const float e = 2.718281828459; const float BS = 10.0; +#ifdef ENABLE_TONE_MAPPING + +/* Hable's UC2 Tone mapping parameters + A = 0.22; + B = 0.30; + C = 0.10; + D = 0.20; + E = 0.01; + F = 0.30; + W = 11.2; + equation used: ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F +*/ + +vec3 uncharted2Tonemap(vec3 x) +{ + return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03334; +} + +vec4 applyToneMapping(vec4 color) +{ + color = vec4(pow(color.rgb, vec3(2.2)), color.a); + const float gamma = 1.6; + const float exposureBias = 5.5; + color.rgb = uncharted2Tonemap(exposureBias * color.rgb); + // Precalculated white_scale from + //vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W)); + vec3 whiteScale = vec3(1.036015346); + color.rgb *= whiteScale; + return vec4(pow(color.rgb, vec3(1.0 / gamma)), color.a); +} +#endif + void get_texture_flags() { vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0)); @@ -116,22 +148,26 @@ vec4 base = texture2D(baseTexture, uv).rgba; color = base.rgb; #endif + vec4 col = vec4(color.rgb * gl_Color.rgb, 1.0); + #if MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE float alpha = gl_Color.a; - vec4 col = vec4(color.rgb, alpha); - col *= gl_Color; - if(fogDistance != 0.0){ + if (fogDistance != 0.0) { float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0)); alpha = mix(alpha, 0.0, d); } - gl_FragColor = vec4(col.rgb, alpha); + col = vec4(col.rgb, alpha); #else - vec4 col = vec4(color.rgb, base.a); - col *= gl_Color; - if(fogDistance != 0.0){ + if (fogDistance != 0.0) { float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0)); col = mix(col, skyBgColor, d); } - gl_FragColor = vec4(col.rgb, base.a); + col = vec4(col.rgb, base.a); +#endif + +#ifdef ENABLE_TONE_MAPPING + gl_FragColor = applyToneMapping(col); +#else + gl_FragColor = col; #endif } diff --git a/minetest.conf.example b/minetest.conf.example index 1bf56720e..09e86ef08 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -353,6 +353,12 @@ # type: bool # enable_shaders = true +##### Tone mapping +# Enables filmic tone mapping. +# Requires shaders to be enabled. +# type: bool +# tone_mapping = false + ##### Bumpmapping # Enables bumpmapping for textures. Normalmaps need to be supplied by the texture pack diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 957857976..271214a4f 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -160,6 +160,7 @@ void set_default_settings(Settings *settings) settings->setDefault("texture_clean_transparent", "false"); settings->setDefault("texture_min_size", "64"); settings->setDefault("preload_item_visuals", "false"); + settings->setDefault("tone_mapping", "false"); settings->setDefault("enable_bumpmapping", "false"); settings->setDefault("enable_parallax_occlusion", "false"); settings->setDefault("generate_normalmaps", "false"); diff --git a/src/shader.cpp b/src/shader.cpp index 917d878bb..a2473ffbf 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -764,6 +764,9 @@ ShaderInfo generate_shader(std::string name, u8 material_type, u8 drawtype, else shaders_header += "0\n"; + if (g_settings->getBool("tone_mapping")) + shaders_header += "#define ENABLE_TONE_MAPPING\n"; + if(pixel_program != "") pixel_program = shaders_header + pixel_program; if(vertex_program != "")