Commit f252d268 authored by Florian Oetke's avatar Florian Oetke
Browse files

tone mapping cleanup

parent 4be73b9a
......@@ -51,9 +51,6 @@ vec3 ToneMapFilmicALU(vec3 color) {
}
float ha_luminance(vec3 c) {
// return max(sqrt(dot(c*c, vec3(0.299,0.587,0.114))), 0.0);
// return (c.r+c.b+c.g)/3;
vec3 f = vec3(0.2126,0.7152,0.0722);
return max(dot(c, f), 0.0);
}
......@@ -75,16 +72,13 @@ vec3 expose(vec3 color, float threshold) {
}
vec3 tone_mapping(vec3 color) {
if(ADJUST_HISTOGRAM==1 && pcs.options.z<=0) {
if(ADJUST_HISTOGRAM==1 && pcs.options.w>0.001) {
float luminance = ha_luminance(color);
float idx = log(luminance);
idx = clamp(idx, MIN_LOG_LUMINANCE, MAX_LOG_LUMINANCE);
idx = (idx-MIN_LOG_LUMINANCE) / (MAX_LOG_LUMINANCE-MIN_LOG_LUMINANCE);
float new_lum = texture(histogram_adjustment_sampler, vec2(idx, 0.5)).r;
//float new_lum = exp(texelFetch(histogram_adjustment_sampler, ivec2(ceil(idx*textureSize(histogram_adjustment_sampler,0).x), 0),0).r);
//color = color / (luminance*vec3(0.2126,0.7152,0.0722)) * (new_lum*vec3(0.2126,0.7152,0.0722));
color *= new_lum;
color *= texture(histogram_adjustment_sampler, vec2(idx, 0.5)).r;
}
if(pcs.options.x<=0.1 && pcs.options.z<=0)
......@@ -175,6 +169,4 @@ vec3 dither(vec3 color) {
void main() {
//out_color = vec4(tone_mapping(texture(color_sampler, vertex_out.tex_coords).rgb), 1.0);
out_color = vec4(dither(tone_mapping(resolve_fxaa().rgb)), 1.0);
//out_color.rgb = exp(texture(histogram_adjustment_sampler, vec2(vertex_out.tex_coords.x, 0.0)).rrr);
}
......@@ -12,10 +12,7 @@ layout(location = 0) out vec4 out_color;
layout(set=0, binding = 0) uniform sampler2D color_sampler;
float luminance(vec3 c) {
// return max(sqrt(dot(c*c, vec3(0.299,0.587,0.114))), 0.0);
vec3 f = vec3(0.2126,0.7152,0.0722);
//vec3 f = vec3(0.299,0.587,0.114);
return max(dot(c, f), 0.0);
}
......
......@@ -5,15 +5,49 @@
layout (constant_id = 0) const int HISTOGRAM_SLOTS = 256;
layout (constant_id = 2) const float HISTOGRAM_MIN = -10;
layout (constant_id = 3) const float HISTOGRAM_MAX = 10;
layout (constant_id = 4) const float DISPLAY_MIN = 0;
layout (constant_id = 5) const float DISPLAY_MAX = 1;
layout (local_size_x_id = 0, local_size_y = 1, local_size_z = 1 ) in;
layout (local_size_x = 1, local_size_y = 1, local_size_z = 1 ) in;
layout(binding = 1) buffer Data
{
uint histogram[HISTOGRAM_SLOTS + 1];
};
uint calc_total() {
uint sum = 0;
for(uint i=0; i<256; i++) {
sum += histogram[i];
}
return sum;
}
void main() {
// TODO
// TODO: optimize
float total = calc_total();
float world_range = HISTOGRAM_MAX - HISTOGRAM_MIN;
float display_range = DISPLAY_MAX - DISPLAY_MIN;
float bin_width = world_range / HISTOGRAM_SLOTS;
float tolerance = 0.025 * total;
float trimmings = total;
int safe_guard = 0;
while(trimmings>tolerance && total>=tolerance && safe_guard++<100) {
trimmings = 0;
float ceiling = floor(total*bin_width / display_range);
for(uint i=0; i<256; i++) {
if(histogram[i] > ceiling) {
trimmings += histogram[i] - ceiling;
histogram[i] = uint(ceiling);
}
}
total -= trimmings;
}
}
......@@ -36,31 +36,14 @@ void main() {
build_prefix_sum();
// sum up histogram (T) and get min/max
uint min_index = HISTOGRAM_SLOTS;
uint max_index = 0;
for(uint i=1; i<HISTOGRAM_SLOTS; i++) {
if(histogram[i]>0) {
min_index = min(i, min_index);
max_index = max(i, max_index);
}
}
float min_log_lum = index_to_log_lum(min_index);
float max_log_lum = index_to_log_lum(max_index);
float sum = prefix_sum[HISTOGRAM_SLOTS-1] + histogram[HISTOGRAM_SLOTS-1];
// store at i: min + (max-min) * (prefix_sum[i] / T)
for(int i=0; i<HISTOGRAM_SLOTS; i++) {
//float factor = pow(2, log2(0.01) + (log2(1)-log2(0.01)) * float(prefix_sum[i])/sum);
float factor = exp(log(0.001) + (log(1)-log(0.001)) * float(prefix_sum[i])/sum);
//float factor = float(prefix_sum[i])/sum;
factor = factor/exp(index_to_log_lum(i));
float factor = exp(DISPLAY_MIN + (DISPLAY_MAX-DISPLAY_MIN) * float(prefix_sum[i])/sum)
/ exp(index_to_log_lum(i));
imageStore(adjustment_factor, ivec2(i,0), vec4(factor));
histogram[i] = uint(factor*100);
//histogram[i] = uint(factor*100);
}
}
......@@ -470,10 +470,14 @@ namespace mirrage {
nk_property_int(
ctx, "Low-Quality MIP-Levels", 0, &renderer_settings.gi_low_quality_mip_levels, 8, 1, 1);
nk_property_float(ctx, "Exposure", 0.f, &renderer_settings.exposure_override, 50.f, 0.01, 0.1);
nk_property_float(ctx, "Exposure", 0.f, &renderer_settings.exposure_override, 50.f, 0.01f, 0.1f);
bool_nk_wrapper = renderer_settings.histogram_adjustment ? 1 : 0;
nk_checkbox_label(ctx, "Histogram Adjustment", &bool_nk_wrapper);
renderer_settings.histogram_adjustment = bool_nk_wrapper == 1;
nk_property_float(
ctx, "Background Brightness", 0.f, &renderer_settings.background_intensity, 10.f, 1, 0.1);
ctx, "Background Brightness", 0.f, &renderer_settings.background_intensity, 10.f, 1, 0.1f);
bool_nk_wrapper = renderer_settings.ssao ? 1 : 0;
nk_checkbox_label(ctx, "Ambient Occlusion", &bool_nk_wrapper);
......@@ -628,10 +632,10 @@ namespace mirrage {
ctx,
"Histogram",
"Histogram",
_gui.centered_right(500, 650),
_gui.centered_right(400, 600),
NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_TITLE | NK_WINDOW_MINIMIZABLE)) {
nk_layout_row_dynamic(ctx, 500, 1);
nk_layout_row_dynamic(ctx, 400, 1);
nk_chart_begin(ctx,
NK_CHART_COLUMN,
static_cast<int>(histogram.size() - 1),
......@@ -661,6 +665,12 @@ namespace mirrage {
nk_label(ctx, "Exposure", NK_TEXT_CENTERED);
nk_label(ctx, to_fixed_str(histogram.back(), 5).c_str(), NK_TEXT_CENTERED);
nk_label(ctx, "Trimmings", NK_TEXT_CENTERED);
nk_label(ctx,
std::to_string(static_cast<int>(_window_width * _window_height - histogram_sum))
.c_str(),
NK_TEXT_CENTERED);
}
nk_end(ctx);
......
......@@ -39,6 +39,7 @@ namespace mirrage::renderer {
bool gi_jitter_samples = false;
int gi_low_quality_mip_levels = 0;
float exposure_override = 0.f;
bool histogram_adjustment = true;
bool ssao = true;
bool bloom = true;
......
......@@ -123,6 +123,7 @@ namespace mirrage::renderer {
settings.x = _tone_mapping_enabled ? 1 : 0;
settings.y = _bloom_enabled && _renderer.settings().bloom ? 20 : 0;
settings.z = _renderer.settings().exposure_override;
settings.w = _renderer.settings().histogram_adjustment ? 1 : 0;
_render_pass.push_constant("settings"_strid, settings);
......
......@@ -99,15 +99,19 @@ namespace mirrage::renderer {
auto module = assets.load<graphic::Shader_module>(shader);
auto spec_entries =
std::array<vk::SpecializationMapEntry, 4>{vk::SpecializationMapEntry{0, 0 * 32, 32},
std::array<vk::SpecializationMapEntry, 6>{vk::SpecializationMapEntry{0, 0 * 32, 32},
vk::SpecializationMapEntry{1, 1 * 32, 32},
vk::SpecializationMapEntry{2, 2 * 32, 32},
vk::SpecializationMapEntry{3, 3 * 32, 32}};
vk::SpecializationMapEntry{3, 3 * 32, 32},
vk::SpecializationMapEntry{4, 4 * 32, 32},
vk::SpecializationMapEntry{5, 5 * 32, 32}};
auto spec_data = std::array<char, 4 * 32>();
reinterpret_cast<std::int32_t&>(spec_data[0 * 32]) = histogram_slots;
reinterpret_cast<std::int32_t&>(spec_data[1 * 32]) = workgroup_size;
reinterpret_cast<float&>(spec_data[2 * 32]) = std::log(histogram_min);
reinterpret_cast<float&>(spec_data[3 * 32]) = std::log(histogram_max);
reinterpret_cast<float&>(spec_data[4 * 32]) = std::log(0.001f);
reinterpret_cast<float&>(spec_data[5 * 32]) = std::log(1.0f);
auto spec_info = vk::SpecializationInfo{
spec_entries.size(), spec_entries.data(), spec_data.size(), spec_data.data()};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment