Conversion between sRGB-encoded and linear-light color values.
sRGB is the encoding of most images and displays: it spends more of its range on dark values than linear light does, so blend, filter and light in linear space and encode on output. Each conversion comes as a float form, a Vector3 (red, green, blue) form and a Vector4 form that leaves alpha as it is. The exact curves are srgb_to_linear and linear_to_srgb; the _fast forms use a table and the _pow2 and _sqrt forms a gamma of 2.0, both cheaper and less accurate. Values outside [0, 1] are not clamped.
Converts one sRGB-encoded value in [0, 1] to linear light with the exact piecewise sRGB curve: a straight segment x / 12.92 up to 0.04045 and ((x + 0.055) / 1.055) ^ 2.4 above it. 0 gives 0 and 1 gives 1. Values outside [0, 1] are not clamped: the curve is evaluated as written, so a negative input stays negative and a large one is extrapolated.
Converts one linear-light value in [0, 1] to sRGB encoding with the exact piecewise curve (the inverse of srgb_to_linear): x * 12.92 up to 0.0031308 and 1.055 * x ^ (1 / 2.4) - 0.055 above it. Values outside [0, 1] are not clamped; clamp first when the result feeds an 8-bit store.
The fast path uses a piecewise linear interpolant of the exact transfer curve.
Sampling in encoded space concentrates linear-domain samples near black.
A faster srgb_to_linear for values in [0, 1]: linear interpolation over a 64-segment table of the exact curve, built at compile time, so there is no pow call at run time. The error is below about 0.002 in the linear result. Inputs of 1 or more fall back to the exact curve, and the linear segment below 0.04045 is exact.
A faster linear_to_srgb for values in [0, 1]: a binary search over the same 64-segment table, inverted by linear interpolation, so there is no pow call at run time. The error is below about 0.003 in the encoded result. Inputs of 1 or more fall back to the exact curve, and the linear segment below 0.0031308 is exact.
Approximates srgb_to_linear by squaring each channel, a gamma of 2.0 instead of the sRGB curve. Cheap, and within a few percent of the real curve in the middle of the range (0.5 gives 0.25 instead of 0.214), but noticeably off near black.
Approximates linear_to_srgb by taking the square root of each channel, a gamma of 2.0 instead of the sRGB curve (the inverse of srgb_to_linear_pow2). A negative channel gives NaN.