diff --git a/CMakeLists.txt b/CMakeLists.txt index a5105e48..e319b6b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -586,6 +586,7 @@ hello_imgui_add_app( src/imageio/qoi.cpp src/imageio/uhdr.cpp src/app.cpp + src/colormap.cpp src/colorspace.cpp src/common.cpp src/emscripten_utils.cpp diff --git a/assets/shaders/colorspaces.glsl b/assets/shaders/colorspaces.glsl index 9b85e865..78451400 100644 --- a/assets/shaders/colorspaces.glsl +++ b/assets/shaders/colorspaces.glsl @@ -36,6 +36,7 @@ float linearToS(float a) } vec3 linearToSRGB(vec3 color) { return vec3(linearToS(color.r), linearToS(color.g), linearToS(color.b)); } +vec4 linearToSRGB(vec4 color) { return vec4(linearToSRGB(color.rgb), color.a); } float sToLinear(float a) { @@ -45,6 +46,7 @@ float sToLinear(float a) } vec3 sRGBToLinear(vec3 color) { return vec3(sToLinear(color.r), sToLinear(color.g), sToLinear(color.b)); } +vec4 sRGBToLinear(vec4 color) { return vec4(sRGBToLinear(color.rgb), color.a); } // returns the luminance of a linear rgb color float RGBToY(vec3 rgb, vec3 weights) { return dot(weights, rgb); } diff --git a/assets/shaders/colorspaces.metal b/assets/shaders/colorspaces.metal index c196dbcf..f997eca4 100644 --- a/assets/shaders/colorspaces.metal +++ b/assets/shaders/colorspaces.metal @@ -36,6 +36,7 @@ float linearToS(float a) } float3 linearToSRGB(float3 color) { return float3(linearToS(color.r), linearToS(color.g), linearToS(color.b)); } +float4 linearToSRGB(float4 color) { return float4(linearToSRGB(color.rgb), color.a); } float sToLinear(float a) { @@ -45,6 +46,7 @@ float sToLinear(float a) } float3 sRGBToLinear(float3 color) { return float3(sToLinear(color.r), sToLinear(color.g), sToLinear(color.b)); } +float4 sRGBToLinear(float4 color) { return float4(sRGBToLinear(color.rgb), color.a); } // returns the luminance of a linear rgb color float RGBToY(float3 rgb, float3 weights) diff --git a/assets/shaders/image-shader_frag.glsl b/assets/shaders/image-shader_frag.glsl index 94a5ef8d..a13ddd3a 100644 --- a/assets/shaders/image-shader_frag.glsl +++ b/assets/shaders/image-shader_frag.glsl @@ -1,14 +1,17 @@ precision mediump float; -// These need to stay in sync with EChannel in fwd.h -#define CHANNEL_RGB 0 -#define CHANNEL_RED 1 -#define CHANNEL_GREEN 2 -#define CHANNEL_BLUE 3 -#define CHANNEL_ALPHA 4 -#define CHANNEL_Y 5 -#define CHANNEL_FALSE_COLOR 6 -#define CHANNEL_POSITIVE_NEGATIVE 7 +// These need to stay in sync with the various enums in fwd.h +#define CHANNEL_RGB 0 +#define CHANNEL_RED 1 +#define CHANNEL_GREEN 2 +#define CHANNEL_BLUE 3 +#define CHANNEL_ALPHA 4 +#define CHANNEL_Y 5 + +#define Tonemap_sRGB 0 +#define Tonemap_Gamma 1 +#define Tonemap_FalseColor 2 +#define Tonemap_PositiveNegative 3 #define NORMAL_BLEND 0 #define MULTIPLY_BLEND 1 @@ -47,11 +50,13 @@ uniform int blend_mode; uniform int channel; uniform float gain; uniform float gamma; -uniform bool sRGB; +uniform int tonemap_mode; uniform bool clamp_to_LDR; uniform int bg_mode; uniform vec4 bg_color; +uniform sampler2D colormap; + uniform sampler2D dither_texture; uniform sampler2D primary_0_texture; @@ -74,11 +79,23 @@ out vec4 frag_color; vec4 tonemap(vec4 color) { - return vec4(sRGB ? linearToSRGB(color.rgb) : sign(color.rgb) * pow(abs(color.rgb), vec3(1.0 / gamma)), color.a); -} -vec4 inv_tonemap(vec4 color) -{ - return vec4(sRGB ? sRGBToLinear(color.rgb) : sign(color.rgb) * pow(abs(color.rgb), vec3(gamma)), color.a); + switch (tonemap_mode) + { + default: return color; + case Tonemap_Gamma: return vec4(sRGBToLinear(sign(color.rgb) * pow(abs(color.rgb), vec3(1.0 / gamma))), color.a); + case Tonemap_FalseColor: + { + float cmap_size = float(textureSize(colormap, 0).x); + float t = mix(0.5 / cmap_size, (cmap_size - 0.5) / cmap_size, dot(color.rgb, vec3(1.0 / 3.0))); + return vec4(sRGBToLinear(texture(colormap, vec2(t, 0.5)).rgb) * color.a, color.a); + } + case Tonemap_PositiveNegative: + { + float cmap_size = float(textureSize(colormap, 0).x); + float t = mix(0.5 / cmap_size, (cmap_size - 0.5) / cmap_size, 0.5 * dot(color.rgb, vec3(1.0 / 3.0)) + 0.5); + return vec4(sRGBToLinear(texture(colormap, vec2(t, 0.5)).rgb) * color.a, color.a); + } + } } float rand_box(vec2 xy) @@ -100,7 +117,6 @@ float rand_tent(vec2 xy) vec4 choose_channel(vec4 rgba) { - float Y = dot(rgba.rgb, primary_yw); switch (channel) { case CHANNEL_RGB: return rgba; @@ -108,9 +124,7 @@ vec4 choose_channel(vec4 rgba) case CHANNEL_GREEN: return vec4(rgba.ggg, 1.0); case CHANNEL_BLUE: return vec4(rgba.bbb, 1.0); case CHANNEL_ALPHA: return vec4(rgba.aaa, 1.0); - case CHANNEL_Y: return vec4(vec3(Y), rgba.a); - case CHANNEL_FALSE_COLOR: return vec4(sRGBToLinear(inferno(saturate(Y))) * rgba.a, rgba.a); - case CHANNEL_POSITIVE_NEGATIVE: return vec4(positiveNegative(Y) * rgba.a, rgba.a); + case CHANNEL_Y: return vec4(vec3(dot(rgba.rgb, primary_yw)), rgba.a); } return rgba; } @@ -159,22 +173,19 @@ void main() float light_gray = (bg_mode == BG_DARK_CHECKER) ? 0.2 : 0.55; float checkerboard = mod(floor(gl_FragCoord.x / 8.0) + floor(gl_FragCoord.y / 8.0), 2.0) == 0.0 ? dark_gray : light_gray; - background.rgb = vec3(checkerboard); + background.rgb = sRGBToLinear(vec3(checkerboard)); } bool in_img = primary_uv.x < 1.0 && primary_uv.y < 1.0 && primary_uv.x > 0.0 && primary_uv.y > 0.0; bool in_ref = secondary_uv.x < 1.0 && secondary_uv.y < 1.0 && secondary_uv.x > 0.0 && secondary_uv.y > 0.0 && has_reference; - if (!in_img && !in_ref) + if (!in_img && !(in_ref && has_reference)) { frag_color = background; return; } - // inverse tonemap the background color so that it appears correct when we blend and tonemap below - background = inv_tonemap(background); - vec4 value = vec4( sample_channel(primary_0_texture, primary_uv, in_img), sample_channel(primary_1_texture, primary_uv, in_img), sample_channel(primary_2_texture, primary_uv, in_img), sample_channel(primary_3_texture, primary_uv, in_img)); @@ -199,8 +210,8 @@ void main() value = blend(value, reference_val); } - vec4 foreground = choose_channel(value * vec4(vec3(gain), 1.0)); - vec4 blended = dither(tonemap(foreground + background * (1.0 - foreground.a))); + vec4 foreground = choose_channel(value) * vec4(vec3(gain), 1.0); + vec4 blended = dither(linearToSRGB(tonemap(foreground) + background * (1.0 - foreground.a))); blended = clamp(blended, clamp_to_LDR ? 0.0 : -64.0, clamp_to_LDR ? 1.0 : 64.0); frag_color = vec4(blended.rgb, 1.0); } \ No newline at end of file diff --git a/assets/shaders/image-shader_frag.metal b/assets/shaders/image-shader_frag.metal index 01219cea..73b48143 100644 --- a/assets/shaders/image-shader_frag.metal +++ b/assets/shaders/image-shader_frag.metal @@ -6,15 +6,18 @@ using namespace metal; -// These need to stay in sync with EChannel in fwd.h +// These need to stay in sync with the various enums in fwd.h #define CHANNEL_RGB 0 #define CHANNEL_RED 1 #define CHANNEL_GREEN 2 #define CHANNEL_BLUE 3 #define CHANNEL_ALPHA 4 #define CHANNEL_Y 5 -#define CHANNEL_FALSE_COLOR 6 -#define CHANNEL_POSITIVE_NEGATIVE 7 + +#define Tonemap_sRGB 0 +#define Tonemap_Gamma 1 +#define Tonemap_FalseColor 2 +#define Tonemap_PositiveNegative 3 #define NORMAL_BLEND 0 #define MULTIPLY_BLEND 1 @@ -51,14 +54,25 @@ struct VertexOut float2 secondary_uv; }; -float4 tonemap(const float4 color, const float gamma, const bool sRGB) -{ - return float4(sRGB ? linearToSRGB(color.rgb) : sign(color.rgb) * pow(abs(color.rgb), float3(1.0 / gamma)), color.a); -} - -float4 inv_tonemap(const float4 color, const float gamma, const bool sRGB) +float4 tonemap(const float4 color, const int mode, const float gamma, texture2d colormap, sampler colormap_sampler) { - return float4(sRGB ? sRGBToLinear(color.rgb) : sign(color.rgb) * pow(abs(color.rgb), float3(gamma)), color.a); + switch (mode) + { + default: return color; + case Tonemap_Gamma: return float4(sRGBToLinear(sign(color.rgb) * pow(abs(color.rgb), float3(1.0 / gamma))), color.a); + case Tonemap_FalseColor: + { + int cmap_size = colormap.get_width(0); + float t = mix(0.5/cmap_size, (cmap_size-0.5)/cmap_size, dot(color.rgb, float3(1.0/3.0))); + return float4(sRGBToLinear(colormap.sample(colormap_sampler, float2(t, 0.5)).rgb) * color.a, color.a); + } + case Tonemap_PositiveNegative: + { + int cmap_size = colormap.get_width(0); + float t = mix(0.5/cmap_size, (cmap_size-0.5)/cmap_size, 0.5 * dot(color.rgb, float3(1.0/3.0)) + 0.5); + return float4(sRGBToLinear(colormap.sample(colormap_sampler, float2(t, 0.5)).rgb) * color.a, color.a); + } + } } float rand_box(float2 xy, texture2d dither_texture, sampler dither_sampler) @@ -80,17 +94,14 @@ float rand_tent(float2 xy, texture2d dither_texture, samp float4 choose_channel(float4 rgba, int channel, const float3 yw) { - float Y = dot(rgba.rgb, yw); switch (channel) { - case CHANNEL_RGB: return rgba; - case CHANNEL_RED: return float4(rgba.rrr, 1.0); - case CHANNEL_GREEN: return float4(rgba.ggg, 1.0); - case CHANNEL_BLUE: return float4(rgba.bbb, 1.0); - case CHANNEL_ALPHA: return float4(rgba.aaa, 1.0); - case CHANNEL_Y: return float4(float3(Y), rgba.a); - case CHANNEL_FALSE_COLOR: return float4(sRGBToLinear(inferno(saturate(Y))) * rgba.a, rgba.a); - case CHANNEL_POSITIVE_NEGATIVE: return float4(positiveNegative(Y) * rgba.a, rgba.a); + case CHANNEL_RGB: return rgba; + case CHANNEL_RED: return float4(rgba.rrr, 1.0); + case CHANNEL_GREEN: return float4(rgba.ggg, 1.0); + case CHANNEL_BLUE: return float4(rgba.bbb, 1.0); + case CHANNEL_ALPHA: return float4(rgba.aaa, 1.0); + case CHANNEL_Y: return float4(float3(dot(rgba.rgb, yw)), rgba.a); } return rgba; } @@ -133,13 +144,15 @@ fragment float4 fragment_main(VertexOut vert [[stage_in]], const constant int &blend_mode, const constant int &channel, const constant float &gain, + const constant int &tonemap_mode, const constant float &gamma, - const constant bool &sRGB, const constant bool &clamp_to_LDR, const constant int &bg_mode, const constant float4 &bg_color, texture2d dither_texture, sampler dither_sampler, + texture2d colormap, + sampler colormap_sampler, texture2d primary_0_texture, texture2d primary_1_texture, texture2d primary_2_texture, @@ -174,17 +187,14 @@ fragment float4 fragment_main(VertexOut vert [[stage_in]], float dark_gray = (bg_mode == BG_DARK_CHECKER) ? 0.1 : 0.5; float light_gray = (bg_mode == BG_DARK_CHECKER) ? 0.2 : 0.55; float checkerboard = (fmod(float(int(floor(vert.position.x / 8.0) + floor(vert.position.y / 8.0))), 2.0) == 0.0) ? dark_gray : light_gray; - background.rgb = float3(checkerboard); + background.rgb = sRGBToLinear(float3(checkerboard)); } bool in_img = all(vert.primary_uv < 1.0) and all(vert.primary_uv > 0.0); bool in_ref = all(vert.secondary_uv < 1.0) and all(vert.secondary_uv > 0.0);// and has_reference; - if (!in_img and !in_ref) + if (!in_img and !(in_ref and has_reference)) return background; - - // inverse tonemap the background color so that it appears correct when we blend and tonemap below - background = inv_tonemap(background, gamma, sRGB); float4 value = float4(sample_channel(primary_0_texture, primary_0_sampler, vert.primary_uv, in_img), sample_channel(primary_1_texture, primary_1_sampler, vert.primary_uv, in_img), @@ -192,7 +202,7 @@ fragment float4 fragment_main(VertexOut vert [[stage_in]], sample_channel(primary_3_texture, primary_3_sampler, vert.primary_uv, in_img)); if (primary_channels_type == YCA_Channels || primary_channels_type == YC_Channels) - value.xyz = YCToRGB(value.xyz, primary_yw); + value.rgb = YCToRGB(value.xyz, primary_yw); value = primary_M_to_Rec709 * value; @@ -204,15 +214,15 @@ fragment float4 fragment_main(VertexOut vert [[stage_in]], sample_channel(secondary_3_texture, secondary_3_sampler, vert.secondary_uv, in_ref)); if (secondary_channels_type == YCA_Channels || secondary_channels_type == YC_Channels) - reference_val.xyz = YCToRGB(reference_val.xyz, secondary_yw); + reference_val.rgb = YCToRGB(reference_val.xyz, secondary_yw); reference_val = secondary_M_to_Rec709 * reference_val; value = blend(value, reference_val, blend_mode); } - float4 foreground = choose_channel(value * float4(float3(gain), 1.0), channel, primary_yw); - float4 blended = dither(tonemap(foreground + background*(1-foreground.a), gamma, sRGB), vert.position.xy, randomness, do_dither, dither_texture, dither_sampler); + float4 foreground = choose_channel(value, channel, primary_yw) * float4(float3(gain), 1.0); + float4 blended = dither(linearToSRGB(tonemap(foreground, tonemap_mode, gamma, colormap, colormap_sampler) + background*(1-foreground.a)), vert.position.xy, randomness, do_dither, dither_texture, dither_sampler); blended = clamp(blended, clamp_to_LDR ? 0.0 : -64.0, clamp_to_LDR ? 1.0 : 64.0); return float4(blended.rgb, 1.0); } \ No newline at end of file diff --git a/resources/sample-colormap.py b/resources/sample-colormap.py new file mode 100755 index 00000000..44339d41 --- /dev/null +++ b/resources/sample-colormap.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 + +import sys +import argparse +import matplotlib.pyplot as plt +import seaborn as sns +import numpy as np + +def srgb_to_linear(srgb): + linear = np.where(srgb <= 0.04045, srgb / 12.92, ((srgb + 0.055) / 1.055) ** 2.4) + return linear + +def linearize(values, do_linearize): + return srgb_to_linear(values) if do_linearize else values + +def get_colormap(name): + try: + return sns.color_palette(name, as_cmap=True) + except ValueError: + raise ValueError(f"Colormap '{name}' not found in Matplotlib or Seaborn.") + +def main(arguments): + parser = argparse.ArgumentParser(description="Sample a colormap at regularly spaced intervals.") + parser.add_argument("name", type=str, help="The name of the matplotlib or seaborn colormap to sample.") + parser.add_argument("-n", "--num-samples", type=int, default=256, help="The number of samples to generate.") + parser.add_argument("-a", "--include-alpha", action="store_true", help="Include the alpha channel in the output.") + parser.add_argument("-l", "--linearize", action="store_true", help="Output linear (instead of sRGB encoded) values.") + + args = parser.parse_args(arguments) + + xs = np.linspace(0, 1, args.num_samples) + print(xs) + + cmap = get_colormap(args.name) + rgba_values = cmap(xs) + + rgb = rgba_values[:, :3] + alpha = rgba_values[:, 3] if rgba_values.shape[1] == 4 else np.ones_like(xs) + values = linearize(rgb, args.linearize) + if args.include_alpha: + values = np.column_stack((values, alpha)) + + values = ",\n ".join(["{" + ", ".join([str(y) + "f" for y in x]) + "}" for x in values]) + "," + print(f"static const std::vector data = {{\n {values}\n}};") + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) \ No newline at end of file diff --git a/src/app.cpp b/src/app.cpp index 3c2f4971..d78af4a8 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -12,6 +12,10 @@ #include "fonts.h" +#include "colormap.h" + +#include "texture.h" + #include "opengl_check.h" #include "colorspace.h" @@ -341,7 +345,7 @@ HDRViewApp::HDRViewApp(std::optional force_exposure, std::optional if (force_gamma.has_value()) m_gamma_live = m_gamma = *force_gamma; else - m_sRGB = true; + m_tonemap = Tonemap_sRGB; if (force_dither.has_value()) m_dither = *force_dither; @@ -360,6 +364,7 @@ HDRViewApp::HDRViewApp(std::optional force_exposure, std::optional m_params.callbacks.BeforeExit = [this] { Image::cleanup_default_textures(); + Colormap::cleanup(); save_settings(); }; @@ -668,7 +673,7 @@ HDRViewApp::HDRViewApp(std::optional force_exposure, std::optional { m_exposure_live = m_exposure = 0.0f; m_gamma_live = m_gamma = 2.2f; - m_sRGB = true; + m_tonemap = Tonemap_sRGB; }}); add_action({"Normalize exposure", ICON_MY_NORMALIZE_EXPOSURE, ImGuiKey_N, 0, [this]() { @@ -697,12 +702,14 @@ HDRViewApp::HDRViewApp(std::optional force_exposure, std::optional add_action({"Draw display window", ICON_MY_DISPLAY_WINDOW, ImGuiKey_None, 0, []() {}, always_enabled, false, &m_draw_display_window}); - add_action({"sRGB", g_blank_icon, 0, 0, []() {}, always_enabled, false, &m_sRGB, - "Use the sRGB non-linear response curve (instead of gamma correction)"}); - add_action({"Decrease gamma", g_blank_icon, ImGuiKey_G, ImGuiInputFlags_Repeat, [this]() - { m_gamma_live = m_gamma = std::max(0.02f, m_gamma - 0.02f); }, [this]() { return !m_sRGB; }}); - add_action({"Increase gamma", g_blank_icon, ImGuiMod_Shift | ImGuiKey_G, ImGuiInputFlags_Repeat, [this]() - { m_gamma_live = m_gamma = std::max(0.02f, m_gamma + 0.02f); }, [this]() { return !m_sRGB; }}); + // add_action({"sRGB", g_blank_icon, 0, 0, []() {}, always_enabled, false, &m_sRGB, + // "Use the sRGB non-linear response curve (instead of gamma correction)"}); + add_action({"Decrease gamma", g_blank_icon, ImGuiKey_G, ImGuiInputFlags_Repeat, + [this]() { m_gamma_live = m_gamma = std::max(0.02f, m_gamma - 0.02f); }, + [this]() { return m_tonemap == Tonemap_Gamma; }}); + add_action({"Increase gamma", g_blank_icon, ImGuiMod_Shift | ImGuiKey_G, ImGuiInputFlags_Repeat, + [this]() { m_gamma_live = m_gamma = std::max(0.02f, m_gamma + 0.02f); }, + [this]() { return m_tonemap == Tonemap_Gamma; }}); add_action({"Pan and zoom", ICON_MY_PAN_ZOOM_TOOL, ImGuiKey_Space, 0, []() @@ -1001,6 +1008,7 @@ void HDRViewApp::setup_rendering() m_render_pass->set_cull_mode(RenderPass::CullMode::Disabled); Image::make_default_textures(); + Colormap::initialize(); m_shader->set_texture("dither_texture", Image::dither_texture()); set_image_textures(); @@ -1038,7 +1046,7 @@ void HDRViewApp::load_settings() m_draw_grid = j.value("draw pixel grid", m_draw_grid); m_exposure_live = m_exposure = j.value("exposure", m_exposure); m_gamma_live = m_gamma = j.value("gamma", m_gamma); - m_sRGB = j.value("sRGB", m_sRGB); + m_tonemap = j.value("tonemap", m_tonemap); m_clamp_to_LDR = j.value("clamp to LDR", m_clamp_to_LDR); m_dither = j.value("dither", m_dither); g_file_list_mode = j.value("file list mode", g_file_list_mode); @@ -1066,7 +1074,7 @@ void HDRViewApp::save_settings() j["draw pixel grid"] = m_draw_grid; j["exposure"] = m_exposure; j["gamma"] = m_gamma; - j["sRGB"] = m_sRGB; + j["tonemap"] = m_tonemap; j["clamp to LDR"] = m_clamp_to_LDR; j["dither"] = m_dither; j["verbosity"] = spdlog::get_level(); @@ -1214,7 +1222,7 @@ void HDRViewApp::draw_menus() ImGui::Separator(); - MenuItem(action("sRGB")); + // MenuItem(action("sRGB")); MenuItem(action("Increase gamma")); MenuItem(action("Decrease gamma")); @@ -1287,10 +1295,12 @@ void HDRViewApp::save_as(const string &filename) const { #if !defined(__EMSCRIPTEN__) std::ofstream os{filename, std::ios_base::binary}; - current_image()->save(os, filename, powf(2.0f, m_exposure_live), m_gamma_live, m_sRGB, m_dither); + current_image()->save(os, filename, powf(2.0f, m_exposure_live), m_gamma_live, m_tonemap == Tonemap_sRGB, + m_dither); #else std::ostringstream os; - current_image()->save(os, filename, powf(2.0f, m_exposure_live), m_gamma_live, m_sRGB, m_dither); + current_image()->save(os, filename, powf(2.0f, m_exposure_live), m_gamma_live, m_tonemap == Tonemap_sRGB, + m_dither); string buffer = os.str(); emscripten_browser_file::download( filename, // the default filename for the browser to save. @@ -1362,21 +1372,27 @@ void HDRViewApp::load_image(const string filename, const string_view buffer) { // convert the buffer (if any) to a string so the async thread has its own copy, // then load from the string or filename depending on whether the buffer is empty - m_pending_images.emplace_back(std::make_shared( - filename, - [buffer_str = string(buffer), filename]() - { - if (buffer_str.empty()) - { - std::ifstream is{std::filesystem::u8path(filename.c_str()), std::ios_base::binary}; - return Image::load(is, filename); - } - else - { - std::istringstream is{buffer_str}; - return Image::load(is, filename); - } - })); + m_pending_images.emplace_back( + std::make_shared(filename, + [buffer_str = string(buffer), filename]() + { + if (buffer_str.empty()) + { + auto u8p = std::filesystem::u8path(filename.c_str()); + if (std::ifstream is{u8p, std::ios_base::binary}) + return Image::load(is, filename); + else + { + spdlog::error("File '{}' doesn't exist.", u8p.string()); + return vector{}; + } + } + else + { + std::istringstream is{buffer_str}; + return Image::load(is, filename); + } + })); // remove any instances of filename from the recent files list until we know it has loaded successfully m_recent_files.erase(std::remove(m_recent_files.begin(), m_recent_files.end(), filename), m_recent_files.end()); @@ -1600,7 +1616,7 @@ static void draw_pixel_color(ConstImagePtr img, const int2 &pixel, int &color_mo auto &group = img->groups[group_idx]; float4 color32 = img->raw_pixel(pixel, target); float4 displayed_color = img->shaded_pixel(pixel, target, powf(2.f, hdrview()->exposure_live()), - hdrview()->gamma_live(), hdrview()->sRGB()); + hdrview()->gamma_live(), hdrview()->tonemap(), hdrview()->colormap()); uint32_t hex = color_f128_to_u32(color_u32_to_f128(color_f128_to_u32(displayed_color))); int4 ldr_color = int4{float4{color_u32_to_f128(hex)} * 255.f}; @@ -2585,7 +2601,7 @@ void HDRViewApp::draw_image() const m_shader->set_uniform("randomness", randomness); m_shader->set_uniform("gain", powf(2.0f, m_exposure_live)); m_shader->set_uniform("gamma", m_gamma_live); - m_shader->set_uniform("sRGB", m_sRGB); + m_shader->set_uniform("tonemap_mode", (int)m_tonemap); m_shader->set_uniform("clamp_to_LDR", m_clamp_to_LDR); m_shader->set_uniform("do_dither", m_dither); @@ -2597,6 +2613,8 @@ void HDRViewApp::draw_image() const m_shader->set_uniform("bg_mode", (int)m_bg_mode); m_shader->set_uniform("bg_color", m_bg_color); + m_shader->set_texture("colormap", Colormap::texture(m_colormap)); + if (reference_image()) { m_shader->set_uniform("has_reference", true); @@ -2641,21 +2659,63 @@ void HDRViewApp::draw_top_toolbar() IconButton(action("Reset tonemapping")); ImGui::SameLine(); - Checkbox(action("sRGB")); - ImGui::SameLine(); - - ImGui::BeginDisabled(m_sRGB); - ImGui::AlignTextToFramePadding(); - ImGui::TextUnformatted("Gamma:"); + ImGui::SetNextItemWidth(HelloImGui::EmSize(7.5)); + ImGui::Combo("##Tonemapping", (int *)&m_tonemap, "sRGB\0Gamma\0Colormap (+)\0Colormap (±)\0"); + ImGui::SetItemTooltip("Set the tonemapping mode."); - ImGui::SameLine(); + switch (m_tonemap) + { + default: break; + case Tonemap_Gamma: + { + ImGui::SameLine(); + ImGui::SetNextItemWidth(HelloImGui::EmSize(8)); + ImGui::SliderFloat("##GammaSlider", &m_gamma_live, 0.02f, 9.f, "%5.3f"); + if (ImGui::IsItemDeactivatedAfterEdit()) + m_gamma = m_gamma_live; + ImGui::SetItemTooltip("Set the exponent for gamma correction."); + } + break; + case Tonemap_FalseColor: + case Tonemap_PositiveNegative: + { + ImGui::SameLine(); + auto p = ImGui::GetCursorScreenPos(); - ImGui::SetNextItemWidth(HelloImGui::EmSize(8)); - ImGui::SliderFloat("##GammaSlider", &m_gamma_live, 0.02f, 9.f, "%5.3f"); - if (ImGui::IsItemDeactivatedAfterEdit()) - m_gamma = m_gamma_live; + if (ImPlot::ColormapButton(Colormap::name(m_colormap), ImVec2(HelloImGui::EmSize(8), ImGui::GetFrameHeight()), + m_colormap)) + ImGui::OpenPopup("colormap_dropdown"); + ImGui::SetItemTooltip("Click to choose a colormap."); - ImGui::EndDisabled(); + ImGui::SetNextWindowPos(ImVec2{p.x, p.y + ImGui::GetFrameHeight()}); + ImGui::PushStyleVarX(ImGuiStyleVar_WindowPadding, ImGui::GetStyle().FramePadding.x); + auto tmp = ImGui::BeginPopup("colormap_dropdown"); + ImGui::PopStyleVar(); + if (tmp) + { + auto maps = {Colormap_Viridis, Colormap_Plasma, Colormap_Inferno, + Colormap_Turbo, Colormap_IceFire, Colormap_CoolWarm}; + for (auto n : maps) + { + const bool is_selected = (m_colormap == n); + if (ImGui::Selectable((string("##") + Colormap::name(n)).c_str(), is_selected, 0, + ImVec2(0, ImGui::GetFrameHeight()))) + m_colormap = n; + ImGui::SameLine(0.f, 0.f); + + ImPlot::ColormapButton( + Colormap::name(n), + ImVec2(HelloImGui::EmSize(8) - ImGui::GetStyle().WindowPadding.x, ImGui::GetFrameHeight()), n); + + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndPopup(); + } + } + break; + } ImGui::SameLine(); if (m_params.rendererBackendOptions.requestFloatBuffer) diff --git a/src/app.h b/src/app.h index 537d644c..681beb47 100644 --- a/src/app.h +++ b/src/app.h @@ -7,6 +7,7 @@ #include "common.h" #include "image.h" +#include "colormap.h" #include "hello_imgui/hello_imgui.h" #include "imgui_ext.h" #include "misc/cpp/imgui_stdlib.h" @@ -147,7 +148,8 @@ class HDRViewApp float &gamma() { return m_gamma; } float &exposure_live() { return m_exposure_live; } float &exposure() { return m_exposure; } - bool &sRGB() { return m_sRGB; } + Tonemap &tonemap() { return m_tonemap; } + Colormap_ &colormap() { return m_colormap; } bool &clamp_to_LDR() { return m_clamp_to_LDR; } bool &dithering_on() { return m_dither; } bool &draw_grid_on() { return m_draw_grid; } @@ -218,7 +220,7 @@ class HDRViewApp float m_exposure = 0.f, m_exposure_live = 0.f, m_gamma = 2.2f, m_gamma_live = 2.2f; AxisScale_ m_x_scale = AxisScale_Asinh, m_y_scale = AxisScale_Linear; - bool m_sRGB = false, m_clamp_to_LDR = false, m_dither = true, m_draw_grid = true, m_draw_pixel_info = true, + bool m_clamp_to_LDR = false, m_dither = true, m_draw_grid = true, m_draw_pixel_info = true, m_draw_watched_pixels = true, m_draw_data_window = true, m_draw_display_window = true; Box2i m_roi = Box2i{int2{0}}, m_roi_live = Box2i{int2{0}}; @@ -229,7 +231,9 @@ class HDRViewApp bool m_auto_fit_data = false; ///< Continually keep the image data window fit within the viewport float m_zoom = 1.f; ///< The zoom factor (image pixel size / logical pixel size) float2 m_offset = {0.f, 0.f}; ///< The panning offset of the image - EChannel m_channel = EChannel::RGB; ///< Which channel to display + EChannel m_channel = EChannel::RGB; ///< Which channel to display + Tonemap m_tonemap = Tonemap_sRGB; + Colormap_ m_colormap = Colormap_Inferno; EBlendMode m_blend_mode = EBlendMode::NORMAL_BLEND; ///< How to blend the current and reference images EBGMode m_bg_mode = EBGMode::BG_DARK_CHECKER; ///< How the background around the image should be rendered float4 m_bg_color = {0.3f, 0.3f, 0.3f, 1.0f}; ///< The background color if m_bg_mode == BG_CUSTOM_COLOR diff --git a/src/colormap.cpp b/src/colormap.cpp new file mode 100644 index 00000000..2a35f764 --- /dev/null +++ b/src/colormap.cpp @@ -0,0 +1,712 @@ +// +// Copyright (C) Wojciech Jarosz. All rights reserved. +// Use of this source code is governed by a BSD-style license that can +// be found in the LICENSE.txt file. +// + +#include "colormap.h" +#include "common.h" +#include "texture.h" + +using std::unique_ptr; +using std::vector; + +static vector> s_values{Colormap_COUNT}; +static unique_ptr s_textures[Colormap_COUNT]; + +void Colormap::initialize() +{ + Colormap_ cmap; + // populate the values from the pre-defined ImPlot colormaps + for (cmap = 0; cmap <= Colormap_Greys; ++cmap) + { + s_values[cmap].resize(ImPlot::GetColormapSize(cmap)); + + for (size_t i = 0; i < s_values[cmap].size(); ++i) s_values[cmap][i] = ImPlot::GetColormapColor(i, cmap); + } + + cmap = Colormap_Inferno; + s_values[cmap] = vector{ + {0.001462f, 0.000466f, 0.013866f, 1.0f}, {0.002267f, 0.00127f, 0.01857f, 1.0f}, + {0.003299f, 0.002249f, 0.024239f, 1.0f}, {0.004547f, 0.003392f, 0.030909f, 1.0f}, + {0.006006f, 0.004692f, 0.038558f, 1.0f}, {0.007676f, 0.006136f, 0.046836f, 1.0f}, + {0.009561f, 0.007713f, 0.055143f, 1.0f}, {0.011663f, 0.009417f, 0.06346f, 1.0f}, + {0.013995f, 0.011225f, 0.071862f, 1.0f}, {0.016561f, 0.013136f, 0.080282f, 1.0f}, + {0.019373f, 0.015133f, 0.088767f, 1.0f}, {0.022447f, 0.017199f, 0.097327f, 1.0f}, + {0.025793f, 0.019331f, 0.10593f, 1.0f}, {0.029432f, 0.021503f, 0.114621f, 1.0f}, + {0.033385f, 0.023702f, 0.123397f, 1.0f}, {0.037668f, 0.025921f, 0.132232f, 1.0f}, + {0.042253f, 0.028139f, 0.141141f, 1.0f}, {0.046915f, 0.030324f, 0.150164f, 1.0f}, + {0.051644f, 0.032474f, 0.159254f, 1.0f}, {0.056449f, 0.034569f, 0.168414f, 1.0f}, + {0.06134f, 0.03659f, 0.177642f, 1.0f}, {0.066331f, 0.038504f, 0.186962f, 1.0f}, + {0.071429f, 0.040294f, 0.196354f, 1.0f}, {0.076637f, 0.041905f, 0.205799f, 1.0f}, + {0.081962f, 0.043328f, 0.215289f, 1.0f}, {0.087411f, 0.044556f, 0.224813f, 1.0f}, + {0.09299f, 0.045583f, 0.234358f, 1.0f}, {0.098702f, 0.046402f, 0.243904f, 1.0f}, + {0.104551f, 0.047008f, 0.25343f, 1.0f}, {0.110536f, 0.047399f, 0.262912f, 1.0f}, + {0.116656f, 0.047574f, 0.272321f, 1.0f}, {0.122908f, 0.047536f, 0.281624f, 1.0f}, + {0.129285f, 0.047293f, 0.290788f, 1.0f}, {0.135778f, 0.046856f, 0.299776f, 1.0f}, + {0.142378f, 0.046242f, 0.308553f, 1.0f}, {0.149073f, 0.045468f, 0.317085f, 1.0f}, + {0.15585f, 0.044559f, 0.325338f, 1.0f}, {0.162689f, 0.043554f, 0.333277f, 1.0f}, + {0.169575f, 0.042489f, 0.340874f, 1.0f}, {0.176493f, 0.041402f, 0.348111f, 1.0f}, + {0.183429f, 0.040329f, 0.354971f, 1.0f}, {0.190367f, 0.039309f, 0.361447f, 1.0f}, + {0.197297f, 0.0384f, 0.367535f, 1.0f}, {0.204209f, 0.037632f, 0.373238f, 1.0f}, + {0.211095f, 0.03703f, 0.378563f, 1.0f}, {0.217949f, 0.036615f, 0.383522f, 1.0f}, + {0.224763f, 0.036405f, 0.388129f, 1.0f}, {0.231538f, 0.036405f, 0.3924f, 1.0f}, + {0.238273f, 0.036621f, 0.396353f, 1.0f}, {0.244967f, 0.037055f, 0.400007f, 1.0f}, + {0.25162f, 0.037705f, 0.403378f, 1.0f}, {0.258234f, 0.038571f, 0.406485f, 1.0f}, + {0.26481f, 0.039647f, 0.409345f, 1.0f}, {0.271347f, 0.040922f, 0.411976f, 1.0f}, + {0.27785f, 0.042353f, 0.414392f, 1.0f}, {0.284321f, 0.043933f, 0.416608f, 1.0f}, + {0.290763f, 0.045644f, 0.418637f, 1.0f}, {0.297178f, 0.04747f, 0.420491f, 1.0f}, + {0.303568f, 0.049396f, 0.422182f, 1.0f}, {0.309935f, 0.051407f, 0.423721f, 1.0f}, + {0.316282f, 0.05349f, 0.425116f, 1.0f}, {0.32261f, 0.055634f, 0.426377f, 1.0f}, + {0.328921f, 0.057827f, 0.427511f, 1.0f}, {0.335217f, 0.06006f, 0.428524f, 1.0f}, + {0.3415f, 0.062325f, 0.429425f, 1.0f}, {0.347771f, 0.064616f, 0.430217f, 1.0f}, + {0.354032f, 0.066925f, 0.430906f, 1.0f}, {0.360284f, 0.069247f, 0.431497f, 1.0f}, + {0.366529f, 0.071579f, 0.431994f, 1.0f}, {0.372768f, 0.073915f, 0.4324f, 1.0f}, + {0.379001f, 0.076253f, 0.432719f, 1.0f}, {0.385228f, 0.078591f, 0.432955f, 1.0f}, + {0.391453f, 0.080927f, 0.433109f, 1.0f}, {0.397674f, 0.083257f, 0.433183f, 1.0f}, + {0.403894f, 0.08558f, 0.433179f, 1.0f}, {0.410113f, 0.087896f, 0.433098f, 1.0f}, + {0.416331f, 0.090203f, 0.432943f, 1.0f}, {0.422549f, 0.092501f, 0.432714f, 1.0f}, + {0.428768f, 0.09479f, 0.432412f, 1.0f}, {0.434987f, 0.097069f, 0.432039f, 1.0f}, + {0.441207f, 0.099338f, 0.431594f, 1.0f}, {0.447428f, 0.101597f, 0.43108f, 1.0f}, + {0.453651f, 0.103848f, 0.430498f, 1.0f}, {0.459875f, 0.106089f, 0.429846f, 1.0f}, + {0.4661f, 0.108322f, 0.429125f, 1.0f}, {0.472328f, 0.110547f, 0.428334f, 1.0f}, + {0.478558f, 0.112764f, 0.427475f, 1.0f}, {0.484789f, 0.114974f, 0.426548f, 1.0f}, + {0.491022f, 0.117179f, 0.425552f, 1.0f}, {0.497257f, 0.119379f, 0.424488f, 1.0f}, + {0.503493f, 0.121575f, 0.423356f, 1.0f}, {0.50973f, 0.123769f, 0.422156f, 1.0f}, + {0.515967f, 0.12596f, 0.420887f, 1.0f}, {0.522206f, 0.12815f, 0.419549f, 1.0f}, + {0.528444f, 0.130341f, 0.418142f, 1.0f}, {0.534683f, 0.132534f, 0.416667f, 1.0f}, + {0.54092f, 0.134729f, 0.415123f, 1.0f}, {0.547157f, 0.136929f, 0.413511f, 1.0f}, + {0.553392f, 0.139134f, 0.411829f, 1.0f}, {0.559624f, 0.141346f, 0.410078f, 1.0f}, + {0.565854f, 0.143567f, 0.408258f, 1.0f}, {0.572081f, 0.145797f, 0.406369f, 1.0f}, + {0.578304f, 0.148039f, 0.404411f, 1.0f}, {0.584521f, 0.150294f, 0.402385f, 1.0f}, + {0.590734f, 0.152563f, 0.40029f, 1.0f}, {0.59694f, 0.154848f, 0.398125f, 1.0f}, + {0.603139f, 0.157151f, 0.395891f, 1.0f}, {0.60933f, 0.159474f, 0.393589f, 1.0f}, + {0.615513f, 0.161817f, 0.391219f, 1.0f}, {0.621685f, 0.164184f, 0.388781f, 1.0f}, + {0.627847f, 0.166575f, 0.386276f, 1.0f}, {0.633998f, 0.168992f, 0.383704f, 1.0f}, + {0.640135f, 0.171438f, 0.381065f, 1.0f}, {0.64626f, 0.173914f, 0.378359f, 1.0f}, + {0.652369f, 0.176421f, 0.375586f, 1.0f}, {0.658463f, 0.178962f, 0.372748f, 1.0f}, + {0.66454f, 0.181539f, 0.369846f, 1.0f}, {0.670599f, 0.184153f, 0.366879f, 1.0f}, + {0.676638f, 0.186807f, 0.363849f, 1.0f}, {0.682656f, 0.189501f, 0.360757f, 1.0f}, + {0.688653f, 0.192239f, 0.357603f, 1.0f}, {0.694627f, 0.195021f, 0.354388f, 1.0f}, + {0.700576f, 0.197851f, 0.351113f, 1.0f}, {0.7065f, 0.200728f, 0.347777f, 1.0f}, + {0.712396f, 0.203656f, 0.344383f, 1.0f}, {0.718264f, 0.206636f, 0.340931f, 1.0f}, + {0.724103f, 0.20967f, 0.337424f, 1.0f}, {0.735683f, 0.215906f, 0.330245f, 1.0f}, + {0.741423f, 0.219112f, 0.326576f, 1.0f}, {0.747127f, 0.222378f, 0.322856f, 1.0f}, + {0.752794f, 0.225706f, 0.319085f, 1.0f}, {0.758422f, 0.229097f, 0.315266f, 1.0f}, + {0.76401f, 0.232554f, 0.311399f, 1.0f}, {0.769556f, 0.236077f, 0.307485f, 1.0f}, + {0.775059f, 0.239667f, 0.303526f, 1.0f}, {0.780517f, 0.243327f, 0.299523f, 1.0f}, + {0.785929f, 0.247056f, 0.295477f, 1.0f}, {0.791293f, 0.250856f, 0.29139f, 1.0f}, + {0.796607f, 0.254728f, 0.287264f, 1.0f}, {0.801871f, 0.258674f, 0.283099f, 1.0f}, + {0.807082f, 0.262692f, 0.278898f, 1.0f}, {0.812239f, 0.266786f, 0.274661f, 1.0f}, + {0.817341f, 0.270954f, 0.27039f, 1.0f}, {0.822386f, 0.275197f, 0.266085f, 1.0f}, + {0.827372f, 0.279517f, 0.26175f, 1.0f}, {0.832299f, 0.283913f, 0.257383f, 1.0f}, + {0.837165f, 0.288385f, 0.252988f, 1.0f}, {0.841969f, 0.292933f, 0.248564f, 1.0f}, + {0.846709f, 0.297559f, 0.244113f, 1.0f}, {0.851384f, 0.30226f, 0.239636f, 1.0f}, + {0.855992f, 0.307038f, 0.235133f, 1.0f}, {0.860533f, 0.311892f, 0.230606f, 1.0f}, + {0.865006f, 0.316822f, 0.226055f, 1.0f}, {0.869409f, 0.321827f, 0.221482f, 1.0f}, + {0.873741f, 0.326906f, 0.216886f, 1.0f}, {0.878001f, 0.33206f, 0.212268f, 1.0f}, + {0.882188f, 0.337287f, 0.207628f, 1.0f}, {0.886302f, 0.342586f, 0.202968f, 1.0f}, + {0.890341f, 0.347957f, 0.198286f, 1.0f}, {0.894305f, 0.353399f, 0.193584f, 1.0f}, + {0.898192f, 0.358911f, 0.18886f, 1.0f}, {0.902003f, 0.364492f, 0.184116f, 1.0f}, + {0.905735f, 0.37014f, 0.17935f, 1.0f}, {0.90939f, 0.375856f, 0.174563f, 1.0f}, + {0.912966f, 0.381636f, 0.169755f, 1.0f}, {0.916462f, 0.387481f, 0.164924f, 1.0f}, + {0.919879f, 0.393389f, 0.16007f, 1.0f}, {0.923215f, 0.399359f, 0.155193f, 1.0f}, + {0.92647f, 0.405389f, 0.150292f, 1.0f}, {0.929644f, 0.411479f, 0.145367f, 1.0f}, + {0.932737f, 0.417627f, 0.140417f, 1.0f}, {0.935747f, 0.423831f, 0.13544f, 1.0f}, + {0.938675f, 0.430091f, 0.130438f, 1.0f}, {0.941521f, 0.436405f, 0.125409f, 1.0f}, + {0.944285f, 0.442772f, 0.120354f, 1.0f}, {0.946965f, 0.449191f, 0.115272f, 1.0f}, + {0.949562f, 0.45566f, 0.110164f, 1.0f}, {0.952075f, 0.462178f, 0.105031f, 1.0f}, + {0.954506f, 0.468744f, 0.099874f, 1.0f}, {0.956852f, 0.475356f, 0.094695f, 1.0f}, + {0.959114f, 0.482014f, 0.089499f, 1.0f}, {0.961293f, 0.488716f, 0.084289f, 1.0f}, + {0.963387f, 0.495462f, 0.079073f, 1.0f}, {0.965397f, 0.502249f, 0.073859f, 1.0f}, + {0.967322f, 0.509078f, 0.068659f, 1.0f}, {0.969163f, 0.515946f, 0.063488f, 1.0f}, + {0.970919f, 0.522853f, 0.058367f, 1.0f}, {0.97259f, 0.529798f, 0.053324f, 1.0f}, + {0.974176f, 0.53678f, 0.048392f, 1.0f}, {0.975677f, 0.543798f, 0.043618f, 1.0f}, + {0.977092f, 0.55085f, 0.03905f, 1.0f}, {0.978422f, 0.557937f, 0.034931f, 1.0f}, + {0.979666f, 0.565057f, 0.031409f, 1.0f}, {0.980824f, 0.572209f, 0.028508f, 1.0f}, + {0.981895f, 0.579392f, 0.02625f, 1.0f}, {0.982881f, 0.586606f, 0.024661f, 1.0f}, + {0.983779f, 0.593849f, 0.02377f, 1.0f}, {0.984591f, 0.601122f, 0.023606f, 1.0f}, + {0.985315f, 0.608422f, 0.024202f, 1.0f}, {0.985952f, 0.61575f, 0.025592f, 1.0f}, + {0.986502f, 0.623105f, 0.027814f, 1.0f}, {0.986964f, 0.630485f, 0.030908f, 1.0f}, + {0.987337f, 0.63789f, 0.034916f, 1.0f}, {0.987622f, 0.64532f, 0.039886f, 1.0f}, + {0.987819f, 0.652773f, 0.045581f, 1.0f}, {0.987926f, 0.66025f, 0.05175f, 1.0f}, + {0.987945f, 0.667748f, 0.058329f, 1.0f}, {0.987874f, 0.675267f, 0.065257f, 1.0f}, + {0.987714f, 0.682807f, 0.072489f, 1.0f}, {0.987464f, 0.690366f, 0.07999f, 1.0f}, + {0.987124f, 0.697944f, 0.087731f, 1.0f}, {0.986694f, 0.70554f, 0.095694f, 1.0f}, + {0.986175f, 0.713153f, 0.103863f, 1.0f}, {0.985566f, 0.720782f, 0.112229f, 1.0f}, + {0.984865f, 0.728427f, 0.120785f, 1.0f}, {0.984075f, 0.736087f, 0.129527f, 1.0f}, + {0.983196f, 0.743758f, 0.138453f, 1.0f}, {0.982228f, 0.751442f, 0.147565f, 1.0f}, + {0.981173f, 0.759135f, 0.156863f, 1.0f}, {0.980032f, 0.766837f, 0.166353f, 1.0f}, + {0.978806f, 0.774545f, 0.176037f, 1.0f}, {0.977497f, 0.782258f, 0.185923f, 1.0f}, + {0.976108f, 0.789974f, 0.196018f, 1.0f}, {0.974638f, 0.797692f, 0.206332f, 1.0f}, + {0.973088f, 0.805409f, 0.216877f, 1.0f}, {0.971468f, 0.813122f, 0.227658f, 1.0f}, + {0.969783f, 0.820825f, 0.238686f, 1.0f}, {0.968041f, 0.828515f, 0.249972f, 1.0f}, + {0.966243f, 0.836191f, 0.261534f, 1.0f}, {0.964394f, 0.843848f, 0.273391f, 1.0f}, + {0.962517f, 0.851476f, 0.285546f, 1.0f}, {0.960626f, 0.859069f, 0.29801f, 1.0f}, + {0.95872f, 0.866624f, 0.31082f, 1.0f}, {0.956834f, 0.874129f, 0.323974f, 1.0f}, + {0.954997f, 0.881569f, 0.337475f, 1.0f}, {0.953215f, 0.888942f, 0.351369f, 1.0f}, + {0.951546f, 0.896226f, 0.365627f, 1.0f}, {0.950018f, 0.903409f, 0.380271f, 1.0f}, + {0.948683f, 0.910473f, 0.395289f, 1.0f}, {0.947594f, 0.917399f, 0.410665f, 1.0f}, + {0.946809f, 0.924168f, 0.426373f, 1.0f}, {0.946392f, 0.930761f, 0.442367f, 1.0f}, + {0.946403f, 0.937159f, 0.458592f, 1.0f}, {0.946903f, 0.943348f, 0.47497f, 1.0f}, + {0.947937f, 0.949318f, 0.491426f, 1.0f}, {0.949545f, 0.955063f, 0.50786f, 1.0f}, + {0.95174f, 0.960587f, 0.524203f, 1.0f}, {0.954529f, 0.965896f, 0.540361f, 1.0f}, + {0.957896f, 0.971003f, 0.556275f, 1.0f}, {0.961812f, 0.975924f, 0.571925f, 1.0f}, + {0.966249f, 0.980678f, 0.587206f, 1.0f}, {0.971162f, 0.985282f, 0.602154f, 1.0f}, + {0.976511f, 0.989753f, 0.61676f, 1.0f}, {0.982257f, 0.994109f, 0.631017f, 1.0f}, + {0.988362f, 0.998364f, 0.644924f, 1.0f}, + }; + ImPlot::AddColormap("Inferno", (const ImVec4 *)s_values[cmap].data(), s_values[cmap].size(), false); + + cmap = Colormap_Turbo; + s_values[cmap] = vector{ + {0.18995f, 0.07176f, 0.23217f, 1.0f}, {0.19483f, 0.08339f, 0.26149f, 1.0f}, + {0.19956f, 0.09498f, 0.29024f, 1.0f}, {0.20415f, 0.10652f, 0.31844f, 1.0f}, + {0.2086f, 0.11802f, 0.34607f, 1.0f}, {0.21291f, 0.12947f, 0.37314f, 1.0f}, + {0.21708f, 0.14087f, 0.39964f, 1.0f}, {0.22111f, 0.15223f, 0.42558f, 1.0f}, + {0.225f, 0.16354f, 0.45096f, 1.0f}, {0.22875f, 0.17481f, 0.47578f, 1.0f}, + {0.23236f, 0.18603f, 0.50004f, 1.0f}, {0.23582f, 0.1972f, 0.52373f, 1.0f}, + {0.23915f, 0.20833f, 0.54686f, 1.0f}, {0.24234f, 0.21941f, 0.56942f, 1.0f}, + {0.24539f, 0.23044f, 0.59142f, 1.0f}, {0.2483f, 0.24143f, 0.61286f, 1.0f}, + {0.25107f, 0.25237f, 0.63374f, 1.0f}, {0.25369f, 0.26327f, 0.65406f, 1.0f}, + {0.25618f, 0.27412f, 0.67381f, 1.0f}, {0.25853f, 0.28492f, 0.693f, 1.0f}, + {0.26074f, 0.29568f, 0.71162f, 1.0f}, {0.2628f, 0.30639f, 0.72968f, 1.0f}, + {0.26473f, 0.31706f, 0.74718f, 1.0f}, {0.26652f, 0.32768f, 0.76412f, 1.0f}, + {0.26816f, 0.33825f, 0.7805f, 1.0f}, {0.26967f, 0.34878f, 0.79631f, 1.0f}, + {0.27103f, 0.35926f, 0.81156f, 1.0f}, {0.27226f, 0.3697f, 0.82624f, 1.0f}, + {0.27334f, 0.38008f, 0.84037f, 1.0f}, {0.27429f, 0.39043f, 0.85393f, 1.0f}, + {0.27509f, 0.40072f, 0.86692f, 1.0f}, {0.27576f, 0.41097f, 0.87936f, 1.0f}, + {0.27628f, 0.42118f, 0.89123f, 1.0f}, {0.27667f, 0.43134f, 0.90254f, 1.0f}, + {0.27691f, 0.44145f, 0.91328f, 1.0f}, {0.27701f, 0.45152f, 0.92347f, 1.0f}, + {0.27698f, 0.46153f, 0.93309f, 1.0f}, {0.2768f, 0.47151f, 0.94214f, 1.0f}, + {0.27648f, 0.48144f, 0.95064f, 1.0f}, {0.27603f, 0.49132f, 0.95857f, 1.0f}, + {0.27543f, 0.50115f, 0.96594f, 1.0f}, {0.27469f, 0.51094f, 0.97275f, 1.0f}, + {0.27381f, 0.52069f, 0.97899f, 1.0f}, {0.27273f, 0.5304f, 0.98461f, 1.0f}, + {0.27106f, 0.54015f, 0.9893f, 1.0f}, {0.26878f, 0.54995f, 0.99303f, 1.0f}, + {0.26592f, 0.55979f, 0.99583f, 1.0f}, {0.26252f, 0.56967f, 0.99773f, 1.0f}, + {0.25862f, 0.57958f, 0.99876f, 1.0f}, {0.25425f, 0.5895f, 0.99896f, 1.0f}, + {0.24946f, 0.59943f, 0.99835f, 1.0f}, {0.24427f, 0.60937f, 0.99697f, 1.0f}, + {0.23874f, 0.61931f, 0.99485f, 1.0f}, {0.23288f, 0.62923f, 0.99202f, 1.0f}, + {0.22676f, 0.63913f, 0.98851f, 1.0f}, {0.22039f, 0.64901f, 0.98436f, 1.0f}, + {0.21382f, 0.65886f, 0.97959f, 1.0f}, {0.20708f, 0.66866f, 0.97423f, 1.0f}, + {0.20021f, 0.67842f, 0.96833f, 1.0f}, {0.19326f, 0.68812f, 0.9619f, 1.0f}, + {0.18625f, 0.69775f, 0.95498f, 1.0f}, {0.17923f, 0.70732f, 0.94761f, 1.0f}, + {0.17223f, 0.7168f, 0.93981f, 1.0f}, {0.16529f, 0.7262f, 0.93161f, 1.0f}, + {0.15844f, 0.73551f, 0.92305f, 1.0f}, {0.15173f, 0.74472f, 0.91416f, 1.0f}, + {0.14519f, 0.75381f, 0.90496f, 1.0f}, {0.13886f, 0.76279f, 0.8955f, 1.0f}, + {0.13278f, 0.77165f, 0.8858f, 1.0f}, {0.12698f, 0.78037f, 0.8759f, 1.0f}, + {0.12151f, 0.78896f, 0.86581f, 1.0f}, {0.11639f, 0.7974f, 0.85559f, 1.0f}, + {0.11167f, 0.80569f, 0.84525f, 1.0f}, {0.10738f, 0.81381f, 0.83484f, 1.0f}, + {0.10357f, 0.82177f, 0.82437f, 1.0f}, {0.10026f, 0.82955f, 0.81389f, 1.0f}, + {0.0975f, 0.83714f, 0.80342f, 1.0f}, {0.09532f, 0.84455f, 0.79299f, 1.0f}, + {0.09377f, 0.85175f, 0.78264f, 1.0f}, {0.09287f, 0.85875f, 0.7724f, 1.0f}, + {0.09267f, 0.86554f, 0.7623f, 1.0f}, {0.0932f, 0.87211f, 0.75237f, 1.0f}, + {0.09451f, 0.87844f, 0.74265f, 1.0f}, {0.09662f, 0.88454f, 0.73316f, 1.0f}, + {0.09958f, 0.8904f, 0.72393f, 1.0f}, {0.10342f, 0.896f, 0.715f, 1.0f}, + {0.10815f, 0.90142f, 0.70599f, 1.0f}, {0.11374f, 0.90673f, 0.69651f, 1.0f}, + {0.12014f, 0.91193f, 0.6866f, 1.0f}, {0.12733f, 0.91701f, 0.67627f, 1.0f}, + {0.13526f, 0.92197f, 0.66556f, 1.0f}, {0.14391f, 0.9268f, 0.65448f, 1.0f}, + {0.15323f, 0.93151f, 0.64308f, 1.0f}, {0.16319f, 0.93609f, 0.63137f, 1.0f}, + {0.17377f, 0.94053f, 0.61938f, 1.0f}, {0.18491f, 0.94484f, 0.60713f, 1.0f}, + {0.19659f, 0.94901f, 0.59466f, 1.0f}, {0.20877f, 0.95304f, 0.58199f, 1.0f}, + {0.22142f, 0.95692f, 0.56914f, 1.0f}, {0.23449f, 0.96065f, 0.55614f, 1.0f}, + {0.24797f, 0.96423f, 0.54303f, 1.0f}, {0.2618f, 0.96765f, 0.52981f, 1.0f}, + {0.27597f, 0.97092f, 0.51653f, 1.0f}, {0.29042f, 0.97403f, 0.50321f, 1.0f}, + {0.30513f, 0.97697f, 0.48987f, 1.0f}, {0.32006f, 0.97974f, 0.47654f, 1.0f}, + {0.33517f, 0.98234f, 0.46325f, 1.0f}, {0.35043f, 0.98477f, 0.45002f, 1.0f}, + {0.36581f, 0.98702f, 0.43688f, 1.0f}, {0.38127f, 0.98909f, 0.42386f, 1.0f}, + {0.39678f, 0.99098f, 0.41098f, 1.0f}, {0.41229f, 0.99268f, 0.39826f, 1.0f}, + {0.42778f, 0.99419f, 0.38575f, 1.0f}, {0.44321f, 0.99551f, 0.37345f, 1.0f}, + {0.45854f, 0.99663f, 0.3614f, 1.0f}, {0.47375f, 0.99755f, 0.34963f, 1.0f}, + {0.48879f, 0.99828f, 0.33816f, 1.0f}, {0.50362f, 0.99879f, 0.32701f, 1.0f}, + {0.51822f, 0.9991f, 0.31622f, 1.0f}, {0.53255f, 0.99919f, 0.30581f, 1.0f}, + {0.54658f, 0.99907f, 0.29581f, 1.0f}, {0.56026f, 0.99873f, 0.28623f, 1.0f}, + {0.57357f, 0.99817f, 0.27712f, 1.0f}, {0.58646f, 0.99739f, 0.26849f, 1.0f}, + {0.59891f, 0.99638f, 0.26038f, 1.0f}, {0.61088f, 0.99514f, 0.2528f, 1.0f}, + {0.62233f, 0.99366f, 0.24579f, 1.0f}, {0.64362f, 0.98999f, 0.23356f, 1.0f}, + {0.65394f, 0.98775f, 0.22835f, 1.0f}, {0.66428f, 0.98524f, 0.2237f, 1.0f}, + {0.67462f, 0.98246f, 0.2196f, 1.0f}, {0.68494f, 0.97941f, 0.21602f, 1.0f}, + {0.69525f, 0.9761f, 0.21294f, 1.0f}, {0.70553f, 0.97255f, 0.21032f, 1.0f}, + {0.71577f, 0.96875f, 0.20815f, 1.0f}, {0.72596f, 0.9647f, 0.2064f, 1.0f}, + {0.7361f, 0.96043f, 0.20504f, 1.0f}, {0.74617f, 0.95593f, 0.20406f, 1.0f}, + {0.75617f, 0.95121f, 0.20343f, 1.0f}, {0.76608f, 0.94627f, 0.20311f, 1.0f}, + {0.77591f, 0.94113f, 0.2031f, 1.0f}, {0.78563f, 0.93579f, 0.20336f, 1.0f}, + {0.79524f, 0.93025f, 0.20386f, 1.0f}, {0.80473f, 0.92452f, 0.20459f, 1.0f}, + {0.8141f, 0.91861f, 0.20552f, 1.0f}, {0.82333f, 0.91253f, 0.20663f, 1.0f}, + {0.83241f, 0.90627f, 0.20788f, 1.0f}, {0.84133f, 0.89986f, 0.20926f, 1.0f}, + {0.8501f, 0.89328f, 0.21074f, 1.0f}, {0.85868f, 0.88655f, 0.2123f, 1.0f}, + {0.86709f, 0.87968f, 0.21391f, 1.0f}, {0.8753f, 0.87267f, 0.21555f, 1.0f}, + {0.88331f, 0.86553f, 0.21719f, 1.0f}, {0.89112f, 0.85826f, 0.2188f, 1.0f}, + {0.8987f, 0.85087f, 0.22038f, 1.0f}, {0.90605f, 0.84337f, 0.22188f, 1.0f}, + {0.91317f, 0.83576f, 0.22328f, 1.0f}, {0.92004f, 0.82806f, 0.22456f, 1.0f}, + {0.92666f, 0.82025f, 0.2257f, 1.0f}, {0.93301f, 0.81236f, 0.22667f, 1.0f}, + {0.93909f, 0.80439f, 0.22744f, 1.0f}, {0.94489f, 0.79634f, 0.228f, 1.0f}, + {0.95039f, 0.78823f, 0.22831f, 1.0f}, {0.9556f, 0.78005f, 0.22836f, 1.0f}, + {0.96049f, 0.77181f, 0.22811f, 1.0f}, {0.96507f, 0.76352f, 0.22754f, 1.0f}, + {0.96931f, 0.75519f, 0.22663f, 1.0f}, {0.97323f, 0.74682f, 0.22536f, 1.0f}, + {0.97679f, 0.73842f, 0.22369f, 1.0f}, {0.98f, 0.73f, 0.22161f, 1.0f}, + {0.98289f, 0.7214f, 0.21918f, 1.0f}, {0.98549f, 0.7125f, 0.2165f, 1.0f}, + {0.98781f, 0.7033f, 0.21358f, 1.0f}, {0.98986f, 0.69382f, 0.21043f, 1.0f}, + {0.99163f, 0.68408f, 0.20706f, 1.0f}, {0.99314f, 0.67408f, 0.20348f, 1.0f}, + {0.99438f, 0.66386f, 0.19971f, 1.0f}, {0.99535f, 0.65341f, 0.19577f, 1.0f}, + {0.99607f, 0.64277f, 0.19165f, 1.0f}, {0.99654f, 0.63193f, 0.18738f, 1.0f}, + {0.99675f, 0.62093f, 0.18297f, 1.0f}, {0.99672f, 0.60977f, 0.17842f, 1.0f}, + {0.99644f, 0.59846f, 0.17376f, 1.0f}, {0.99593f, 0.58703f, 0.16899f, 1.0f}, + {0.99517f, 0.57549f, 0.16412f, 1.0f}, {0.99419f, 0.56386f, 0.15918f, 1.0f}, + {0.99297f, 0.55214f, 0.15417f, 1.0f}, {0.99153f, 0.54036f, 0.1491f, 1.0f}, + {0.98987f, 0.52854f, 0.14398f, 1.0f}, {0.98799f, 0.51667f, 0.13883f, 1.0f}, + {0.9859f, 0.50479f, 0.13367f, 1.0f}, {0.9836f, 0.49291f, 0.12849f, 1.0f}, + {0.98108f, 0.48104f, 0.12332f, 1.0f}, {0.97837f, 0.4692f, 0.11817f, 1.0f}, + {0.97545f, 0.4574f, 0.11305f, 1.0f}, {0.97234f, 0.44565f, 0.10797f, 1.0f}, + {0.96904f, 0.43399f, 0.10294f, 1.0f}, {0.96555f, 0.42241f, 0.09798f, 1.0f}, + {0.96187f, 0.41093f, 0.0931f, 1.0f}, {0.95801f, 0.39958f, 0.08831f, 1.0f}, + {0.95398f, 0.38836f, 0.08362f, 1.0f}, {0.94977f, 0.37729f, 0.07905f, 1.0f}, + {0.94538f, 0.36638f, 0.07461f, 1.0f}, {0.94084f, 0.35566f, 0.07031f, 1.0f}, + {0.93612f, 0.34513f, 0.06616f, 1.0f}, {0.93125f, 0.33482f, 0.06218f, 1.0f}, + {0.92623f, 0.32473f, 0.05837f, 1.0f}, {0.92105f, 0.31489f, 0.05475f, 1.0f}, + {0.91572f, 0.3053f, 0.05134f, 1.0f}, {0.91024f, 0.29599f, 0.04814f, 1.0f}, + {0.90463f, 0.28696f, 0.04516f, 1.0f}, {0.89888f, 0.27824f, 0.04243f, 1.0f}, + {0.89298f, 0.26981f, 0.03993f, 1.0f}, {0.88691f, 0.26152f, 0.03753f, 1.0f}, + {0.88066f, 0.25334f, 0.03521f, 1.0f}, {0.87422f, 0.24526f, 0.03297f, 1.0f}, + {0.8676f, 0.2373f, 0.03082f, 1.0f}, {0.86079f, 0.22945f, 0.02875f, 1.0f}, + {0.8538f, 0.2217f, 0.02677f, 1.0f}, {0.84662f, 0.21407f, 0.02487f, 1.0f}, + {0.83926f, 0.20654f, 0.02305f, 1.0f}, {0.83172f, 0.19912f, 0.02131f, 1.0f}, + {0.82399f, 0.19182f, 0.01966f, 1.0f}, {0.81608f, 0.18462f, 0.01809f, 1.0f}, + {0.80799f, 0.17753f, 0.0166f, 1.0f}, {0.79971f, 0.17055f, 0.0152f, 1.0f}, + {0.79125f, 0.16368f, 0.01387f, 1.0f}, {0.7826f, 0.15693f, 0.01264f, 1.0f}, + {0.77377f, 0.15028f, 0.01148f, 1.0f}, {0.76476f, 0.14374f, 0.01041f, 1.0f}, + {0.75556f, 0.13731f, 0.00942f, 1.0f}, {0.74617f, 0.13098f, 0.00851f, 1.0f}, + {0.73661f, 0.12477f, 0.00769f, 1.0f}, {0.72686f, 0.11867f, 0.00695f, 1.0f}, + {0.71692f, 0.11268f, 0.00629f, 1.0f}, {0.7068f, 0.1068f, 0.00571f, 1.0f}, + {0.6965f, 0.10102f, 0.00522f, 1.0f}, {0.68602f, 0.09536f, 0.00481f, 1.0f}, + {0.67535f, 0.0898f, 0.00449f, 1.0f}, {0.66449f, 0.08436f, 0.00424f, 1.0f}, + {0.65345f, 0.07902f, 0.00408f, 1.0f}, {0.64223f, 0.0738f, 0.00401f, 1.0f}, + {0.63082f, 0.06868f, 0.00401f, 1.0f}, {0.61923f, 0.06367f, 0.0041f, 1.0f}, + {0.60746f, 0.05878f, 0.00427f, 1.0f}, {0.5955f, 0.05399f, 0.00453f, 1.0f}, + {0.58336f, 0.04931f, 0.00486f, 1.0f}, {0.57103f, 0.04474f, 0.00529f, 1.0f}, + {0.55852f, 0.04028f, 0.00579f, 1.0f}, {0.54583f, 0.03593f, 0.00638f, 1.0f}, + {0.53295f, 0.03169f, 0.00705f, 1.0f}, {0.51989f, 0.02756f, 0.0078f, 1.0f}, + {0.50664f, 0.02354f, 0.00863f, 1.0f}, {0.49321f, 0.01963f, 0.00955f, 1.0f}, + {0.4796f, 0.01583f, 0.01055f, 1.0f}, + }; + ImPlot::AddColormap("Turbo", (const ImVec4 *)s_values[cmap].data(), s_values[cmap].size(), false); + + cmap = Colormap_IceFire; + s_values[cmap] = { + {0.73936227f, 0.90443867f, 0.85757238f, 1.0f}, {0.72888063f, 0.89639109f, 0.85488394f, 1.0f}, + {0.71834255f, 0.88842162f, 0.8521605f, 1.0f}, {0.70773866f, 0.88052939f, 0.849422f, 1.0f}, + {0.69706215f, 0.87271313f, 0.84668315f, 1.0f}, {0.68629021f, 0.86497329f, 0.84398721f, 1.0f}, + {0.67543654f, 0.85730617f, 0.84130969f, 1.0f}, {0.66448539f, 0.84971123f, 0.83868005f, 1.0f}, + {0.65342679f, 0.84218728f, 0.83611512f, 1.0f}, {0.64231804f, 0.83471867f, 0.83358584f, 1.0f}, + {0.63117745f, 0.827294f, 0.83113431f, 1.0f}, {0.62000484f, 0.81991069f, 0.82876741f, 1.0f}, + {0.60879435f, 0.81256797f, 0.82648905f, 1.0f}, {0.59754118f, 0.80526458f, 0.82430414f, 1.0f}, + {0.58624247f, 0.79799884f, 0.82221573f, 1.0f}, {0.57489525f, 0.7907688f, 0.82022901f, 1.0f}, + {0.56349779f, 0.78357215f, 0.81834861f, 1.0f}, {0.55204294f, 0.77640827f, 0.81657563f, 1.0f}, + {0.54052516f, 0.76927562f, 0.81491462f, 1.0f}, {0.52894085f, 0.76217215f, 0.81336913f, 1.0f}, + {0.51728854f, 0.75509528f, 0.81194156f, 1.0f}, {0.50555676f, 0.74804469f, 0.81063503f, 1.0f}, + {0.49373871f, 0.7410187f, 0.80945242f, 1.0f}, {0.48183174f, 0.73401449f, 0.80839675f, 1.0f}, + {0.46982587f, 0.72703075f, 0.80747097f, 1.0f}, {0.45770893f, 0.72006648f, 0.80667756f, 1.0f}, + {0.44547249f, 0.71311941f, 0.80601991f, 1.0f}, {0.43318643f, 0.70617126f, 0.80549278f, 1.0f}, + {0.42110294f, 0.69916972f, 0.80506683f, 1.0f}, {0.40925101f, 0.69211059f, 0.80473246f, 1.0f}, + {0.3976693f, 0.68498786f, 0.80448272f, 1.0f}, {0.38632002f, 0.67781125f, 0.80431024f, 1.0f}, + {0.37523981f, 0.67057537f, 0.80420832f, 1.0f}, {0.36442578f, 0.66328229f, 0.80417474f, 1.0f}, + {0.35385939f, 0.65593699f, 0.80420591f, 1.0f}, {0.34358916f, 0.64853177f, 0.8043f, 1.0f}, + {0.33355526f, 0.64107876f, 0.80445484f, 1.0f}, {0.32383062f, 0.63356578f, 0.80467091f, 1.0f}, + {0.31434372f, 0.62600624f, 0.8049475f, 1.0f}, {0.30516161f, 0.618389f, 0.80528692f, 1.0f}, + {0.29623491f, 0.61072284f, 0.80569021f, 1.0f}, {0.28759072f, 0.60300319f, 0.80616055f, 1.0f}, + {0.27923924f, 0.59522877f, 0.80669803f, 1.0f}, {0.27114651f, 0.5874047f, 0.80730545f, 1.0f}, + {0.26337153f, 0.57952055f, 0.80799113f, 1.0f}, {0.25588696f, 0.57157984f, 0.80875922f, 1.0f}, + {0.248686f, 0.56358255f, 0.80961366f, 1.0f}, {0.24180668f, 0.55552289f, 0.81055123f, 1.0f}, + {0.23526251f, 0.54739477f, 0.8115939f, 1.0f}, {0.22921445f, 0.53918506f, 0.81267292f, 1.0f}, + {0.22397687f, 0.53086094f, 0.8137141f, 1.0f}, {0.21977058f, 0.52241482f, 0.81457651f, 1.0f}, + {0.21658989f, 0.51384321f, 0.81528511f, 1.0f}, {0.21452772f, 0.50514155f, 0.81577278f, 1.0f}, + {0.21372783f, 0.49630865f, 0.81589566f, 1.0f}, {0.21409503f, 0.48734861f, 0.81566163f, 1.0f}, + {0.2157176f, 0.47827123f, 0.81487615f, 1.0f}, {0.21842857f, 0.46909168f, 0.81351614f, 1.0f}, + {0.22211705f, 0.45983212f, 0.81146983f, 1.0f}, {0.22665681f, 0.45052233f, 0.80860217f, 1.0f}, + {0.23176013f, 0.44119137f, 0.80494325f, 1.0f}, {0.23727775f, 0.43187704f, 0.80038017f, 1.0f}, + {0.24298285f, 0.42261123f, 0.79493267f, 1.0f}, {0.24865068f, 0.41341842f, 0.78869164f, 1.0f}, + {0.25423116f, 0.40433127f, 0.78155831f, 1.0f}, {0.25950239f, 0.39535521f, 0.77376848f, 1.0f}, + {0.2644736f, 0.38651212f, 0.76524809f, 1.0f}, {0.26901584f, 0.37779582f, 0.75621942f, 1.0f}, + {0.27318141f, 0.36922056f, 0.746605f, 1.0f}, {0.27690355f, 0.3607736f, 0.73659374f, 1.0f}, + {0.28023585f, 0.35244234f, 0.72622103f, 1.0f}, {0.28306009f, 0.34438449f, 0.71500731f, 1.0f}, + {0.28535896f, 0.33660243f, 0.70303975f, 1.0f}, {0.28708711f, 0.32912157f, 0.69034504f, 1.0f}, + {0.28816354f, 0.32200604f, 0.67684067f, 1.0f}, {0.28862749f, 0.31519824f, 0.66278813f, 1.0f}, + {0.28847904f, 0.30869064f, 0.6482815f, 1.0f}, {0.28770912f, 0.30250126f, 0.63331265f, 1.0f}, + {0.28640325f, 0.29655509f, 0.61811374f, 1.0f}, {0.28458943f, 0.29082155f, 0.60280913f, 1.0f}, + {0.28233561f, 0.28527482f, 0.58742866f, 1.0f}, {0.27967038f, 0.2798938f, 0.57204225f, 1.0f}, + {0.27665361f, 0.27465357f, 0.55667809f, 1.0f}, {0.27332564f, 0.2695165f, 0.54145387f, 1.0f}, + {0.26973851f, 0.26447054f, 0.52634916f, 1.0f}, {0.2659204f, 0.25949691f, 0.511417f, 1.0f}, + {0.26190145f, 0.25458123f, 0.49668768f, 1.0f}, {0.2577151f, 0.24971691f, 0.48214874f, 1.0f}, + {0.25337618f, 0.24490494f, 0.46778758f, 1.0f}, {0.24890842f, 0.24013332f, 0.45363816f, 1.0f}, + {0.24433654f, 0.23539226f, 0.4397245f, 1.0f}, {0.23967922f, 0.23067729f, 0.4260591f, 1.0f}, + {0.23495608f, 0.22598894f, 0.41262952f, 1.0f}, {0.23018113f, 0.22132414f, 0.39945577f, 1.0f}, + {0.22534609f, 0.21670847f, 0.38645794f, 1.0f}, {0.22048761f, 0.21211723f, 0.37372555f, 1.0f}, + {0.2156198f, 0.20755389f, 0.36125301f, 1.0f}, {0.21074637f, 0.20302717f, 0.34903192f, 1.0f}, + {0.20586893f, 0.19855368f, 0.33701661f, 1.0f}, {0.20101757f, 0.19411573f, 0.32529173f, 1.0f}, + {0.19619947f, 0.18972425f, 0.31383846f, 1.0f}, {0.19140726f, 0.18540157f, 0.30260777f, 1.0f}, + {0.1866769f, 0.1811332f, 0.29166583f, 1.0f}, {0.18201285f, 0.17694992f, 0.28088776f, 1.0f}, + {0.17745228f, 0.17282141f, 0.27044211f, 1.0f}, {0.17300684f, 0.16876921f, 0.26024893f, 1.0f}, + {0.16868273f, 0.16479861f, 0.25034479f, 1.0f}, {0.16448691f, 0.16091728f, 0.24075373f, 1.0f}, + {0.16043195f, 0.15714351f, 0.23141745f, 1.0f}, {0.15652427f, 0.15348248f, 0.22238175f, 1.0f}, + {0.15277065f, 0.14994111f, 0.21368395f, 1.0f}, {0.14918274f, 0.14653431f, 0.20529486f, 1.0f}, + {0.14577095f, 0.14327403f, 0.19720829f, 1.0f}, {0.14254381f, 0.14016944f, 0.18944326f, 1.0f}, + {0.13951035f, 0.13723063f, 0.18201072f, 1.0f}, {0.13667798f, 0.13446606f, 0.17493774f, 1.0f}, + {0.13405762f, 0.13188822f, 0.16820842f, 1.0f}, {0.13165767f, 0.12950667f, 0.16183275f, 1.0f}, + {0.12948748f, 0.12733187f, 0.15580631f, 1.0f}, {0.12755435f, 0.1253723f, 0.15014098f, 1.0f}, + {0.12586516f, 0.12363617f, 0.1448459f, 1.0f}, {0.12442647f, 0.12213143f, 0.13992571f, 1.0f}, + {0.12324241f, 0.12086419f, 0.13539995f, 1.0f}, {0.12232067f, 0.11984278f, 0.13124644f, 1.0f}, + {0.12166209f, 0.11907077f, 0.12749671f, 1.0f}, {0.12126982f, 0.11855309f, 0.12415079f, 1.0f}, + {0.12114244f, 0.11829179f, 0.1212385f, 1.0f}, {0.12284806f, 0.1179729f, 0.11772022f, 1.0f}, + {0.12619498f, 0.11721796f, 0.11770203f, 1.0f}, {0.129968f, 0.11663788f, 0.11792377f, 1.0f}, + {0.13410011f, 0.11625146f, 0.11839138f, 1.0f}, {0.13855459f, 0.11606618f, 0.11910584f, 1.0f}, + {0.14333775f, 0.11607038f, 0.1200606f, 1.0f}, {0.148417f, 0.11626929f, 0.12125453f, 1.0f}, + {0.15377389f, 0.11666192f, 0.12268364f, 1.0f}, {0.15941427f, 0.11723486f, 0.12433911f, 1.0f}, + {0.16533376f, 0.11797856f, 0.12621303f, 1.0f}, {0.17152547f, 0.11888403f, 0.12829735f, 1.0f}, + {0.17797765f, 0.11994436f, 0.13058435f, 1.0f}, {0.18468769f, 0.12114722f, 0.13306426f, 1.0f}, + {0.19165663f, 0.12247737f, 0.13572616f, 1.0f}, {0.19884415f, 0.12394381f, 0.1385669f, 1.0f}, + {0.20627181f, 0.12551883f, 0.14157124f, 1.0f}, {0.21394877f, 0.12718055f, 0.14472604f, 1.0f}, + {0.22184572f, 0.12893119f, 0.14802579f, 1.0f}, {0.22994394f, 0.13076731f, 0.15146314f, 1.0f}, + {0.23823937f, 0.13267611f, 0.15502793f, 1.0f}, {0.24676041f, 0.13462172f, 0.15870321f, 1.0f}, + {0.25546457f, 0.13661751f, 0.16248722f, 1.0f}, {0.26433628f, 0.13865956f, 0.16637301f, 1.0f}, + {0.27341345f, 0.14070412f, 0.17034221f, 1.0f}, {0.28264773f, 0.14277192f, 0.1743957f, 1.0f}, + {0.29202272f, 0.14486161f, 0.17852793f, 1.0f}, {0.30159648f, 0.14691224f, 0.1827169f, 1.0f}, + {0.31129002f, 0.14897583f, 0.18695213f, 1.0f}, {0.32111555f, 0.15103351f, 0.19119629f, 1.0f}, + {0.33107961f, 0.1530674f, 0.19543758f, 1.0f}, {0.34119892f, 0.15504762f, 0.1996803f, 1.0f}, + {0.35142388f, 0.15701131f, 0.20389086f, 1.0f}, {0.36178937f, 0.1589124f, 0.20807639f, 1.0f}, + {0.37229381f, 0.16073993f, 0.21223189f, 1.0f}, {0.38288348f, 0.16254006f, 0.2163249f, 1.0f}, + {0.39359592f, 0.16426336f, 0.22036577f, 1.0f}, {0.40444332f, 0.16588767f, 0.22434027f, 1.0f}, + {0.41537995f, 0.16745325f, 0.2282297f, 1.0f}, {0.42640867f, 0.16894939f, 0.23202755f, 1.0f}, + {0.43754706f, 0.17034847f, 0.23572899f, 1.0f}, {0.44878564f, 0.1716535f, 0.23932344f, 1.0f}, + {0.4601126f, 0.17287365f, 0.24278607f, 1.0f}, {0.47151732f, 0.17401641f, 0.24610337f, 1.0f}, + {0.48300689f, 0.17506676f, 0.2492737f, 1.0f}, {0.49458302f, 0.17601892f, 0.25227688f, 1.0f}, + {0.50623876f, 0.17687777f, 0.255096f, 1.0f}, {0.5179623f, 0.17765528f, 0.2577162f, 1.0f}, + {0.52975234f, 0.17835232f, 0.2601134f, 1.0f}, {0.54159776f, 0.17898292f, 0.26226847f, 1.0f}, + {0.55348804f, 0.17956232f, 0.26416003f, 1.0f}, {0.56541729f, 0.18010175f, 0.26575971f, 1.0f}, + {0.57736669f, 0.180631f, 0.26704888f, 1.0f}, {0.58932081f, 0.18117827f, 0.26800409f, 1.0f}, + {0.60127582f, 0.18175888f, 0.26858488f, 1.0f}, {0.61319563f, 0.1824336f, 0.2687872f, 1.0f}, + {0.62506376f, 0.18324015f, 0.26858301f, 1.0f}, {0.63681202f, 0.18430173f, 0.26795276f, 1.0f}, + {0.64842603f, 0.18565472f, 0.26689463f, 1.0f}, {0.65988195f, 0.18734638f, 0.26543435f, 1.0f}, + {0.67111966f, 0.18948885f, 0.26357955f, 1.0f}, {0.68209194f, 0.19216636f, 0.26137175f, 1.0f}, + {0.69281185f, 0.19535326f, 0.25887063f, 1.0f}, {0.70335022f, 0.19891271f, 0.25617971f, 1.0f}, + {0.71375229f, 0.20276438f, 0.25331365f, 1.0f}, {0.72401436f, 0.20691287f, 0.25027366f, 1.0f}, + {0.73407638f, 0.21145051f, 0.24710661f, 1.0f}, {0.74396983f, 0.21631913f, 0.24380715f, 1.0f}, + {0.75361506f, 0.22163653f, 0.24043996f, 1.0f}, {0.7630579f, 0.22731637f, 0.23700095f, 1.0f}, + {0.77222228f, 0.23346231f, 0.23356628f, 1.0f}, {0.78115441f, 0.23998404f, 0.23013825f, 1.0f}, + {0.78979746f, 0.24694858f, 0.22678822f, 1.0f}, {0.79819286f, 0.25427223f, 0.22352658f, 1.0f}, + {0.80630444f, 0.26198807f, 0.22040877f, 1.0f}, {0.81417437f, 0.27001406f, 0.21744645f, 1.0f}, + {0.82177364f, 0.27837336f, 0.21468316f, 1.0f}, {0.82915955f, 0.28696963f, 0.21210766f, 1.0f}, + {0.83628628f, 0.2958499f, 0.20977813f, 1.0f}, {0.84322168f, 0.30491136f, 0.20766435f, 1.0f}, + {0.84995458f, 0.31415945f, 0.2057863f, 1.0f}, {0.85648867f, 0.32358058f, 0.20415327f, 1.0f}, + {0.86286243f, 0.33312058f, 0.20274969f, 1.0f}, {0.86908321f, 0.34276705f, 0.20157271f, 1.0f}, + {0.87512876f, 0.3525416f, 0.20064949f, 1.0f}, {0.88100349f, 0.36243385f, 0.19999078f, 1.0f}, + {0.8866469f, 0.37249496f, 0.1997976f, 1.0f}, {0.89203964f, 0.38273475f, 0.20013431f, 1.0f}, + {0.89713496f, 0.39318156f, 0.20121514f, 1.0f}, {0.90195099f, 0.40380687f, 0.20301555f, 1.0f}, + {0.90648379f, 0.41460191f, 0.20558847f, 1.0f}, {0.9106967f, 0.42557857f, 0.20918529f, 1.0f}, + {0.91463791f, 0.43668557f, 0.21367954f, 1.0f}, {0.91830723f, 0.44790913f, 0.21916352f, 1.0f}, + {0.92171507f, 0.45922856f, 0.22568002f, 1.0f}, {0.92491786f, 0.4705936f, 0.23308207f, 1.0f}, + {0.92790792f, 0.48200153f, 0.24145932f, 1.0f}, {0.93073701f, 0.49341219f, 0.25065486f, 1.0f}, + {0.93343918f, 0.5048017f, 0.26056148f, 1.0f}, {0.93602064f, 0.51616486f, 0.27118485f, 1.0f}, + {0.93850535f, 0.52748892f, 0.28242464f, 1.0f}, {0.94092933f, 0.53875462f, 0.29416042f, 1.0f}, + {0.94330011f, 0.5499628f, 0.30634189f, 1.0f}, {0.94563159f, 0.56110987f, 0.31891624f, 1.0f}, + {0.94792955f, 0.57219822f, 0.33184256f, 1.0f}, {0.95020929f, 0.5832232f, 0.34508419f, 1.0f}, + {0.95247324f, 0.59419035f, 0.35859866f, 1.0f}, {0.95471709f, 0.60510869f, 0.37236035f, 1.0f}, + {0.95698411f, 0.61595766f, 0.38629631f, 1.0f}, {0.95923863f, 0.62676473f, 0.40043317f, 1.0f}, + {0.9615041f, 0.6375203f, 0.41474106f, 1.0f}, {0.96371553f, 0.64826619f, 0.42928335f, 1.0f}, + {0.96591497f, 0.65899621f, 0.44380444f, 1.0f}, {0.96809871f, 0.66971662f, 0.45830232f, 1.0f}, + {0.9702495f, 0.6804394f, 0.47280492f, 1.0f}, {0.9723881f, 0.69115622f, 0.48729272f, 1.0f}, + {0.97450723f, 0.70187358f, 0.50178034f, 1.0f}, {0.9766108f, 0.712592f, 0.51626837f, 1.0f}, + {0.97871716f, 0.72330511f, 0.53074053f, 1.0f}, {0.98082222f, 0.73401769f, 0.54520694f, 1.0f}, + {0.9829001f, 0.74474445f, 0.5597019f, 1.0f}, {0.98497466f, 0.75547635f, 0.57420239f, 1.0f}, + {0.98705581f, 0.76621129f, 0.58870185f, 1.0f}, {0.98913325f, 0.77695637f, 0.60321626f, 1.0f}, + {0.99119918f, 0.78771716f, 0.61775821f, 1.0f}, {0.9932672f, 0.79848979f, 0.63231691f, 1.0f}, + {0.99535958f, 0.80926704f, 0.64687278f, 1.0f}, {0.99740544f, 0.82008078f, 0.66150571f, 1.0f}, + {0.9992197f, 0.83100723f, 0.6764127f, 1.0f}, + }; + ImPlot::AddColormap("IceFire", (const ImVec4 *)s_values[cmap].data(), s_values[cmap].size(), false); + + ++cmap; + s_values[cmap] = { + {0.2298057f, 0.298717966f, 0.753683153f, 1.0f}, + {0.23437707945098038f, 0.3055417303294118f, 0.7596795275882353f, 1.0f}, + {0.2389484589019608f, 0.3123654946588235f, 0.7656759021764705f, 1.0f}, + {0.24351983835294116f, 0.3191892589882353f, 0.7716722767647058f, 1.0f}, + {0.24809121780392157f, 0.3260130233176471f, 0.7776686513529412f, 1.0f}, + {0.2526625972549019f, 0.3328367876470588f, 0.7836650259411765f, 1.0f}, + {0.25723397670588233f, 0.3396605519764706f, 0.7896614005294117f, 1.0f}, + {0.26180535615686273f, 0.3464843163058824f, 0.795657775117647f, 1.0f}, + {0.26638146835294113f, 0.35330440842352945f, 0.8016373194980392f, 1.0f}, + {0.2711042956470588f, 0.3600106619764706f, 0.8070951274352941f, 1.0f}, + {0.27582712294117645f, 0.36671691552941177f, 0.812552935372549f, 1.0f}, + {0.2805499502352941f, 0.37342316908235296f, 0.818010743309804f, 1.0f}, + {0.28527277752941177f, 0.38012942263529415f, 0.8234685512470589f, 1.0f}, + {0.2899956048235294f, 0.3868356761882353f, 0.8289263591843137f, 1.0f}, + {0.29471843211764703f, 0.39354192974117647f, 0.8343841671215686f, 1.0f}, + {0.2994412594117647f, 0.40024818329411765f, 0.8398419750588235f, 1.0f}, + {0.3041742870039216f, 0.40694488283921565f, 0.8452627266980393f, 1.0f}, + {0.30906031906666664f, 0.41349827226666663f, 0.8501276338666667f, 1.0f}, + {0.31394635112941177f, 0.4200516616941176f, 0.8549925410352941f, 1.0f}, + {0.31883238319215684f, 0.4266050511215686f, 0.8598574482039216f, 1.0f}, + {0.32371841525490197f, 0.4331584405490196f, 0.864722355372549f, 1.0f}, + {0.32860444731764704f, 0.43971182997647057f, 0.8695872625411765f, 1.0f}, + {0.33349047938039217f, 0.44626521940392155f, 0.8744521697098039f, 1.0f}, + {0.3383765114431373f, 0.45281860883137254f, 0.8793170768784313f, 1.0f}, + {0.34327752343529416f, 0.45935363472941176f, 0.8841219216235294f, 1.0f}, + {0.34832334141176474f, 0.4657111465098039f, 0.8883461629411764f, 1.0f}, + {0.3533691593882353f, 0.47206865829019606f, 0.8925704042588235f, 1.0f}, + {0.3584149773647059f, 0.47842617007058824f, 0.8967946455764706f, 1.0f}, + {0.3634607953411765f, 0.4847836818509804f, 0.9010188868941177f, 1.0f}, + {0.36850661331764706f, 0.49114119363137254f, 0.9052431282117647f, 1.0f}, + {0.37355243129411764f, 0.4974987054117647f, 0.9094673695294118f, 1.0f}, + {0.3785982492705882f, 0.5038562171921569f, 0.9136916108470589f, 1.0f}, + {0.383662065772549f, 0.5101834172862746f, 0.9178306732313726f, 1.0f}, + {0.38885187195294113f, 0.5162984355764706f, 0.9213734830823529f, 1.0f}, + {0.3940416781333333f, 0.5224134538666667f, 0.9249162929333333f, 1.0f}, + {0.39923148431372546f, 0.5285284721568628f, 0.9284591027843138f, 1.0f}, + {0.4044212904941176f, 0.5346434904470588f, 0.9320019126352941f, 1.0f}, + {0.4096110966745098f, 0.540758508737255f, 0.9355447224862745f, 1.0f}, + {0.41480090285490195f, 0.5468735270274511f, 0.939087532337255f, 1.0f}, + {0.4199907090352941f, 0.5529885453176471f, 0.9426303421882353f, 1.0f}, + {0.42519897019607844f, 0.559058179764706f, 0.9460614570784314f, 1.0f}, + {0.4305068882509804f, 0.5648827414588236f, 0.9488894191803922f, 1.0f}, + {0.4358148063058824f, 0.5707073031529412f, 0.951717381282353f, 1.0f}, + {0.4411227243607843f, 0.5765318648470589f, 0.9545453433843137f, 1.0f}, + {0.4464306424156863f, 0.5823564265411765f, 0.9573733054862745f, 1.0f}, + {0.4517385604705882f, 0.5881809882352941f, 0.9602012675882352f, 1.0f}, + {0.4570464785254902f, 0.5940055499294118f, 0.963029229690196f, 1.0f}, + {0.4623543965803922f, 0.5998301116235294f, 0.9658571917921568f, 1.0f}, + {0.46767809468235294f, 0.6055912316235293f, 0.9685462810941176f, 1.0f}, + {0.4730701729882353f, 0.6110774376156862f, 0.970633588262745f, 1.0f}, + {0.4784622512941176f, 0.6165636436078431f, 0.9727208954313725f, 1.0f}, + {0.48385432959999997f, 0.6220498496f, 0.9748082026f, 1.0f}, + {0.48924640790588236f, 0.6275360555921569f, 0.9768955097686275f, 1.0f}, + {0.49463848621176465f, 0.6330222615843136f, 0.9789828169372549f, 1.0f}, + {0.500030564517647f, 0.6385084675764706f, 0.9810701241058823f, 1.0f}, + {0.5054226428235293f, 0.6439946735686275f, 0.9831574312745098f, 1.0f}, + {0.5108243242509803f, 0.6493966148235294f, 0.9850787763764707f, 1.0f}, + {0.5162603025411764f, 0.6544976105882353f, 0.9864073998117647f, 1.0f}, + {0.5216962808313725f, 0.6595986063529412f, 0.9877360232470589f, 1.0f}, + {0.5271322591215686f, 0.664699602117647f, 0.9890646466823529f, 1.0f}, + {0.5325682374117646f, 0.6698005978823529f, 0.9903932701176471f, 1.0f}, + {0.5380042157019607f, 0.6749015936470587f, 0.9917218935529412f, 1.0f}, + {0.5434401939921568f, 0.6800025894117647f, 0.9930505169882353f, 1.0f}, + {0.5488761722823529f, 0.6851035851764705f, 0.9943791404235295f, 1.0f}, + {0.5543118699137254f, 0.6900970112156862f, 0.9955155482352941f, 1.0f}, + {0.5597467255686274f, 0.6947677280784313f, 0.9960753091764706f, 1.0f}, + {0.5651815812235294f, 0.6994384449411764f, 0.9966350701176471f, 1.0f}, + {0.5706164368784313f, 0.7041091618039216f, 0.9971948310588236f, 1.0f}, + {0.5760512925333333f, 0.7087798786666667f, 0.997754592f, 1.0f}, + {0.5814861481882353f, 0.7134505955294117f, 0.9983143529411764f, 1.0f}, + {0.5869210038431373f, 0.7181213123921568f, 0.9988741138823529f, 1.0f}, + {0.5923558594980393f, 0.7227920292549019f, 0.9994338748235294f, 1.0f}, + {0.5977767754941177f, 0.7273297248823529f, 0.9997767317764705f, 1.0f}, + {0.603162067917647f, 0.7315274773529412f, 0.9995652785372549f, 1.0f}, + {0.6085473603411764f, 0.7357252298235294f, 0.9993538252980392f, 1.0f}, + {0.6139326527647059f, 0.7399229822941177f, 0.9991423720588235f, 1.0f}, + {0.6193179451882354f, 0.7441207347647059f, 0.9989309188196078f, 1.0f}, + {0.6247032376117647f, 0.7483184872352941f, 0.9987194655803922f, 1.0f}, + {0.6300885300352941f, 0.7525162397058823f, 0.9985080123411765f, 1.0f}, + {0.6354738224588236f, 0.7567139921764706f, 0.9982965591019608f, 1.0f}, + {0.640827782372549f, 0.7607515064117647f, 0.9978457748823529f, 1.0f}, + {0.6461128107647058f, 0.7644364965294117f, 0.9968684625058823f, 1.0f}, + {0.6513978391568627f, 0.7681214866470587f, 0.9958911501294118f, 1.0f}, + {0.6566828675490196f, 0.7718064767647058f, 0.9949138377529412f, 1.0f}, + {0.6619678959411764f, 0.7754914668823529f, 0.9939365253764706f, 1.0f}, + {0.6672529243333334f, 0.7791764569999999f, 0.992959213f, 1.0f}, + {0.6725379527254902f, 0.782861447117647f, 0.9919819006235294f, 1.0f}, + {0.677822981117647f, 0.786546437235294f, 0.9910045882470588f, 1.0f}, + {0.6830556815607843f, 0.790042626890196f, 0.9897684281843138f, 1.0f}, + {0.6881884831921569f, 0.7931783792980391f, 0.9880381043568628f, 1.0f}, + {0.6933212848235294f, 0.7963141317058823f, 0.9863077805294118f, 1.0f}, + {0.6984540864549019f, 0.7994498841137254f, 0.9845774567019608f, 1.0f}, + {0.7035868880862746f, 0.8025856365215686f, 0.9828471328745098f, 1.0f}, + {0.7087196897176471f, 0.8057213889294117f, 0.9811168090470588f, 1.0f}, + {0.7138524913490196f, 0.8088571413372548f, 0.9793864852196078f, 1.0f}, + {0.7189852929803922f, 0.811992893745098f, 0.9776561613921568f, 1.0f}, + {0.724041371882353f, 0.8149103926470588f, 0.9756509706470589f, 1.0f}, + {0.7289695795686274f, 0.8174641357058824f, 0.973187668372549f, 1.0f}, + {0.7338977872549018f, 0.8200178787647059f, 0.9707243660980392f, 1.0f}, + {0.7388259949411764f, 0.8225716218235294f, 0.9682610638235294f, 1.0f}, + {0.743754202627451f, 0.8251253648823529f, 0.9657977615490196f, 1.0f}, + {0.7486824103137254f, 0.8276791079411765f, 0.9633344592745098f, 1.0f}, + {0.753610618f, 0.830232851f, 0.960871157f, 1.0f}, + {0.7585388256862745f, 0.8327865940588235f, 0.9584078547254902f, 1.0f}, + {0.7633627801019607f, 0.8350922218196078f, 0.9556576765568627f, 1.0f}, + {0.7680343643529411f, 0.8370352195294117f, 0.9524882182352941f, 1.0f}, + {0.7727059486039215f, 0.8389782172392156f, 0.9493187599137255f, 1.0f}, + {0.777377532854902f, 0.8409212149490196f, 0.9461493015921568f, 1.0f}, + {0.7820491171058823f, 0.8428642126588235f, 0.9429798432705883f, 1.0f}, + {0.7867207013568628f, 0.8448072103686275f, 0.9398103849490196f, 1.0f}, + {0.7913922856078431f, 0.8467502080784314f, 0.9366409266274509f, 1.0f}, + {0.7960638698588236f, 0.8486932057882353f, 0.9334714683058823f, 1.0f}, + {0.8006008472941177f, 0.8503583215607843f, 0.9300075603921568f, 1.0f}, + {0.8049647588235295f, 0.8516661605568627f, 0.9261650744313725f, 1.0f}, + {0.8093286703529411f, 0.8529739995529412f, 0.9223225884705882f, 1.0f}, + {0.8136925818823529f, 0.8542818385490196f, 0.9184801025098039f, 1.0f}, + {0.8180564934117647f, 0.8555896775450981f, 0.9146376165490196f, 1.0f}, + {0.8224204049411765f, 0.8568975165411765f, 0.9107951305882354f, 1.0f}, + {0.8267843164705883f, 0.8582053555372549f, 0.906952644627451f, 1.0f}, + {0.831148228f, 0.8595131945333333f, 0.9031101586666667f, 1.0f}, + {0.8353447113529412f, 0.8605139972941176f, 0.8989704099411765f, 1.0f}, + {0.839351442772549f, 0.861166825654902f, 0.8944937634156863f, 1.0f}, + {0.8433581741921568f, 0.8618196540156863f, 0.8900171168901961f, 1.0f}, + {0.8473649056117647f, 0.8624724823764706f, 0.885540470364706f, 1.0f}, + {0.8513716370313725f, 0.8631253107372548f, 0.8810638238392158f, 1.0f}, + {0.8553783684509804f, 0.8637781390980391f, 0.8765871773137255f, 1.0f}, + {0.8593850998705882f, 0.8644309674588235f, 0.8721105307882353f, 1.0f}, + {0.8674276350862745f, 0.864376599772549f, 0.8626024620196079f, 1.0f}, + {0.8714925112588235f, 0.8623093793176471f, 0.8570162640588236f, 1.0f}, + {0.8755573874313726f, 0.860242158862745f, 0.8514300660980393f, 1.0f}, + {0.8796222636039216f, 0.8581749384078431f, 0.845843868137255f, 1.0f}, + {0.8836871397764705f, 0.8561077179529412f, 0.8402576701764708f, 1.0f}, + {0.8877520159490196f, 0.8540404974980391f, 0.8346714722156863f, 1.0f}, + {0.8918168921215687f, 0.8519732770431372f, 0.829085274254902f, 1.0f}, + {0.8958817682941177f, 0.8499060565882353f, 0.8234990762941177f, 1.0f}, + {0.8995432066000001f, 0.8475002359999999f, 0.8177890744f, 1.0f}, + {0.9028486703176472f, 0.8447956505882352f, 0.8119698337411765f, 1.0f}, + {0.9061541340352941f, 0.8420910651764706f, 0.8061505930823529f, 1.0f}, + {0.9094595977529412f, 0.8393864797647058f, 0.8003313524235294f, 1.0f}, + {0.9127650614705882f, 0.8366818943529412f, 0.7945121117647058f, 1.0f}, + {0.9160705251882353f, 0.8339773089411765f, 0.7886928711058824f, 1.0f}, + {0.9193759889058823f, 0.8312727235294118f, 0.7828736304470588f, 1.0f}, + {0.9226814526235294f, 0.8285681381176471f, 0.7770543897882353f, 1.0f}, + {0.925563423f, 0.8255172980705883f, 0.7711363078117647f, 1.0f}, + {0.9281160096666666f, 0.8221971488627451f, 0.765141349254902f, 1.0f}, + {0.9306685963333333f, 0.818876999654902f, 0.7591463906980392f, 1.0f}, + {0.933221183f, 0.8155568504470588f, 0.7531514321411764f, 1.0f}, + {0.9357737696666666f, 0.8122367012392158f, 0.7471564735843139f, 1.0f}, + {0.9383263563333333f, 0.8089165520313726f, 0.741161515027451f, 1.0f}, + {0.940878943f, 0.8055964028235294f, 0.7351665564705883f, 1.0f}, + {0.9434315296666667f, 0.8022762536156862f, 0.7291715979137255f, 1.0f}, + {0.945540298909804f, 0.7986057405333333f, 0.7231054172980392f, 1.0f}, + {0.9473454036f, 0.7946955048f, 0.7169905058f, 1.0f}, + {0.9491505082901961f, 0.7907852690666667f, 0.7108755943019608f, 1.0f}, + {0.9509556129803922f, 0.7868750333333333f, 0.7047606828039216f, 1.0f}, + {0.9527607176705882f, 0.7829647976f, 0.6986457713058823f, 1.0f}, + {0.9545658223607844f, 0.7790545618666667f, 0.6925308598078431f, 1.0f}, + {0.9563709270509804f, 0.7751443261333334f, 0.6864159483098039f, 1.0f}, + {0.9581760317411765f, 0.7712340904f, 0.6803010368117647f, 1.0f}, + {0.9595176584705882f, 0.7669728545098039f, 0.6741447150392157f, 1.0f}, + {0.9605811984235294f, 0.7625010185254902f, 0.6679635471019607f, 1.0f}, + {0.9616447383764706f, 0.7580291825411765f, 0.6617823791647058f, 1.0f}, + {0.9627082783294117f, 0.7535573465568628f, 0.655601211227451f, 1.0f}, + {0.9637718182823529f, 0.7490855105725491f, 0.6494200432901962f, 1.0f}, + {0.9648353582352941f, 0.7446136745882352f, 0.6432388753529412f, 1.0f}, + {0.9658988981882353f, 0.7401418386039216f, 0.6370577074156862f, 1.0f}, + {0.9669624381411764f, 0.7356700026196078f, 0.6308765394784314f, 1.0f}, + {0.9675442976352941f, 0.7308497161882352f, 0.6246854782352941f, 1.0f}, + {0.9678738483176471f, 0.7258469080941177f, 0.6184892347843137f, 1.0f}, + {0.968203399f, 0.7208441f, 0.6122929913333334f, 1.0f}, + {0.9685329496823529f, 0.7158412919058823f, 0.6060967478823529f, 1.0f}, + {0.9688625003647059f, 0.7108384838117647f, 0.5999005044313725f, 1.0f}, + {0.9691920510470589f, 0.705835675717647f, 0.5937042609803921f, 1.0f}, + {0.9695216017294117f, 0.7008328676235294f, 0.5875080175294117f, 1.0f}, + {0.9698511524117647f, 0.6958300595294117f, 0.5813117740784314f, 1.0f}, + {0.9696829796666666f, 0.6904839307372549f, 0.5751383613647059f, 1.0f}, + {0.9692885689999999f, 0.6849817470823529f, 0.5689753262588235f, 1.0f}, + {0.9688941583333334f, 0.679479563427451f, 0.5628122911529412f, 1.0f}, + {0.9684997476666667f, 0.673977379772549f, 0.5566492560470588f, 1.0f}, + {0.968105337f, 0.6684751961176472f, 0.5504862209411766f, 1.0f}, + {0.9677109263333333f, 0.6629730124627451f, 0.5443231858352942f, 1.0f}, + {0.9673165156666667f, 0.6574708288078431f, 0.5381601507294118f, 1.0f}, + {0.966922105f, 0.6519686451529412f, 0.5319971156235295f, 1.0f}, + {0.9660167198392157f, 0.6461297415882352f, 0.5258903482588235f, 1.0f}, + {0.9649113881372549f, 0.6401590780588234f, 0.5198055987058824f, 1.0f}, + {0.963806056435294f, 0.6341884145294118f, 0.5137208491529413f, 1.0f}, + {0.9627007247333333f, 0.628217751f, 0.5076360996f, 1.0f}, + {0.9615953930313725f, 0.6222470874705882f, 0.5015513500470589f, 1.0f}, + {0.9604900613294117f, 0.6162764239411764f, 0.49546660049411767f, 1.0f}, + {0.9593847296274509f, 0.6103057604117648f, 0.4893818509411765f, 1.0f}, + {0.9582793979254902f, 0.604335096882353f, 0.48329710138823534f, 1.0f}, + {0.9566532109764706f, 0.598033822717647f, 0.4773022923529412f, 1.0f}, + {0.9548534056117647f, 0.5916223450078432f, 0.4713374634901961f, 1.0f}, + {0.9530536002470588f, 0.5852108672980392f, 0.465372634627451f, 1.0f}, + {0.951253794882353f, 0.5787993895882353f, 0.4594078057647059f, 1.0f}, + {0.9494539895176471f, 0.5723879118784315f, 0.453442976901961f, 1.0f}, + {0.9476541841529411f, 0.5659764341686274f, 0.4474781480392157f, 1.0f}, + {0.9458543787882353f, 0.5595649564588235f, 0.44151331917647063f, 1.0f}, + {0.9440545734235294f, 0.5531534787490197f, 0.4355484903137255f, 1.0f}, + {0.9417279298235294f, 0.5464134770196079f, 0.429707070372549f, 1.0f}, + {0.9392537715176471f, 0.5395814885647059f, 0.4239002049294118f, 1.0f}, + {0.9367796132117647f, 0.5327495001098039f, 0.41809333948627453f, 1.0f}, + {0.9343054549058823f, 0.525917511654902f, 0.4122864740431373f, 1.0f}, + {0.9318312966f, 0.5190855232f, 0.4064796086f, 1.0f}, + {0.9293571382941177f, 0.512253534745098f, 0.40067274315686274f, 1.0f}, + {0.9268829799882353f, 0.5054215462901961f, 0.3948658777137255f, 1.0f}, + {0.9244088216823529f, 0.49858955783529413f, 0.38905901227058826f, 1.0f}, + {0.921406221227451f, 0.49142041718431373f, 0.38340843537647057f, 1.0f}, + {0.9182816725843137f, 0.48417347218039214f, 0.37779392507058823f, 1.0f}, + {0.9151571239411764f, 0.4769265271764706f, 0.3721794147647059f, 1.0f}, + {0.9120325752980393f, 0.469679582172549f, 0.36656490445882356f, 1.0f}, + {0.908908026654902f, 0.46243263716862765f, 0.36095039415294133f, 1.0f}, + {0.9057834780117647f, 0.4551856921647059f, 0.35533588384705883f, 1.0f}, + {0.9026589293686275f, 0.4479387471607843f, 0.3497213735411765f, 1.0f}, + {0.8995343807254902f, 0.4406918021568627f, 0.34410686323529416f, 1.0f}, + {0.8958845948352941f, 0.43307455670588235f, 0.3386806345176471f, 1.0f}, + {0.8921375427882353f, 0.4253887370980392f, 0.33328927276078435f, 1.0f}, + {0.8883904907411765f, 0.41770291749019606f, 0.32789791100392157f, 1.0f}, + {0.8846434386941177f, 0.41001709788235297f, 0.32250654924705885f, 1.0f}, + {0.8808963866470588f, 0.4023312782745098f, 0.3171151874901961f, 1.0f}, + {0.8771493346f, 0.39464545866666667f, 0.31172382573333335f, 1.0f}, + {0.8734022825529412f, 0.3869596390588235f, 0.3063324639764706f, 1.0f}, + {0.8696552305058823f, 0.37927381945098043f, 0.30094110221960785f, 1.0f}, + {0.8653913329372549f, 0.3711276720470588f, 0.2957689564156863f, 1.0f}, + {0.8610536002941176f, 0.3629157635294118f, 0.2906281271764706f, 1.0f}, + {0.8567158676509804f, 0.3547038550117647f, 0.2854872979372549f, 1.0f}, + {0.8523781350078431f, 0.34649194649411763f, 0.2803464686980392f, 1.0f}, + {0.848040402364706f, 0.3382800379764708f, 0.2752056394588237f, 1.0f}, + {0.8437026697215686f, 0.3300681294588235f, 0.2700648102196078f, 1.0f}, + {0.8393649370784314f, 0.32185622094117644f, 0.26492398098039216f, 1.0f}, + {0.8350272044352941f, 0.3136443124235294f, 0.25978315174117644f, 1.0f}, + {0.8301865219490197f, 0.30473276355294115f, 0.25489142806666665f, 1.0f}, + {0.8252938101686275f, 0.2957488380941176f, 0.2500254739333333f, 1.0f}, + {0.8204010983882353f, 0.2867649126352941f, 0.2451595198f, 1.0f}, + {0.8155083866078432f, 0.2777809871764706f, 0.24029356566666665f, 1.0f}, + {0.810615674827451f, 0.26879706171764706f, 0.23542761153333333f, 1.0f}, + {0.8057229630470588f, 0.2598131362588235f, 0.2305616574f, 1.0f}, + {0.8008302512666666f, 0.2508292108f, 0.22569570326666666f, 1.0f}, + {0.7959375394862745f, 0.24184528534117647f, 0.22082974913333334f, 1.0f}, + {0.7905615319411765f, 0.23139699905882352f, 0.21624203829411764f, 1.0f}, + {0.7851533046784314f, 0.2208510887215686f, 0.21167287700784312f, 1.0f}, + {0.7797450774156863f, 0.21030517838431373f, 0.20710371572156863f, 1.0f}, + {0.7743368501529412f, 0.19975926804705882f, 0.2025345544352941f, 1.0f}, + {0.7689286228901963f, 0.18921335770980421f, 0.19796539314901973f, 1.0f}, + {0.763520395627451f, 0.17866744737254903f, 0.1933962318627451f, 1.0f}, + {0.758112168364706f, 0.1681215370352941f, 0.18882707057647058f, 1.0f}, + {0.7527039411019608f, 0.1575756266980392f, 0.1842579092901961f, 1.0f}, + {0.7468380122117647f, 0.14002101948235293f, 0.17999609695686275f, 1.0f}, + {0.7409573187529412f, 0.12224032527058823f, 0.17574419910588235f, 1.0f}, + {0.7350766252941177f, 0.10445963105882351f, 0.17149230125490195f, 1.0f}, + {0.7291959318352941f, 0.08667893684705881f, 0.16724040340392157f, 1.0f}, + {0.7233152383764706f, 0.06889824263529411f, 0.16298850555294117f, 1.0f}, + {0.717434544917647f, 0.05111754842352939f, 0.15873660770196077f, 1.0f}, + {0.7115538514588235f, 0.03333685421176469f, 0.1544847098509804f, 1.0f}, + {0.705673158f, 0.01555616f, 0.150232812f, 1.0f}, + }; + ImPlot::AddColormap("CoolWarm", (const ImVec4 *)s_values[cmap].data(), s_values[cmap].size(), false); + + for (cmap = 0; cmap < Colormap_COUNT; ++cmap) + { + s_textures[cmap] = std::make_unique( + Texture::PixelFormat::RGBA, Texture::ComponentFormat::Float32, int2(s_values[cmap].size(), 1), + Texture::InterpolationMode::Nearest, + cmap <= ImPlotColormap_Paired ? Texture::InterpolationMode::Nearest : Texture::InterpolationMode::Bilinear, + Texture::WrapMode::ClampToEdge, 1, Texture::TextureFlags::ShaderRead); + if (s_textures[cmap]->pixel_format() != Texture::PixelFormat::RGBA) + throw std::invalid_argument("Pixel format not supported by the hardware!"); + + s_textures[cmap]->upload((const uint8_t *)s_values[cmap].data()); + } +} +void Colormap::cleanup() +{ + for (int cmap = 0; cmap < Colormap_COUNT; ++cmap) s_textures[cmap].reset(); +} + +const char *Colormap::name(Colormap_ idx) { return ImPlot::GetColormapName(idx); } +Texture *Colormap::texture(Colormap_ idx) { return idx < Colormap_COUNT && idx >= 0 ? s_textures[idx].get() : nullptr; } +const std::vector &Colormap::values(Colormap_ idx) +{ + if (idx >= Colormap_COUNT || idx < 0) + throw std::invalid_argument(fmt::format("Invalid colormap index: {}", idx)); + return s_values[idx]; +} \ No newline at end of file diff --git a/src/colormap.h b/src/colormap.h new file mode 100644 index 00000000..76ebdf9e --- /dev/null +++ b/src/colormap.h @@ -0,0 +1,45 @@ +/** + \file colormap.h +*/ +#pragma once + +#include "fwd.h" +#include "implot.h" +#include + +using Colormap_ = int; +enum EColormap : Colormap_ +{ + Colormap_Deep = ImPlotColormap_Deep, // a.k.a. seaborn deep (qual=true, n=10) (default) + Colormap_Dark = ImPlotColormap_Dark, // a.k.a. matplotlib "Set1" (qual=true, n=9 ) + Colormap_Pastel = ImPlotColormap_Pastel, // a.k.a. matplotlib "Pastel1" (qual=true, n=9 ) + Colormap_Paired = ImPlotColormap_Paired, // a.k.a. matplotlib "Paired" (qual=true, n=12) + Colormap_Viridis = ImPlotColormap_Viridis, // a.k.a. matplotlib "viridis" (qual=false, n=11) + Colormap_Plasma = ImPlotColormap_Plasma, // a.k.a. matplotlib "plasma" (qual=false, n=11) + Colormap_Hot = ImPlotColormap_Hot, // a.k.a. matplotlib/MATLAB "hot" (qual=false, n=11) + Colormap_Cool = ImPlotColormap_Cool, // a.k.a. matplotlib/MATLAB "cool" (qual=false, n=11) + Colormap_Pink = ImPlotColormap_Pink, // a.k.a. matplotlib/MATLAB "pink" (qual=false, n=11) + Colormap_Jet = ImPlotColormap_Jet, // a.k.a. MATLAB "jet" (qual=false, n=11) + Colormap_Twilight = ImPlotColormap_Twilight, // a.k.a. matplotlib "twilight" (qual=false, n=11) + Colormap_RdBu = ImPlotColormap_RdBu, // red/blue, Color Brewer (qual=false, n=11) + Colormap_BrBG = ImPlotColormap_BrBG, // brown/blue-green, Color Brewer (qual=false, n=11) + Colormap_PiYG = ImPlotColormap_PiYG, // pink/yellow-green, Color Brewer (qual=false, n=11) + Colormap_Spectral = ImPlotColormap_Spectral, // color spectrum, Color Brewer (qual=false, n=11) + Colormap_Greys = ImPlotColormap_Greys, // white/black (qual=false, n=2 ) + Colormap_Inferno, + Colormap_Turbo, + Colormap_IceFire, + Colormap_CoolWarm, + Colormap_COUNT +}; + +class Colormap +{ +public: + static void initialize(); + static void cleanup(); + + static const char *name(Colormap_ idx); + static Texture *texture(Colormap_ idx); + static const std::vector &values(Colormap_ idx); +}; diff --git a/src/colorspace.h b/src/colorspace.h index 13bf0f17..fc3071dd 100644 --- a/src/colorspace.h +++ b/src/colorspace.h @@ -7,6 +7,9 @@ #pragma once #include "common.h" + +#include "colormap.h" + #include "fwd.h" #include #include @@ -332,13 +335,40 @@ inline float3 to_linear(const float3 &encoded, const TransferFunction tf, const void to_linear(float *pixels, int3 size, TransferFunction tf, float gamma = 2.2f); -inline Color3 tonemap(const Color3 color, float gamma, bool sRGB) +inline Color3 tonemap(const Color3 color, float gamma, Tonemap tonemap_mode, Colormap_ colormap) { - return sRGB ? LinearToSRGB(color) : LinearToGamma(color, Color3(1.f / gamma)); + switch (tonemap_mode) + { + default: return LinearToSRGB(color); + case Tonemap_Gamma: return LinearToGamma(color, float3{1.f / gamma}); + case Tonemap_FalseColor: [[fallthrough]]; + case Tonemap_PositiveNegative: + { + auto xform = tonemap_mode == Tonemap_FalseColor ? float2{1.f, 0.f} : float2{0.5f, 0.5f}; + float avg = dot(color, float3(1.f / 3.f)); + float cmap_size = Colormap::values(colormap).size(); + float t = lerp(0.5f / cmap_size, (cmap_size - 0.5f) / cmap_size, xform.x * avg + xform.y); + return LinearToSRGB(SRGBToLinear(float4{ImPlot::SampleColormap(saturate(t), colormap)}.xyz())); + } + } } -inline Color4 tonemap(const Color4 color, float gamma, bool sRGB) +inline Color4 tonemap(const Color4 color, float gamma, Tonemap tonemap_mode, Colormap_ colormap) { - return Color4(sRGB ? LinearToSRGB(color.xyz()) : LinearToGamma(color.xyz(), Color3(1.f / gamma)), color.w); + switch (tonemap_mode) + { + default: return LinearToSRGB(color); + case Tonemap_Gamma: return LinearToGamma(color, float3{1.f / gamma}); + case Tonemap_FalseColor: [[fallthrough]]; + case Tonemap_PositiveNegative: + { + auto xform = tonemap_mode == Tonemap_FalseColor ? float2{1.f, 0.f} : float2{0.5f, 0.5f}; + float avg = dot(color.xyz(), float3(1.f / 3.f)); + float cmap_size = Colormap::values(colormap).size(); + float t = lerp(0.5f / cmap_size, (cmap_size - 0.5f) / cmap_size, xform.x * avg + xform.y); + return float4(LinearToSRGB(SRGBToLinear(float4{ImPlot::SampleColormap(saturate(t), colormap)}.xyz()) * color.w), + color.w); + } + } } const std::vector &colorSpaceNames(); @@ -369,9 +399,9 @@ inline float4 color_u32_to_f128(uint32_t in) inline uint32_t color_f128_to_u32(const float4 &in) { uint32_t out; - out = ((uint32_t)(clamp01(in.x) * 255.f + 0.5f)) << HDRVIEW_COL32_R_SHIFT; - out |= ((uint32_t)(clamp01(in.y) * 255.f + 0.5f)) << HDRVIEW_COL32_G_SHIFT; - out |= ((uint32_t)(clamp01(in.z) * 255.f + 0.5f)) << HDRVIEW_COL32_B_SHIFT; - out |= ((uint32_t)(clamp01(in.w) * 255.f + 0.5f)) << HDRVIEW_COL32_A_SHIFT; + out = ((uint32_t)(saturate(in.x) * 255.f + 0.5f)) << HDRVIEW_COL32_R_SHIFT; + out |= ((uint32_t)(saturate(in.y) * 255.f + 0.5f)) << HDRVIEW_COL32_G_SHIFT; + out |= ((uint32_t)(saturate(in.z) * 255.f + 0.5f)) << HDRVIEW_COL32_B_SHIFT; + out |= ((uint32_t)(saturate(in.w) * 255.f + 0.5f)) << HDRVIEW_COL32_A_SHIFT; return out; } \ No newline at end of file diff --git a/src/common.cpp b/src/common.cpp index dac3d532..565eca53 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -100,10 +100,15 @@ string indent(string_view input, bool also_indent_first, int amount) return oss.str(); } +const vector &tonemap_names() +{ + static const vector names{"sRGB", "Gamma", "False color", "Positive/Negative"}; + return names; +} + const vector &channel_names() { - static const vector names{"RGB", "Red", "Green", "Blue", - "Alpha", "Luminance", "False color", "Negative-positive"}; + static const vector names{"RGBA", "Red", "Green", "Blue", "Alpha", "Luminance"}; return names; } diff --git a/src/common.h b/src/common.h index 23e0e500..9dc11161 100644 --- a/src/common.h +++ b/src/common.h @@ -49,7 +49,7 @@ inline T sign(T a) } template -inline T clamp01(T a) +inline T saturate(T a) { return std::clamp(a, T(0), T(1)); } @@ -119,7 +119,7 @@ inline T lerp_factor(T a, T b, T m) template inline T smoothstep(T a, T b, T x) { - T t = clamp01(lerp_factor(a, b, x)); + T t = saturate(lerp_factor(a, b, x)); return t * t * (T(3) - T(2) * t); } @@ -248,7 +248,7 @@ inline T brightness_contrast_linear(T v, T slope, T midpoint) template inline T brightness_contrast_nonlinear(T v, T slope, T bias) { - return gain_Perlin(bias_Schlick(clamp01(v), bias), slope); + return gain_Perlin(bias_Schlick(saturate(v), bias), slope); } //! Returns a modulus b. @@ -281,6 +281,7 @@ void process_lines(std::string_view input, std::function &tonemap_names(); const std::vector &channel_names(); const std::vector &blend_mode_names(); std::string channel_to_string(EChannel channel); diff --git a/src/fwd.h b/src/fwd.h index 59fa02a3..b437aa59 100644 --- a/src/fwd.h +++ b/src/fwd.h @@ -61,12 +61,21 @@ enum EChannel : int BLUE, ALPHA, Y, - FALSE_COLOR, - POSITIVE_NEGATIVE, NUM_CHANNELS }; +using Tonemap_ = int; +enum Tonemap : Tonemap_ +{ + Tonemap_sRGB = 0, + Tonemap_Gamma, + Tonemap_FalseColor, + Tonemap_PositiveNegative, + + Tonemap_COUNT +}; + enum EBlendMode : int { NORMAL_BLEND = 0, diff --git a/src/image.cpp b/src/image.cpp index 66054205..c54c06a4 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -882,7 +882,8 @@ float4 Image::raw_pixel(int2 p, Target target) const } // This implements a simplified CPU version of the glsl/metal fragment shaders used to render the image -float4 Image::shaded_pixel(int2 p, Target target, float gain, float gamma, bool sRGB) const +float4 Image::shaded_pixel(int2 p, Target target, float gain, float gamma, Tonemap tonemap_mode, + Colormap_ colormap) const { if (!contains(p)) return float4{0.f}; @@ -911,5 +912,5 @@ float4 Image::shaded_pixel(int2 p, Target target, float gain, float gamma, bool } value.xyz() = mul(M_to_Rec709, value.xyz()); - return tonemap(float4{gain * value.xyz(), value.w}, gamma, sRGB); + return tonemap(float4{gain * value.xyz(), value.w}, gamma, tonemap_mode, colormap); } diff --git a/src/image.h b/src/image.h index 865ea616..70687abf 100644 --- a/src/image.h +++ b/src/image.h @@ -340,7 +340,7 @@ struct Image void set_as_texture(Target target = Target_Primary); float4 raw_pixel(int2 p, Target target = Target_Primary) const; float4 shaded_pixel(int2 p, Target target = Target_Primary, float gain = 1.f, float gamma = 2.4f, - bool sRGB = true) const; + Tonemap tonemap = Tonemap_sRGB, Colormap_ colormap = Colormap_Inferno) const; std::map channels_in_layer(const std::string &layer) const; void build_layers_and_groups(); void finalize(); diff --git a/src/imageio.cpp b/src/imageio.cpp index 52803c6c..ca085004 100644 --- a/src/imageio.cpp +++ b/src/imageio.cpp @@ -31,6 +31,9 @@ vector Image::load(istream &is, const string &filename) Timer timer; try { + if (!is.good()) + throw invalid_argument("Invalid input stream"); + vector images; if (is_exr_image(is, filename))