File: ToneMapper.cpp

package info (click to toggle)
ospray 3.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 10,048 kB
  • sloc: cpp: 80,569; ansic: 951; sh: 805; makefile: 170; python: 69
file content (91 lines) | stat: -rw-r--r-- 2,625 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// Copyright 2009 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#include "ToneMapper.h"
#include "fb/FrameBufferView.h"

DECLARE_FRAMEOP_KERNEL_LAUNCHER(ToneMapper_kernelLauncher);

namespace ospray {

ToneMapperFrameOp::ToneMapperFrameOp(devicert::Device &device) : FrameOp(device)
{}

void ToneMapperFrameOp::commit()
{
  FrameOp::commit();

  exposure = getParam<float>("exposure", 1.f);
  // Default parameters fitted to the ACES 1.0 grayscale curve
  // (RRT.a1.0.3 + ODT.Academy.Rec709_100nits_dim.a1.0.3)
  // We included exposure adjustment to match 18% middle gray
  // (ODT(RRT(0.18)) = 0.18)
  const float aces_contrast = 1.6773f;
  const float aces_shoulder = 0.9714f;
  const float aces_midIn = 0.18f;
  const float aces_midOut = 0.18f;
  const float aces_hdrMax = 11.0785f;

  a = max(getParam<float>("contrast", aces_contrast), 0.0001f);
  d = clamp(getParam<float>("shoulder", aces_shoulder), 0.0001f, 1.f);

  float m = clamp(getParam<float>("midIn", aces_midIn), 0.0001f, 1.f);
  float n = clamp(getParam<float>("midOut", aces_midOut), 0.0001f, 1.f);

  float w = max(getParam<float>("hdrMax", aces_hdrMax), 1.f);
  acesColor = getParam<bool>("acesColor", true);

  // Solve b and c
  b = -((powf(m, -a * d)
            * (-powf(m, a)
                + (n
                      * (powf(m, a * d) * n * powf(w, a)
                          - powf(m, a) * powf(w, a * d)))
                    / (powf(m, a * d) * n - n * powf(w, a * d))))
      / n);

  // avoid discontinuous curve by clamping to 0
  c = max((powf(m, a * d) * n * powf(w, a) - powf(m, a) * powf(w, a * d))
          / (powf(m, a * d) * n - n * powf(w, a * d)),
      0.f);
}

std::unique_ptr<LiveFrameOpInterface> ToneMapperFrameOp::attach(
    FrameBufferView &fbView)
{
  return rkcommon::make_unique<LiveToneMapperFrameOp>(
      device, fbView, exposure, a, b, c, d, acesColor);
}

std::string ToneMapperFrameOp::toString() const
{
  return "ospray::ToneMapperFrameOp";
}

LiveToneMapperFrameOp::LiveToneMapperFrameOp(devicert::Device &device,
    FrameBufferView &fbView,
    float exposure,
    float a,
    float b,
    float c,
    float d,
    bool acesColor)
    : AddStructShared(device, device, fbView)
{
  // Pass tone mapping parameters
  getSh()->exposure = exposure;
  getSh()->a = a;
  getSh()->b = b;
  getSh()->c = c;
  getSh()->d = d;
  getSh()->acesColor = acesColor;
}

devicert::AsyncEvent LiveToneMapperFrameOp::process()
{
  const vec2ui &itemDims = getSh()->super.viewDims;
  return device.launchFrameOpKernel(
      itemDims, ispc::ToneMapper_kernelLauncher, &getSh()->super);
}

} // namespace ospray