mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-01-21 05:00:06 -05:00
export raw histogram data
This commit is contained in:
parent
6ef145e76e
commit
a7b4cc70d6
@ -1137,6 +1137,25 @@ eRenderStatus Renderer<T, bucketT>::AccumulatorToFinalImage(vector<v4F>& pixels,
|
||||
return eRenderStatus::RENDER_ERROR;
|
||||
}
|
||||
|
||||
if (RawHistogram())
|
||||
{
|
||||
auto p = pixels.data() + finalOffset;
|
||||
auto q = m_AccumulatorBuckets.data();
|
||||
auto bytes = sizeof(*p) * FinalRasW();
|
||||
parallel_for(size_t(0), FinalRasH(), size_t(1), [&](size_t j)
|
||||
{
|
||||
auto pixelsRowStart = (m_YAxisUp ? ((FinalRasH() - j) - 1) : j) * FinalRasW();//Pull out of inner loop for optimization.
|
||||
auto rowStart = j * m_SuperRasW;
|
||||
memcpy(p + pixelsRowStart, q + rowStart, bytes);
|
||||
}
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
, tbb::static_partitioner()
|
||||
#endif
|
||||
);
|
||||
LeaveFinalAccum();
|
||||
return m_Abort ? eRenderStatus::RENDER_ABORT : eRenderStatus::RENDER_OK;
|
||||
}
|
||||
|
||||
//Timing t(4);
|
||||
const size_t filterWidth = m_SpatialFilter->FinalFilterWidth();
|
||||
bucketT g, linRange, vibrancy;
|
||||
|
@ -374,6 +374,40 @@ void RendererBase::ReclaimOnResize(bool reclaimOnResize)
|
||||
ChangeVal([&] { m_ReclaimOnResize = reclaimOnResize; }, eProcessAction::FULL_RENDER);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get whether to output raw histogram values instead of gamma corrected
|
||||
/// colours.
|
||||
/// Default: false.
|
||||
/// </summary>
|
||||
/// <returns>True if raw, else false.</returns>
|
||||
bool RendererBase::RawHistogram() const { return m_RawHistogram; }
|
||||
|
||||
/// <summary>
|
||||
/// Set whether to output raw histogram values instead of gamma corrected
|
||||
/// colours.
|
||||
/// </summary>
|
||||
/// <param name="rawHistogram">True if raw, else false.</param>
|
||||
void RendererBase::RawHistogram(bool rawHistogram)
|
||||
{
|
||||
ChangeVal([&] { m_RawHistogram = rawHistogram; }, eProcessAction::ACCUM_ONLY);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get whether to output raw histogram values before density filtering.
|
||||
/// Default: false.
|
||||
/// </summary>
|
||||
/// <returns>True if raw, else false.</returns>
|
||||
bool RendererBase::RawHistogramPreDensity() const { return m_RawHistogramPreDensity; }
|
||||
|
||||
/// <summary>
|
||||
/// Set whether to output raw histogram values before density filtering.
|
||||
/// </summary>
|
||||
/// <param name="rawHistogram">True if pre density, else false.</param>
|
||||
void RendererBase::RawHistogramPreDensity(bool rawHistogramPreDensity)
|
||||
{
|
||||
ChangeVal([&] { m_RawHistogramPreDensity = rawHistogramPreDensity; }, eProcessAction::ACCUM_ONLY);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the callback object.
|
||||
/// </summary>
|
||||
|
@ -156,6 +156,10 @@ public:
|
||||
void InsertPalette(bool insertPalette);
|
||||
bool ReclaimOnResize() const;
|
||||
void ReclaimOnResize(bool reclaimOnResize);
|
||||
bool RawHistogram() const;
|
||||
void RawHistogram(bool rawHistogram);
|
||||
bool RawHistogramPreDensity() const;
|
||||
void RawHistogramPreDensity(bool rawHistogramPreDensity);
|
||||
void Callback(RenderCallback* callback);
|
||||
void ThreadCount(size_t threads, const char* seedString = nullptr);
|
||||
size_t BytesPerChannel() const;
|
||||
@ -207,6 +211,8 @@ protected:
|
||||
bool m_InFinalAccum = false;
|
||||
bool m_InsertPalette = false;
|
||||
bool m_ReclaimOnResize = false;
|
||||
bool m_RawHistogram = false;
|
||||
bool m_RawHistogramPreDensity = false;
|
||||
bool m_CurvesSet = false;
|
||||
volatile bool m_Abort = false;
|
||||
volatile bool m_Pause = false;
|
||||
|
@ -332,6 +332,8 @@ bool EmberAnimate(int argc, _TCHAR* argv[], EmberOptions& opt)
|
||||
r->EarlyClip(opt.EarlyClip());
|
||||
r->YAxisUp(opt.YAxisUp());
|
||||
r->LockAccum(opt.LockAccum());
|
||||
r->RawHistogram(opt.RawHistogram());
|
||||
r->RawHistogramPreDensity(opt.RawHistogramPreDensity());
|
||||
r->PixelAspectRatio(T(opt.AspectRatio()));
|
||||
r->Priority(eThreadPriority(Clamp<intmax_t>(intmax_t(opt.Priority()), intmax_t(eThreadPriority::LOWEST), intmax_t(eThreadPriority::HIGHEST))));
|
||||
}
|
||||
@ -471,7 +473,7 @@ bool EmberAnimate(int argc, _TCHAR* argv[], EmberOptions& opt)
|
||||
vector<float> g(size);
|
||||
vector<float> b(size);
|
||||
vector<float> a(size);
|
||||
Rgba32ToRgba32Exr(finalImagep, r.data(), g.data(), b.data(), a.data(), w, h, opt.Transparency());
|
||||
Rgba32ToRgba32Exr(finalImagep, r.data(), g.data(), b.data(), a.data(), w, h, opt.Transparency(), ! opt.RawHistogram());
|
||||
const auto writeSuccess = WriteExr32(fn.c_str(),
|
||||
r.data(),
|
||||
g.data(),
|
||||
|
@ -433,8 +433,36 @@ template <typename T, typename bucketT>
|
||||
bool RendererCL<T, bucketT>::ReadFinal(v4F* pixels)
|
||||
{
|
||||
if (pixels && !m_Devices.empty())
|
||||
{
|
||||
if (RawHistogram())
|
||||
{
|
||||
if (RawHistogramPreDensity() ? ReadHist(0) : ReadAccum())
|
||||
{
|
||||
auto p = pixels;
|
||||
auto q = RawHistogramPreDensity() ? HistBuckets() : AccumulatorBuckets();
|
||||
auto bytes = sizeof(*p) * FinalRasW();
|
||||
parallel_for(size_t(0), FinalRasH(), size_t(1), [&](size_t j)
|
||||
{
|
||||
auto pixelsRowStart = (m_YAxisUp ? ((FinalRasH() - j) - 1) : j) * FinalRasW();//Pull out of inner loop for optimization.
|
||||
auto rowStart = j * SuperRasW();
|
||||
memcpy(p + pixelsRowStart, q + rowStart, bytes);
|
||||
}
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
, tbb::static_partitioner()
|
||||
#endif
|
||||
);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_Devices[0]->m_Wrapper.ReadImage(m_FinalImageName, FinalRasW(), FinalRasH(), 0, m_Devices[0]->m_Wrapper.Shared(), pixels);
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -310,9 +310,12 @@ static void Rgba32ToRgbaExr(const v4F* rgba, Rgba* ilmfRgba, size_t width, size_
|
||||
/// <param name="width">The width of the image in pixels</param>
|
||||
/// <param name="height">The height of the image in pixels</param>
|
||||
/// <param name="doAlpha">True to use alpha transparency, false to assign the max alpha value to make each pixel fully visible</param>
|
||||
static void Rgba32ToRgba32Exr(const v4F* rgba, float* r, float* g, float* b, float* a, size_t width, size_t height, bool doAlpha)
|
||||
/// <param name="doClamp">True to clamp output to 0..1, false to use full high dynamic range</param>
|
||||
static void Rgba32ToRgba32Exr(const v4F* rgba, float* r, float* g, float* b, float* a, size_t width, size_t height, bool doAlpha, bool doClamp)
|
||||
{
|
||||
if (rgba != nullptr && r != nullptr && g != nullptr && b != nullptr && a != nullptr)
|
||||
{
|
||||
if (doClamp)
|
||||
{
|
||||
for (size_t i = 0; i < (width * height); i++)
|
||||
{
|
||||
@ -322,6 +325,17 @@ static void Rgba32ToRgba32Exr(const v4F* rgba, float* r, float* g, float* b, flo
|
||||
a[i] = doAlpha ? Clamp<float>(rgba[i].a * 1.0f, 0.0f, 1.0f) : 1.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < (width * height); i++)
|
||||
{
|
||||
r[i] = rgba[i].r;
|
||||
g[i] = rgba[i].g;
|
||||
b[i] = rgba[i].b;
|
||||
a[i] = rgba[i].a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -70,6 +70,8 @@ enum class eOptionIDs : et
|
||||
OPT_DUMP_KERNEL,
|
||||
OPT_FLAM3_COMPAT,
|
||||
OPT_IGNORE_EXISTING,
|
||||
OPT_RAW_HISTOGRAM,
|
||||
OPT_RAW_HISTOGRAM_PRE_DENSITY,
|
||||
|
||||
//Value args.
|
||||
OPT_NTHREADS,//Int value args.
|
||||
@ -378,6 +380,8 @@ public:
|
||||
INITBOOLOPTION(DumpKernel, Eob(eOptionUse::OPT_USE_RENDER, eOptionIDs::OPT_DUMP_KERNEL, _T("--dump_kernel"), false, SO_NONE, " --dump_kernel Print the iteration kernel string when using OpenCL (ignored for CPU) [default: false].\n"));
|
||||
INITBOOLOPTION(Flam3Compat, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_FLAM3_COMPAT, _T("--flam3_compat"), false, SO_NONE, " --flam3_compat The behavior of the cos, cosh, cot, coth, csc, csch, sec, sech, sin, sinh, tan and tanh variations are different in flam3/Apophysis versus Chaotica. True for flam3/Apophysis behavior, false for Chaotica behavior [default: true].\n"));
|
||||
INITBOOLOPTION(IgnoreExisting, Eob(eOptionUse::OPT_USE_ANIMATE, eOptionIDs::OPT_IGNORE_EXISTING, _T("--ignore-existing"), false, SO_NONE, " --ignore-existing Skip animating a frame if the output images for all of the specified file output types already exist in the output folder [default: false].\n"));
|
||||
INITBOOLOPTION(RawHistogram, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_RAW_HISTOGRAM, _T("--raw_histogram"), false, SO_NONE, " --raw_histogram Output raw histogram values (after density filter, before gamma correction). For best results, use EXR 32-bit float and set supersampling to 1x. [default: false].\n"));
|
||||
INITBOOLOPTION(RawHistogramPreDensity, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_RAW_HISTOGRAM_PRE_DENSITY, _T("--raw_histogram_pre_density"), false, SO_NONE, " --raw_histogram_pre_density Output raw histogram values before density filter instead of afterwards. Requires --raw_histogram. [default: false].\n"));
|
||||
//Int.
|
||||
INITINTOPTION(Symmetry, Eoi(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_SYMMETRY, _T("--symmetry"), 0, SO_REQ_SEP, " --symmetry=<val> Set symmetry of result [default: 0].\n"));
|
||||
INITINTOPTION(SheepGen, Eoi(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_SHEEP_GEN, _T("--sheep_gen"), -1, SO_REQ_SEP, " --sheep_gen=<val> Sheep generation of this flame [default: -1].\n"));
|
||||
@ -541,6 +545,8 @@ public:
|
||||
PARSEBOOLOPTION(eOptionIDs::OPT_DUMP_KERNEL, DumpKernel);
|
||||
PARSEBOOLOPTION(eOptionIDs::OPT_FLAM3_COMPAT, Flam3Compat);
|
||||
PARSEBOOLOPTION(eOptionIDs::OPT_IGNORE_EXISTING, IgnoreExisting);
|
||||
PARSEBOOLOPTION(eOptionIDs::OPT_RAW_HISTOGRAM, RawHistogram);
|
||||
PARSEBOOLOPTION(eOptionIDs::OPT_RAW_HISTOGRAM_PRE_DENSITY, RawHistogramPreDensity);
|
||||
PARSEOPTION(eOptionIDs::OPT_SYMMETRY, Symmetry);//Int args
|
||||
PARSEOPTION(eOptionIDs::OPT_SHEEP_GEN, SheepGen);
|
||||
PARSEOPTION(eOptionIDs::OPT_SHEEP_ID, SheepId);
|
||||
@ -833,6 +839,8 @@ public:
|
||||
Eob DumpKernel;
|
||||
Eob Flam3Compat;
|
||||
Eob IgnoreExisting;
|
||||
Eob RawHistogram;
|
||||
Eob RawHistogramPreDensity;
|
||||
|
||||
Eoi Symmetry;//Value int.
|
||||
Eoi SheepGen;
|
||||
|
@ -603,6 +603,8 @@ bool EmberGenome(int argc, _TCHAR* argv[], EmberOptions& opt)
|
||||
renderer->EarlyClip(opt.EarlyClip());
|
||||
renderer->YAxisUp(opt.YAxisUp());
|
||||
renderer->LockAccum(opt.LockAccum());
|
||||
renderer->RawHistogram(opt.RawHistogram());
|
||||
renderer->RawHistogramPreDensity(opt.RawHistogramPreDensity());
|
||||
renderer->PixelAspectRatio(T(opt.AspectRatio()));
|
||||
|
||||
if (opt.Repeat() == 0)
|
||||
|
@ -153,6 +153,8 @@ bool EmberRender(int argc, _TCHAR* argv[], EmberOptions& opt)
|
||||
renderer->EarlyClip(opt.EarlyClip());
|
||||
renderer->YAxisUp(opt.YAxisUp());
|
||||
renderer->LockAccum(opt.LockAccum());
|
||||
renderer->RawHistogram(opt.RawHistogram());
|
||||
renderer->RawHistogramPreDensity(opt.RawHistogramPreDensity());
|
||||
renderer->InsertPalette(opt.InsertPalette());
|
||||
renderer->PixelAspectRatio(T(opt.AspectRatio()));
|
||||
renderer->Priority(eThreadPriority(Clamp<intmax_t>(intmax_t(opt.Priority()), intmax_t(eThreadPriority::LOWEST), intmax_t(eThreadPriority::HIGHEST))));
|
||||
@ -447,7 +449,7 @@ bool EmberRender(int argc, _TCHAR* argv[], EmberOptions& opt)
|
||||
vector<float> g(size);
|
||||
vector<float> b(size);
|
||||
vector<float> a(size);
|
||||
Rgba32ToRgba32Exr(finalImagep, r.data(), g.data(), b.data(), a.data(), finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, opt.Transparency());
|
||||
Rgba32ToRgba32Exr(finalImagep, r.data(), g.data(), b.data(), a.data(), finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, opt.Transparency(), ! opt.RawHistogram());
|
||||
const auto writeSuccess = WriteExr32(filename.c_str(),
|
||||
r.data(),
|
||||
g.data(),
|
||||
|
@ -183,7 +183,8 @@ bool FractoriumEmberControllerBase::SaveCurrentRender(const QString& filename, c
|
||||
vector<float> g(size);
|
||||
vector<float> b(size);
|
||||
vector<float> a(size);
|
||||
Rgba32ToRgba32Exr(data, r.data(), g.data(), b.data(), a.data(), width, height, transparency);
|
||||
bool raw_histogram = false;
|
||||
Rgba32ToRgba32Exr(data, r.data(), g.data(), b.data(), a.data(), width, height, transparency, ! raw_histogram);
|
||||
ret = WriteExr32(s.c_str(), r.data(), g.data(), b.data(), a.data(), width, height, true, comments, id, url, nick);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user