fix reinhard tonemapper, modified filmic tonemapper, added internal exposure bias

This commit is contained in:
alex-poe 2018-08-26 12:29:20 +02:00
parent 8c435a343e
commit 5cd00c3780
5 changed files with 21 additions and 17 deletions

View file

@ -3975,7 +3975,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_FILMIC_TONEMAPPER, env->tone_mapper == VS::ENV_TONE_MAPPER_FILMIC); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_FILMIC_TONEMAPPER, env->tone_mapper == VS::ENV_TONE_MAPPER_FILMIC);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_ACES_TONEMAPPER, env->tone_mapper == VS::ENV_TONE_MAPPER_ACES); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_ACES_TONEMAPPER, env->tone_mapper == VS::ENV_TONE_MAPPER_ACES);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_REINDHART_TONEMAPPER, env->tone_mapper == VS::ENV_TONE_MAPPER_REINHARDT); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_REINHARD_TONEMAPPER, env->tone_mapper == VS::ENV_TONE_MAPPER_REINHARD);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::KEEP_3D_LINEAR, storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_KEEP_3D_LINEAR]); state.tonemap_shader.set_conditional(TonemapShaderGLES3::KEEP_3D_LINEAR, storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_KEEP_3D_LINEAR]);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_AUTO_EXPOSURE, env->auto_exposure); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_AUTO_EXPOSURE, env->auto_exposure);
@ -4062,7 +4062,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_AUTO_EXPOSURE, false); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_AUTO_EXPOSURE, false);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_FILMIC_TONEMAPPER, false); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_FILMIC_TONEMAPPER, false);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_ACES_TONEMAPPER, false); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_ACES_TONEMAPPER, false);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_REINDHART_TONEMAPPER, false); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_REINHARD_TONEMAPPER, false);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_LEVEL1, false); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_LEVEL1, false);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_LEVEL2, false); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_LEVEL2, false);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_LEVEL3, false); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_LEVEL3, false);

View file

@ -122,13 +122,16 @@ vec4 texture2D_bicubic(sampler2D tex, vec2 uv, int p_lod) {
#endif #endif
vec3 tonemap_filmic(vec3 color, float white) { vec3 tonemap_filmic(vec3 color, float white) {
const float A = 0.15f; // exposure bias: input scale (color *= bias, white *= bias) to make the brighness consistent with other tonemappers
const float B = 0.50f; // also useful to scale the input to the range that the tonemapper is designed for (some require very high input values)
// has no effect on the curve's general shape or visual properties
const float exposure_bias = 2.0f;
const float A = 0.22f * exposure_bias * exposure_bias; // bias baked into constants for performance
const float B = 0.30f * exposure_bias;
const float C = 0.10f; const float C = 0.10f;
const float D = 0.20f; const float D = 0.20f;
const float E = 0.02f; const float E = 0.01f;
const float F = 0.30f; const float F = 0.30f;
const float W = 11.2f;
vec3 color_tonemapped = ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F; vec3 color_tonemapped = ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F;
float white_tonemapped = ((white * (A * white + C * B) + D * E) / (white * (A * white + B) + D * F)) - E / F; float white_tonemapped = ((white * (A * white + C * B) + D * E) / (white * (A * white + B) + D * F)) - E / F;
@ -137,10 +140,11 @@ vec3 tonemap_filmic(vec3 color, float white) {
} }
vec3 tonemap_aces(vec3 color, float white) { vec3 tonemap_aces(vec3 color, float white) {
const float A = 2.51f; const float exposure_bias = 0.85f;
const float B = 0.03f; const float A = 2.51f * exposure_bias * exposure_bias;
const float C = 2.43f; const float B = 0.03f * exposure_bias;
const float D = 0.59f; const float C = 2.43f * exposure_bias * exposure_bias;
const float D = 0.59f * exposure_bias;
const float E = 0.14f; const float E = 0.14f;
vec3 color_tonemapped = (color * (A * color + B)) / (color * (C * color + D) + E); vec3 color_tonemapped = (color * (A * color + B)) / (color * (C * color + D) + E);
@ -149,8 +153,8 @@ vec3 tonemap_aces(vec3 color, float white) {
return clamp(color_tonemapped / white_tonemapped, vec3(0.0f), vec3(1.0f)); return clamp(color_tonemapped / white_tonemapped, vec3(0.0f), vec3(1.0f));
} }
vec3 tonemap_reindhart(vec3 color, float white) { vec3 tonemap_reinhard(vec3 color, float white) {
return clamp((color) / (1.0f + color) * (1.0f + (color / (white))), vec3(0.0f), vec3(1.0f)); // whitepoint is probably not in linear space here! return clamp((white * color + color) / (color * white + white), vec3(0.0f), vec3(1.0f));
} }
vec3 linear_to_srgb(vec3 color) { // convert linear rgb to srgb, assumes clamped input in range [0;1] vec3 linear_to_srgb(vec3 color) { // convert linear rgb to srgb, assumes clamped input in range [0;1]
@ -159,8 +163,8 @@ vec3 linear_to_srgb(vec3 color) { // convert linear rgb to srgb, assumes clamped
} }
vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR, always outputs clamped [0;1] color vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR, always outputs clamped [0;1] color
#ifdef USE_REINDHART_TONEMAPPER #ifdef USE_REINHARD_TONEMAPPER
return tonemap_reindhart(color, white); return tonemap_reinhard(color, white);
#endif #endif
#ifdef USE_FILMIC_TONEMAPPER #ifdef USE_FILMIC_TONEMAPPER

View file

@ -961,7 +961,7 @@ void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_grey"), &Environment::get_tonemap_auto_exposure_grey); ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_grey"), &Environment::get_tonemap_auto_exposure_grey);
ADD_GROUP("Tonemap", "tonemap_"); ADD_GROUP("Tonemap", "tonemap_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "tonemap_mode", PROPERTY_HINT_ENUM, "Linear,Reindhart,Filmic,Aces"), "set_tonemapper", "get_tonemapper"); ADD_PROPERTY(PropertyInfo(Variant::INT, "tonemap_mode", PROPERTY_HINT_ENUM, "Linear,Reinhard,Filmic,Aces"), "set_tonemapper", "get_tonemapper");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "tonemap_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_exposure", "get_tonemap_exposure"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "tonemap_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_exposure", "get_tonemap_exposure");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "tonemap_white", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_white", "get_tonemap_white"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "tonemap_white", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_white", "get_tonemap_white");
ADD_GROUP("Auto Exposure", "auto_exposure_"); ADD_GROUP("Auto Exposure", "auto_exposure_");

View file

@ -2282,7 +2282,7 @@ void VisualServer::_bind_methods() {
BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_REPLACE); BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_REPLACE);
BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_LINEAR); BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_LINEAR);
BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_REINHARDT); BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_REINHARD);
BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_FILMIC); BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_FILMIC);
BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_ACES); BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_ACES);

View file

@ -735,7 +735,7 @@ public:
enum EnvironmentToneMapper { enum EnvironmentToneMapper {
ENV_TONE_MAPPER_LINEAR, ENV_TONE_MAPPER_LINEAR,
ENV_TONE_MAPPER_REINHARDT, ENV_TONE_MAPPER_REINHARD,
ENV_TONE_MAPPER_FILMIC, ENV_TONE_MAPPER_FILMIC,
ENV_TONE_MAPPER_ACES ENV_TONE_MAPPER_ACES
}; };