Creating shapers using basic operators


(Scott Dyer) #1

In the last VWG meeting, we discussed how the halfDomain attribute allows for 1D LUTs where one can specify exactly how each value should be mapped. There was discussion about creating a tool to assist with making such LUTs, since it tends to be confusing for inexperienced people to do.

It was also discussed that we should determine the basic grammar operators that would be needed to manipulate LUTs as shapers. Are there one or more base parametric forms that would allows us to represent the majority of log-lin conversions? There was discussion about being able to use OCIO as a guideline and @doug_walker volunteered to try to add the various log things that we were looking at (“log w/ linear”) and we were also aware that PQ could be problematic with fitting into these forms.

What are the basic operators we need to allow for a parametric process node that will cover the majority of needs for lin-log conversions?

Unique cases that don’t fit the parametric forms or those LUT creators who want to would still be able to use the halfDomain attribute for exact 1D LUT coverage.


Meeting - CLF Spec / Code Review - 2/6/19 9am pst
(doug_walker) #2

JD / Scott,

Following up on my action item from the previous meeting, here is a proposal for adding a Log operator to CLF that could be used for a variety of lin-to-log type transforms.

There are three classes of these transforms that I think we should support. First there is the basic logarithm. OCIO has this and it is regularly used (along with an affine transform) to create shaper transforms when needing to apply linear values to LUTs. Second, there is the classic Cineon type lin-to-log transform and the related Josh Pines type transform (the latter being similar to Cineon but is more fun at parties, also it handles blacks better!). These can be implemented as an affine transform (a multiply and add), followed by a logarithm, followed by another affine transform. Third, there is a Cineon type curve with the addition of a linear section near black. This handles most of the digital camera log curves including Alexa LogC (for typical EIs), Sony SLog3, Panasonic VLog, and Red Log3G10, as well as ACEScct.

So here is a rough proposal for an XML syntax that could represent these three types of log curves.

Basic logarithm examples (base 10 and 2 allowed):

 <Log inBitDepth="16f" outBitDepth="12i" style="log10" />
 <Log inBitDepth="12i" outBitDepth="16f" style="antiLog10" />
 <Log inBitDepth="16f" outBitDepth="12i" style="log2" />
 <Log inBitDepth="12i" outBitDepth="16f" style="antiLog2" />

Cineon style logarithm examples:

<Log inBitDepth="32f" outBitDepth="10i" style="linToLog">
    <LogParams gamma="0.6" refBlack=" 95." refWhite="685." highlight="1.0" shadow="0.0" />
</Log>
<Log inBitDepth="10i" outBitDepth="32f" style="logToLin">
    <LogParams gamma="0.6" refBlack=" 95." refWhite="685." highlight="1.0" shadow="0.0" />
</Log>

If the parameters are different per channel, they may be expressed this way:

  <LogParams channel="R" gamma="0.5" refWhite="681" refBlack="95" highlight="0.9" shadow="0.0045" />
  <LogParams channel="G" gamma="0.6" refWhite="682" refBlack="94" highlight="1" shadow="0.0025" />
  <LogParams channel="B" gamma="0.65" refWhite="683" refBlack="93" highlight="0.8" shadow="0.0035" />

In order to be more in line with OCIO, we should also allow specifying the LogParams as follows:

<Log inBitDepth="32f" outBitDepth="10i" style="linToLog">
    <LogParams linSideSlope="1.0" linSideOffset="0.0" logSideSlope="1.0" logSideOffset="0.0" base="10.0"  />
</Log>

The implied lin-to-log equation is:
y = logSideSlope * log( linSideSlope * x + linSideOffset, base ) + logSideOffset;

(If the traditional refBlack/refWhite/gamma syntax above is used, those parameters may be converted to utilize this same equation too.)

Finally, the Camera Log style transforms would be written as follows:

<Log inBitDepth="32f" outBitDepth="10i" style="cameraLinToLog">
    <LogParams linSideSlope="1.0" linSideOffset="0.0" logSideSlope="1.0" logSideOffset="0.0" linSideBreak="0.0" linearGain="1.0" base="10.0"  />
</Log>
<Log inBitDepth="10i" outBitDepth="32f" style="cameraLogToLin">
    <LogParams linSideSlope="1.0" linSideOffset="0.0" logSideSlope="1.0" logSideOffset="0.0" linSideBreak="0.0" linearGain="1.0" base="10.0"  />
</Log>

The implied lin-to-log equation is:

if (x <= linSideBreak)
  y = x * linearGain + k;
else
  y = logSideSlope * log( linSideSlope * x + linSideOffset, base ) + logSideOffset;

And where k is calculated so the two pieces are continuous at the break point. The linearGain parameter is optional. If it is missing, the default is to calculate it so that the two pieces are also continuous in slope (e.g., like ACEScct).

There are some details to be filled in such as more detailed pseudo-code and the details around bit-depth, and I could add these in a more formal proposal later if there is interest in proceeding. Also, there are some other log-like curves such as PQ and HLG that are not covered here. That said, hopefully the above will at least serve as a good strawman to continue the discussion.

Doug

p.s. If you receive this as an email and the formatting is difficult to read, please look at the message on ACESCentral. Thx