Skip to content

Commit

Permalink
Add tonemapper that hashes to a random color
Browse files Browse the repository at this point in the history
  • Loading branch information
a-e-k committed Aug 11, 2024
1 parent 2c7e709 commit 451ae01
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 4 deletions.
1 change: 1 addition & 0 deletions include/tev/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ enum ETonemap : int {
Gamma,
FalseColor,
PositiveNegative,
Hash,

// This enum value should never be used directly.
// It facilitates looping over all members of this enum.
Expand Down
2 changes: 2 additions & 0 deletions src/Common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ ETonemap toTonemap(string name) {
return FalseColor;
} else if (name == "POSITIVENEGATIVE" || name == "POSNEG" || name == "PN" ||name == "+-") {
return PositiveNegative;
} else if (name == "HASH") {
return Hash;
} else {
return SRGB;
}
Expand Down
11 changes: 11 additions & 0 deletions src/ImageCanvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,17 @@ Vector3f ImageCanvas::applyTonemap(const Vector3f& value, float gamma, ETonemap
result = {-2.0f * mean(min(value, Vector3f{0.0f})), 2.0f * mean(max(value, Vector3f{0.0f})), 0.0f};
break;
}
case ETonemap::Hash:
{
static const auto fract = [](float x){ return x - floor(x); };
result = value;
result *= {abs(result.x()) < 1024.0f ? 1.0f : 1.0f / 1024.0f, abs(result.y()) < 1024.0f ? 1.0f : 1.0f / 1024.0f, abs(result.z()) < 1024.0f ? 1.0f : 1.0f / 1024.0f};
result *= {abs(result.x()) < 1024.0f ? 1.0f : 1.0f / 1024.0f, abs(result.y()) < 1024.0f ? 1.0f : 1.0f / 1024.0f, abs(result.z()) < 1024.0f ? 1.0f : 1.0f / 1024.0f};
result *= {abs(result.x()) < 1024.0f ? 1.0f : 1.0f / 1024.0f, abs(result.y()) < 1024.0f ? 1.0f : 1.0f / 1024.0f, abs(result.z()) < 1024.0f ? 1.0f : 1.0f / 1024.0f};
result = abs(fract(dot(result, Vector3f{115.191742f, 64.0546951f, 124.512291f})) - 0.5f) * Vector3f{1368.46143f, 1523.2019f, 1034.50476f};
result = {2.0f * abs(fract(result.x()) - 0.5f), 2.0f * abs(fract(result.y()) - 0.5f), 2.0f * abs(fract(result.z()) - 0.5f)};
break;
}
default:
throw runtime_error{"Invalid tonemap selected."};
}
Expand Down
10 changes: 7 additions & 3 deletions src/ImageViewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ using namespace std;

