ExpressionTransformation for OCIO?


Mark Boorer <mark...@...>
 

Hi Ben,


* I'm surprised your lin-log transform cannot be nicely applied as a 1D LUT.  Even with a large 2**16 or 2**32 line LUT? Would a different interpolation help (e.g cubic)?

My example where a 1D lut would be insufficient is where the source image is already in float linear, and a grading operation is to be applied in log (like saturation). Here negative values are acceptable, and we would expect them to be preserved when converted back to lin. When using a 1D lut, negative values (and positive values greater than 1) would be clamped off.


The GPU code path for this expression-transform would be difficult. Not sure how big a deal this is, as I have little experience with such things, but: Compiling the expression to shader code sounds doable but difficult. Baking the expressions to a LUT for the GPU seems might be more practical (using the AllocationOps to define the range the expression applies over)

I had a quick search for the current GPU shader code, but only found a process that generates a 3D lut as a texture, then does a simple lookup to generate output frag colors. Is there a mode complex model that accurately follows the CPU computation? Because that was another point I was hoping to raise :D

* OCIO's Transforms have a "hasChannelCrosstalk" method - since deterring this from an arbitrary expression might be impractical, so I guess when defining the transform you would have to specify if it's a 1D transform (e.g !<ExprTransform> {expr: "v**2"}) or 3D expression (e.g !<ExprTransform> {expr: "r+g+b/3", is3d:true})
 
I imagined either providing a single expression for 1D transforms, or 3 expressions for 3D, but I like the idea of the expression engine pre-setting the variables "x" or "r,g,b" when toggled via a bool.

Could you let me know where to look for the current GPU implementations? Obviously duplicating the effort of expression compilation on the GPU would be insane, but I don't have any other immediate ideas. Personally I'm happy with just a CPU based solution.



On Friday, August 30, 2013 4:25:51 PM UTC+1, dbr/Ben wrote:
There was discussion of a CTLTransform (Color Transform Language) in the past, although it would probably require OCIO to have a plugin interface for transforms, because having the OCIO core depend on CTL which depends on IlmBase is.. not ideal..



exprtk seems interesting, and looks "small enough" to be included in the core, as done with md5/pystring (Jeremy could say more authoritatively). The SeExpr project also seems suitable. Would definitely be interesting to see a prototype of the transform..


Some other random thoughts:

* I'm surprised your lin-log transform cannot be nicely applied as a 1D LUT.  Even with a large 2**16 or 2**32 line LUT? Would a different interpolation help (e.g cubic)?

* The GPU code path for this expression-transform would be difficult. Not sure how big a deal this is, as I have little experience with such things, but: Compiling the expression to shader code sounds doable but difficult. Baking the expressions to a LUT for the GPU seems might be more practical (using the AllocationOps to define the range the expression applies over)

Baking the expression to a LUT defeats the purpose you mention, but it would be useful in other cases (e.g we have a several colourspaces which are defined by simple expressions, but we currently have to bake these out as LUTs - would be much tidier as an expression-transform)

* OCIO's Transforms have a "hasChannelCrosstalk" method - since deterring this from an arbitrary expression might be impractical, so I guess when defining the transform you would have to specify if it's a 1D transform (e.g !<ExprTransform> {expr: "v**2"}) or 3D expression (e.g !<ExprTransform> {expr: "r+g+b/3", is3d:true})

On 31/08/2013, at 12:05 AM, Mark Boorer wrote:

Hi,

I'm currently looking at moving our existing color pipeline tools over to OCIO, and I'm wondering if anyone can see a place for such a feature.

In our current setup, some of our log to lin conversions cannot be adequately expressed via a 1D lut, and for grading operations the changes caused by interpolation are too great.

I'm proposing to write an Expression Transformation, which would allow us to express these transformation operations via a string, and evaluate them using exprtk or a similar library.

Has anything like this been proposed before? Does anyone have any thoughts? I'm hoping to knock up a proof of concept over the next few weeks.

Cheers,
Mark


--
You received this message because you are subscribed to the Google Groups "OpenColorIO Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ocio-dev+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Jeremy Selan <jeremy...@...>
 




On Fri, Aug 30, 2013 at 9:11 AM, Mark Boorer <mark...@...> wrote:
Hi Ben,



* I'm surprised your lin-log transform cannot be nicely applied as a 1D LUT.  Even with a large 2**16 or 2**32 line LUT? Would a different interpolation help (e.g cubic)?

My example where a 1D lut would be insufficient is where the source image is already in float linear, and a grading operation is to be applied in log (like saturation). Here negative values are acceptable, and we would expect them to be preserved when converted back to lin. When using a 1D lut, negative values (and positive values greater than 1) would be clamped off.



You may be interested in experimenting with the .spi1d lut format, it's actually rather general.

The spi1d format is unique in allowing LDR on an input axis, and HDR on the output axis. So if you wanted to have a log to linear lut, which supports HDR linear, but also maps negative values into a reasonable range in log space such a lut could be formulated.  And it supports both inverse / forward operations at full fidelity, so as long as both of your axes are not HDR it works great.

Mocking up a small demonstration of your use case...

The input domain for the LUT below is log space.  But rather than defining only the range of 0-1, I've extended it to -0.25,1.25 to allow for 'negative' log values as you mentioned.  So for the samples you see, they represent uniform steps in log space from of [-0.25, 0.0, 0.25, 0.5, 1.0, 1.25] The output domain is scene-linear.

> mylogtolin.spi1d

Version 1
From -0.25 1.25
Length 7
Components 1
{
    -0.05
     0.0
     0.05
     0.18
     1.5
     13.0
     55.0
}

You will be able to use such a LUT, at full fidelity, in programs such as nuke in either the forward (log->lin) or inverse (lin->log) directions.  Obviously a real lut would have much higher number of samples.