New <Exponent> Process Node

Tags: #<Tag:0x00007fd30aa36f30>

This process node is on the list to be added to the revised spec.

The node is intended to allow for achieving both basic “gamma” curves and “moncurve” gamma curves (i.e. linear segment near black).

Needs from the group:

  • agreement on name for node
  • decision on handling of values below 0 - pass-through? mirror? linear extension? clamp?
  • valid ranges for exponent attribute
  • valid ranges for offset attribute
  • is ExponentParams separatable per channel?

As of now, this node will have sub-elements:
<Description> - (optional)
<ExponentParams> (or other name) - (required) contains the attributes exponent and offset

The node will have attribute(s):
style - specifies the type of exponent function
Options for style are "basicFwd", "basicRev", "moncurveFwd", "moncurveRev"
For style="basic", only exponent attribute is recognized and valid.

Additional styles will need to be named and defined in order to provide for different negative handling options.

What options do interested parties require?

Hi Scott,

I wanted to follow up on the point you raised regarding how to handle negative values. We had a long discussion about this at SIGGRAPH during our OpenColorIO v2 working group meeting.

I presented the three likely options: clamp negatives, pass through negatives unchanged, pass through negatives by reflecting/mirroring the curve around the origin. (I also expressed my preference to settle on the third choice.)

The overwhelming preference of the OCIO v2 working group was to allow for all three choices. The reason for that is that there currently is no consistency in how various apps handle this issue. The working group members were able to cite major applications as examples of each of the three techniques. These are apps they are often called upon to emulate, hence the desire to have a way to do that.

It’s worth pointing out that the existing Range process node may be used to clamp negatives. So one option would be to have styles for the two non-clamping options and implement the clamping one by pre-pending a Range. But I would say the preference of the group was to have a separate style option for all three.

Note that the “moncurve” or ExponentWithLinear type of curve (sRGB, L*, Rec.709) is not an issue since I think we all agree that the linear segment should just continue down into the negative values.


If anyone would like to offer feedback on the formulation of the new Exponent node, it would be much appreciated.

Overleaf: Draft of <Exponent> Node (only)

I toyed with many different ways to lay out the section and describe the formulas. Originally I was much more explicit for each individual context but realized the formulas were redundant and I wanted to make it more apparent to those reading the spec that the “mirror”, “passthru” and “clamp” options are all minor conditional variants on top of the base functions.

Do the provided options meet all the needed behaviors?
There is currently also a “mirror” option included for moncurve, too, which might be overkill. Would there ever be a use case for this or is extending the linear portion always the preferred method for moncurve-type contexts? Easy to remove if we want to further simplify…

Looking forward to any and all feedback from the group while I continue to work on other sections.


1 Like

This looks great Scott! I think the way you’ve structured it is very clear.

I think it does cover all the required options, although I think the mirror option on moncurve is not necessary (although I don’t object to it if others want it). The main motivation for needing the three negative-handling methods for the basic power was because people could name popular examples that used that approach and they needed to be able to emulate it. For moncurve, I’m not aware of other parametric implementations of that, so there isn’t as much of a compelling need for more options.

A few minor proof-reading points:

  1. I think the moncurveRev formula is missing a “- k” at the end.
  2. The first Note on page 3 is redundant from the first paragraph.
  3. I would clarify that the offset param is not allowed for the basic types.
  4. Alpha (A) should be an allowed channel parameter.
  5. The examples are missing the style attribute.
  6. The question of what range of values should be allowed is a tricky one. For the basic styles I would recommend 0.01 to 100. For the moncurve style I would recommend 1.0 to 10.0 for exponent and 0.0 to 0.9 for the offset. Those are the bounds currently in OCIO. (I could elaborate more on the reasoning, let me know if it’s useful.)
  7. Very minor, but perhaps change “basic” to “main” in the second sentence just to avoid confusion with the basic power styles. And at the end of that paragraph perhaps change “Rec. 709” to “Rec. 709 (OETF)”.

Good progress!

1 Like

9 posts were split to a new topic: Handling of alpha channels when processing CLF

Thanks for taking a look and for the helpful comments.

I’ve seen mirror be used with a log curve but not for exponent functions. If no one has a need for moncurve mirror, it will be removed. Still there for now - but likely unnecessary. Easy to cut.

If we allow offset to be 0.0…
then in the case that offset=“0.0”, is the “moncurve” function supposed to be equivalent to the “basic” formula?
Will the k in the denominator of the definition of s cause any issues for code implementations? (divide by 0?)

Yep, originally I had set it to zero because it made sense that it should “default” to that if not provided (i.e. the exponent w/ linear function then follows the “basic” formulation). But I realized it was to avoid the divide by 0 so had changed it to 1e-6.

I tend to agree that it’s cleaner to make it be 0 (as long as implementers are warned that they should protect against that case).


Just throwing a couple of thoughts into the mix (and I realise it’s probably a bit late, because I missed a few VWG meetings).

I vote for the removal of “moncurveFwdMirror” and “moncurveRevMirror”. They seem redundant.

Is “moncurve” a confusing name? I assume that is an abbreviation of “monitor curve”, and the Rec. 709 curve is absolutely not a monitor curve (EOTF); it is an OETF. The sRGB curve is a monitor curve, but as specified currently the “moncurveRev” style needs to be used to implement the sRGB EOTF. This is a bit counterintuitive. Logically the forward form of a monitor curve should be the EOTF, should it not?

On the subject of sRGB, the example given states that it applies “the EOTF found in IEC 61966-2-1:1999 (sRGB)”. This is not strictly true. It produces an idealised form of the sRGB EOTF, where the tangent at the break point is an exact match for the linear portion. This is not exactly the case with the rounded constants given in the standard. It is not possible to exactly replicate the sRGB curve from the IEC standard using the moncurve formula. Whether this actually matters is a different question!

I have not investigated, but I suspect that the same may be the case for some camera log curves.

Lastly, for ease of understandability, might it be easier to use the same calculation of s for moncurveFwd and moncurveRev, and just use moncurveFwd(x) = x * s and moncurveRev(y) = y / s below the respective break points?

1 Like

I also often am confused in the CTL where the function names are moncurve_f and moncurve_r. To me these seem labeled the opposite of what my brain assumes naturally. In other contexts (my Matlab and here) I’ve kept the similar function names so that I can match to the CTL. However, this is a new node and so we can theoretically call these whatever we want.

What names other than “moncurve” would you suggest? EOTF? ExponentWithLinear? Let the naming debate begin…