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

fixed contrast ceiling

parent 09d75937
......@@ -27,12 +27,15 @@ shared int trimmings;
float delta_L_t(float La) {
// Table 1 of "A Visibility Matching Tone Reproduction Operator for High Dynamic Range Scenes"
float x = log(La)/log(10)+1; // to log_10
float r = 0;
if (x < -3.94) return -2.86;
else if(x < -1.44) return pow(0.405*x+1.6, 2.18) - 2.86;
else if(x < -0.0184) return x - 0.395;
else if(x < 1.9) return pow(0.249*x+0.65, 2.7) - 0.72;
else return x - 1.255;
if (x<=-3.94 ) r = -2.86;
else if(x<=-1.44 ) r = pow(0.405*x+1.6, 2.18) - 2.86;
else if(x<=-0.0184) r = x - 0.395;
else if(x<=1.9 ) r = pow(0.249*x+0.65, 2.7) - 0.72;
else r = x - 1.255;
return pow(10.0, r);
}
float index_to_log_lum(uint index) {
......@@ -82,7 +85,7 @@ void main() {
for(uint i=local_id; i<HISTOGRAM_SLOTS; i+=local_size) {
float L_w = exp(index_to_log_lum(i));
float L_d = exp(DISPLAY_MIN + display_range * float(prefix_sum[i])/sum);
int ceiling = int(floor(delta_L_t(L_d)/delta_L_t(L_w) * total*bin_width*L_w / (display_range*L_d)));
int ceiling = int(round(delta_L_t(L_d)/delta_L_t(L_w) * sum*bin_width*L_w / (display_range*L_d)));
if(local_histogram[i] >= ceiling) {
sub_trimmings += int(local_histogram[i]) - ceiling;
......@@ -106,16 +109,14 @@ void main() {
trimmings = 0;
}
// write result back to global memory
if(total<tolerance) {
for(uint i=local_id; i<HISTOGRAM_SLOTS; i+=local_size) {
local_histogram[i] = 0;
histogram[i] = 10;
}
} else {
for(uint i=local_id; i<HISTOGRAM_SLOTS; i+=local_size) {
histogram[i] = local_histogram[i];
}
memoryBarrierShared();
barrier();
}
// write result back to global memory
for(uint i=local_id; i<HISTOGRAM_SLOTS; i+=local_size) {
histogram[i] = local_histogram[i];
}
}
......@@ -40,7 +40,7 @@ void main() {
float top = HISTOGRAM_SLOTS-1;
for(int i=HISTOGRAM_SLOTS-1; i>0; i--) {
sum += histogram[i];
if(sum < histogram_sum*0.1) {
if(sum < histogram_sum*0.05) {
top = i;
} else {
break;
......@@ -51,13 +51,13 @@ void main() {
float top_log_lum = top/HISTOGRAM_SLOTS * (HISTOGRAM_MAX-HISTOGRAM_MIN) + HISTOGRAM_MIN;
float median_log_lum = median/HISTOGRAM_SLOTS * (HISTOGRAM_MAX-HISTOGRAM_MIN) + HISTOGRAM_MIN;
float target_log_lum = median_log_lum;
float target_log_lum = top_log_lum;
float L = exp(target_log_lum);
float key = 1.03f - (2.0f / (2 + log(L + 1)/log(10)));
float exposure = key/L;
//exposure = exp(target_log_lum);
exposure = exp(target_log_lum);
histogram[HISTOGRAM_SLOTS] = floatBitsToUint(exposure);
}
......
......@@ -43,14 +43,9 @@ void main() {
float prev = imageLoad(adjustment_factor, ivec2(i,0)).r;
float curr_lum = exp(index_to_log_lum(i));
float factor;
if(sum<=0.0001f) {
factor = curr_lum / (curr_lum+1.f) * (exp(DISPLAY_MAX)-exp(DISPLAY_MIN)) + exp(DISPLAY_MIN);
} else {
factor = exp(DISPLAY_MIN + (DISPLAY_MAX-DISPLAY_MIN) * float(prefix_sum[i])/sum)
/ curr_lum;
}
float factor = exp(DISPLAY_MIN + (DISPLAY_MAX-DISPLAY_MIN) * float(prefix_sum[i])/sum);
factor = (factor - exp(DISPLAY_MIN)) / (exp(DISPLAY_MAX)-exp(DISPLAY_MIN));
factor = factor / curr_lum;
factor = mix(prev, factor, global_uniforms.time.z/0.5);
......
......@@ -13,12 +13,20 @@ layout(location = 0) out vec4 out_color;
layout(set=1, binding = 0) uniform sampler2D color_sampler;
void main() {
float min_mesoptic = 0.00031622776f/1.5f;
float max_mesoptic = 3.16227766017f/1.5f;
vec3 grey = vec3(1);
vec3 grey_cie = rgb2cie(grey);
grey /= grey_cie.y * (1.33*(1+(grey_cie.y+grey_cie.z)/grey_cie.x)-1.68);;
vec3 color = textureLod(color_sampler, vertex_out.tex_coords, 0).rgb;
vec3 cie_color = rgb2cie(color);
float scotopic_lum = cie_color.y * (1.33*(1+(cie_color.y+cie_color.z)/cie_color.x)-1.68);
float min_mesoptic = 0.00031622776f/10/2;
float max_mesoptic = 3.16227766017f/10/2;
float alpha = clamp((scotopic_lum-min_mesoptic) / (max_mesoptic-min_mesoptic), 0.25, 1);
out_color = vec4(mix(vec3(scotopic_lum), color, alpha), 1.0);
scotopic_lum = min(scotopic_lum, max_mesoptic);
float alpha = clamp((scotopic_lum*10 - min_mesoptic) / (max_mesoptic-min_mesoptic), 0.1, 1.0);
out_color = vec4(mix(grey * scotopic_lum, color, alpha), 1.0);
}
......@@ -665,7 +665,8 @@ namespace mirrage {
nk_label(ctx, "Trimmings", NK_TEXT_CENTERED);
nk_label(ctx,
std::to_string(static_cast<int>(_window_width * _window_height - histogram_sum))
std::to_string(
static_cast<int>(tone_mapping_pass->max_histogram_size() - histogram_sum))
.c_str(),
NK_TEXT_CENTERED);
......@@ -685,14 +686,14 @@ namespace mirrage {
"Min Display Lum.",
1.f / 255.f / 4.f,
&renderer_settings.min_display_luminance,
1.f,
500.f,
0.001f,
0.01f);
nk_property_float(ctx,
"Max Display Lum.",
1.f / 255.f / 4.f,
&renderer_settings.max_display_luminance,
1.f,
500.f,
0.001f,
0.01f);
......
......@@ -41,8 +41,8 @@ namespace mirrage::renderer {
float exposure_override = 0.f;
bool histogram_adjustment = true;
bool histogram_trim = true;
float min_display_luminance = 0.005f;
float max_display_luminance = 0.9f;
float min_display_luminance = 2.f;
float max_display_luminance = 150.0f;
bool ssao = true;
bool bloom = true;
......
......@@ -37,6 +37,6 @@ namespace mirrage::renderer {
util::maybe<graphic::Texture_2D&> histogram_adjustment_factors;
float min_luminance = 1e-4f;
float max_luminance = 1e4f;
float max_luminance = 1e6f;
};
} // namespace mirrage::renderer
......@@ -23,6 +23,7 @@ namespace mirrage::renderer {
std::size_t swapchain_image) override;
auto last_histogram() const noexcept -> auto& { return _last_result_data; }
auto max_histogram_size() const noexcept { return _last_max_histogram_size; }
auto name() const noexcept -> const char* override { return "Tone Mapping"; }
......@@ -36,6 +37,7 @@ namespace mirrage::renderer {
int _ready_result = -1;
int _next_result = 0;
std::vector<float> _last_result_data;
std::uint32_t _last_max_histogram_size = 0;
vk::UniqueSampler _sampler;
graphic::Image_descriptor_set_layout _descriptor_set_layout;
......
......@@ -400,6 +400,7 @@ namespace mirrage::renderer {
auto foveal_mip_level =
compute_foveal_mip_level(_src.height(), _renderer.global_uniforms().proj_planes.w);
_last_max_histogram_size = _src.height(foveal_mip_level) * _src.width(foveal_mip_level);
if(foveal_mip_level > 0) {
graphic::generate_mipmaps(command_buffer,
_target.image(),
......@@ -573,8 +574,8 @@ namespace mirrage::renderer {
nullptr);
auto pcs = Push_constants{};
pcs.parameters.x = std::log(std::max(_renderer.settings().min_display_luminance, 0.0001f));
pcs.parameters.y = std::log(_renderer.settings().max_display_luminance);
pcs.parameters.x = std::log(std::max(_renderer.settings().min_display_luminance / 10.f, 0.0001f));
pcs.parameters.y = std::log(_renderer.settings().max_display_luminance / 10.f);
command_buffer.pushConstants(
*_compute_pipeline_layout, vk::ShaderStageFlagBits::eCompute, 0, sizeof(Push_constants), &pcs);
......@@ -632,8 +633,8 @@ namespace mirrage::renderer {
nullptr);
auto pcs = Push_constants{};
pcs.parameters.x = std::log(std::max(_renderer.settings().min_display_luminance, 0.0001f));
pcs.parameters.y = std::log(_renderer.settings().max_display_luminance);
pcs.parameters.x = std::log(std::max(_renderer.settings().min_display_luminance / 10.f, 0.0001f));
pcs.parameters.y = std::log(_renderer.settings().max_display_luminance / 10.f);
command_buffer.pushConstants(
*_compute_pipeline_layout, vk::ShaderStageFlagBits::eCompute, 0, sizeof(Push_constants), &pcs);
......
Markdown is supported
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