Creating an HDR LUT from scratch in an OpenEXR texture: how to think about "HDR" (> 1.0) values

This really isn’t specific to the game industry, but I might as well put this here than somewhere else.

I am constructing a custom LUT using python and OpenEXR to make an unwrapped 3d texture (aka, 32x32x32 = 1024x32 texture). The use case is for covering HDR and SDR grades. FP32. All these questions deal with applying the grade in a linear pipeline, I have a display transform at the end that can either kick out to an HDR or SDR target. I suppose the actual grade will take place in a log gamma, applied, then expanded back out to linear.

So I start by filling my neutral LUT from 0 to 1 as you normally would:

Of course, this still doesn’t buy me anything for HDR, because I will be using this LUT in linear space, and the linear renders exceed 1.0 all the time. So I know that I want to shape the LUT by putting it in some kind of log space.

So here’s the start of my questions.

  1. Do I log encode the contents of the LUT?
    e.g. [r][g][b] = [logEncoded(r,g,b)]

  2. Do I extend the range of the LUT by indexing farther than one, essentially making the LUT color cube bigger? Seems like a huge waste of space since HDR only seldom goes outside the typical range, and I don’t think it makes sense to make some huge cube just for that. Related to question one: if I’m log-encoding the contents, that means I can index far higher than one without hitting 1.0 in the LUT itself. Am I thinking about this right?

  3. Is there some alternative like creating a floating point 0.0 - 1.0 LUT and then somehow just extending it to cover my HDR grades? Gamut mapping? What am I missing? I know 1D shaper LUTs are a thing but to me that seems the same as log encoding like my previous questions.

  4. For log encoding, is there a specific advantage to using some of the ACES supplied shaper LUT type algorithms (aka 1000 nit SP1D etc) over just encoding it in, say, ACEScc? Seems to serve the same purpose?

  5. What am I losing by using a log-encoding intended for a big display range like 1000 nit and also using it for the SDR case? The same linear grading pipeline applies for either case.

Any form of log encoding is good. With regards to ACEScc and ACEScct, the fact that their nominal range is not 0…1 but -something to a bit less than 1.47 gave me pain when encoding to textures. If one can live without pure blacks then the negative part can be omitted as ACEScc 0 decodes to aroundish 0.0012 linear. However, if linear values higher than 222 are needed then ACEScc will need to be scaled in order to make a bigger part of it fit into 0…1 . Be aware that a lot of other popular log encoding are not really better with regards to range and often clip lower. If you can custom fit your curve with a scale and offset for every individual LUT then you have all the power w.r.t. range and precision.

Hope that helps,