What is the math that unity uses to bring an sRGB into shader graph linear space? (solved)

Edit: Solved

The solution TLDR is that gamma correction removal isn’t as simple as applying a curve ^2.2 to the values. Beneath is an entry from wikipedia and is AFAICT the math used by the graphics card to remove gamma correction and convert to linear values.

To undo this (put the texture back into gamma space), you also have to use a piece wise function. Below 0.00313, the conversion is linear (y = x/12.92), after that, it is y=(1+0.055)x^(1/2.4)-0.055 .

I notice there are still some slight errors in my lookup table, so some of these values are very slightly off, (but remapping my input from 0->1 to 0+1/256 ->0-1/256 solved all issues. 1/256 is the texel size.

Below is the relevant page on wikipedia I used to solve the problem (additional info can be found under the page “gamma correction”, with regards to where I pulled 0.00313 from:

A straight line that passes through (0,0) is y = x Φ {isplaystyle y={rac {x}{hi }}}, and a gamma curve that passes through (1,1) is y = ( x + A 1 + A ) Γ {isplaystyle y=eft({rac {x+A}{1+A}}ight)^{amma }}

If these are joined at the point (X,X/Φ) then:

X Φ = ( X + A 1 + A ) Γ {isplaystyle {rac {X}{hi }}=eft({rac {X+A}{1+A}}ight)^{amma }}

To avoid a kink where the two segments meet, the derivatives must be equal at this point:

1 Φ = Γ ( X + A 1 + A ) Γ − 1 ( 1 1 + A ) {isplaystyle {rac {1}{hi }}=amma eft({rac {X+A}{1+A}}ight)^{amma -1}eft({rac {1}{1+A}}ight)}

We now have two equations. If we take the two unknowns to be X and Φ then we can solve to give

X = A Γ − 1 , Φ = ( 1 + A ) Γ ( Γ − 1 ) Γ − 1 ( A Γ − 1 ) ( Γ Γ ) {isplaystyle X={rac {A}{amma -1}},hi ={rac {(1+A)^{amma }(amma -1)^{amma -1}}{(A^{amma -1})(amma ^{amma })}}}

The values A = 0.055 and Γ = 2.4 were chosen[how?] so the curve closely resembled the gamma-2.2 curve. This gives X ≈ 0.0392857, Φ ≈ 12.9232102. These values, rounded to X = 0.03928, Φ = 12.92321 sometimes describe sRGB conversion.[7]

Draft publications by sRGB’s creators further rounded Φ = 12.92,[2] resulting in a small discontinuity in the curve. Some authors adopted these incorrect values, in part because the draft paper was freely available and the official IEC standard is behind a paywall.[8] For the standard, the rounded value of Φ was kept and X was recomputed as 0.04045 to make the curve continuous,[a] resulting in a slope discontinuity from 1/12.92 below the intersection to 1/12.70 above.

OG POST: If an sRGB texture is in gamma space, from my understanding (working in linear space), shader graph removes the gamma correction so that rest of the shader gets to enjoy linear space calcualtions.

The thing is… I expect pow(2.2) and pow(1/2.2) to be the math used to go back and forth between gamma space and linear space, but this isn’t the case at all. It roughly approximates it, but there are errors.

I have a shader that uses a color channel as a lookup texture. I have confirmed that this shader works at all levels except where it attempts to gamma correct the texture. Using gamma math magic, pow(1/2.2). in the shader, I would expect that the original 0-255 will now be mapped linearly to 0-1 (ie 127 roughly = 0.5) But this isn’t the case, meaning whatever math is used by unity to remove gamma correction isn’t as simple as a 2.2 gamma curve. Taking the texture and using pow(1/2.2) mostly works, but not exactly, and the errors don’t work when using it as a UV in a palettle lookup.

Specifically, I notice that rgb values from 1-6 all get crushed to 6, and banding occurs throughout the table lookup to compensate.

To test this, I have a 256x1 Green ramp sRGB png (with values 0-255 in the G ch), I then have a 256x1 lookup texture with a repeating rainbow pattern that is 8 pixels wide. I use this to check for errors. If I inport the ramp with sRGB unchecked, and perform no gamma/linear conversions, it works perfectly as a UV input on the lookup texture. But if I check sRGB, unity removes the gamma correction adn I can’t figure out what the right math is to “effectly” map the texture RGB values 0-255 to 0-1 as though sRGB was unchecked.

For reasons, I need the sRGB checked, as I need the other two channels as they are in that mode.