namespace tev {

static const int SIDEBAR_MIN_WIDTH = 230;
static const int SIDEBAR_MIN_WIDTH = 245;
static const float CROP_MIN_SIZE = 3;

ImageViewer::ImageViewer(
Expand Down Expand Up @@ -214,7 +214,7 @@ ImageViewer::ImageViewer(
// Tonemap options
{
mTonemapButtonContainer = new Widget{mSidebarLayout};
mTonemapButtonContainer->set_layout(new GridLayout{Orientation::Horizontal, 4, Alignment::Fill, 5, 2});
mTonemapButtonContainer->set_layout(new GridLayout{Orientation::Horizontal, 5, Alignment::Fill, 5, 2});

auto makeTonemapButton = [&](const string& name, function<void()> callback) {
auto button = new Button{mTonemapButtonContainer, name};
Expand All @@ -228,6 +228,7 @@ ImageViewer::ImageViewer(
makeTonemapButton("Gamma", [this]() { setTonemap(ETonemap::Gamma); });
makeTonemapButton("FC", [this]() { setTonemap(ETonemap::FalseColor); });
makeTonemapButton("+/-", [this]() { setTonemap(ETonemap::PositiveNegative); });
makeTonemapButton("Hash", [this]() { setTonemap(ETonemap::Hash); });

setTonemap(ETonemap::SRGB);

Expand All @@ -244,7 +245,10 @@ ImageViewer::ImageViewer(
"False-color visualization\n\n"

"+/-\n"
"Positive=Green, Negative=Red"
"Positive=Green, Negative=Red\n\n"

"Hash\n"
"Hash values to random colors"
);
}

Expand Down
23 changes: 22 additions & 1 deletion src/UberShader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ UberShader::UberShader(RenderPass* renderPass) {
# elif defined(NANOGUI_USE_GLES)
std::string preamble =
R"(#version 100
precision highp float;)";
precision highp float;
precision highp sampler2D;)";
# endif
auto vertexShader = preamble +
R"glsl(
Expand Down Expand Up @@ -51,6 +52,7 @@ UberShader::UberShader(RenderPass* renderPass) {
#define GAMMA 1
#define FALSE_COLOR 2
#define POS_NEG 3
#define HASH 4
#define ERROR 0
#define ABSOLUTE_ERROR 1
Expand Down Expand Up @@ -117,6 +119,13 @@ UberShader::UberShader(RenderPass* renderPass) {
}
}
vec3 hash(vec3 co){
co *= mix(vec3(1.0), vec3(1.0 / 1024.0), step(1024.0, abs(co)));
co *= mix(vec3(1.0), vec3(1.0 / 1024.0), step(1024.0, abs(co)));
co *= mix(vec3(1.0), vec3(1.0 / 1024.0), step(1024.0, abs(co)));
return 2.0 * abs(fract(abs(fract(dot(co, vec3(115.191742, 64.0546951, 124.512291))) - 0.5) * vec3(1368.46143, 1523.2019, 1034.50476)) - 0.5);
}
vec3 applyTonemap(vec3 col, vec4 background) {
if (tonemap == SRGB) {
col = col +
Expand All @@ -129,6 +138,8 @@ UberShader::UberShader(RenderPass* renderPass) {
return falseColor(log2(average(col)+0.03125) / 10.0 + 0.5) + (background.rgb - falseColor(0.0)) * background.a;
} else if (tonemap == POS_NEG) {
return vec3(-average(min(col, vec3(0.0))) * 2.0, average(max(col, vec3(0.0))) * 2.0, 0.0) + background.rgb * background.a;
} else if (tonemap == HASH) {
return hash(col) + (background.rgb - hash(vec3(offset))) * background.a;
}
return vec3(0.0);
}
Expand Down Expand Up @@ -230,6 +241,7 @@ UberShader::UberShader(RenderPass* renderPass) {
#define GAMMA 1
#define FALSE_COLOR 2
#define POS_NEG 3
#define HASH 4
#define ERROR 0
#define ABSOLUTE_ERROR 1
Expand Down Expand Up @@ -272,6 +284,13 @@ UberShader::UberShader(RenderPass* renderPass) {
}
}
float3 hash(float3 co){
co *= mix(float3(1.0f), float3(1.0f / 1024.0f), step(1024.0f, abs(co)));
co *= mix(float3(1.0f), float3(1.0f / 1024.0f), step(1024.0f, abs(co)));
co *= mix(float3(1.0f), float3(1.0f / 1024.0f), step(1024.0f, abs(co)));
return 2.0f * abs(fract(abs(fract(dot(co.xyz, float3(115.191742f, 64.0546951f, 124.512291f))) - 0.5f) * float3(1368.46143f, 1523.2019f, 1034.50476f)) - 0.5f);
}
float3 applyTonemap(float3 col, float4 background, int tonemap, float offset, float gamma, texture2d<float, access::sample> colormap, sampler colormapSampler) {
switch (tonemap) {
case SRGB:
Expand All @@ -286,6 +305,8 @@ UberShader::UberShader(RenderPass* renderPass) {
return falseColor(log2(average(col)+0.03125f) / 10.0f + 0.5f, colormap, colormapSampler) + (background.rgb - falseColor(0.0f, colormap, colormapSampler)) * background.a;
case POS_NEG:
return float3(-average(min(col, float3(0.0f))) * 2.0f, average(max(col, float3(0.0f))) * 2.0f, 0.0f) + background.rgb * background.a;
case HASH:
return hash(col) + (background.rgb - hash(float3(offset))) * background.a;
}
return float3(0.0f);
}
Expand Down
1 change: 1 addition & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ int mainFunc(const vector<string>& arguments) {
"Gamma - Gamma curve\n"
"FC - False Color\n"
"PN - Positive=Green, Negative=Red\n"
"Hash - Hash values to random colors\n"
"Default is sRGB.",
{'t', "tonemap"},
};
Expand Down

0 comments on commit 451ae01

Please sign in to comment.