I think your understanding and mine are in sync.

At this step I'm looking for (1): a way to "truly save sRGB" rather than
just save filtered values derived from samples which were once converted to
RGB.

I hadn't thought of (2) but that's a really good point; "true sRGB" texture
data isn't a fully correct solution without linearization before filtering.

I'm not overly concerned about (3) because we've got a proprietary solution
called "texture bundles" which explicitly specify the linearizing LUT for
our textures.

Can (4) be avoided by keeping the texture cache as a cache of the actual
texture data, and re-linearizing every time we need the values? Whether
this is a good idea probably depends how many textures we want to fit in
RAM. (Answer: so, so many. Probably worthwhile for us.)


On Mon, 11 Jan 2021 at 00:30, Larry Gritz <l...@larrygritz.com> wrote:

> OH, I get it.
>
> --colorconvert in out means "Convert the source image from `in` to `out`
> before turning it into a MIP-map."
>
> It does NOT mean "convert the source from `in` to linear, and then when
> writing the MIPmap convert it to `out`."
>
> So your source texture, the checkerboard, has values 0.0 and 1.0 only, and
> when you convert those from linear to "sRGB", they are still 0.0 and 1.0,
> respectively, so the rest proceeds apace, and your 1x1 fully filtered layer
> ends up pretty darned close to 0.5.
>
> It assumes that you write a linear file. Maybe because the texture system
> assumes all its input is linear. Using linear math for the downsizing when
> creating the MIPmap is not enough. ALL the math inside the texture system
> for blending between pixels (the filtering of the individual texture
> lookups) is also linear, and will be wrong if the map is sRGB.
>
> You could make an argument, I suppose, that this is all not as flexible as
> you'd want, and that you want to store nonlinear textures. You'd need a
> number of changes:
>
> (1) a way to instruct maketx to do a second color conversion upon output
> to the color space of your choice (i.e. truly save sRGB).
>
> (2) to have an option in the texture system to color convert BACK to a
> linear space upon reading tiles, so that the filtering math will be
> correct, because it's not correct to convert sRGB->linear in the shader
> itself after the filter math is done, the conversion has to be upstream of
> the filter math.
>
> (3) to figure out how you're going to be able to tell, for a TIFF texture,
> whether it's intended to be linear or in some other color space, because
> TIFF doesn't directly say this anywhere. (Maybe you could rely on the file
> naming convention, like maybe you seem to with checker_uint8_sRGB.tx?)
>
> (4) If you have a uint8 sRGB texture on disk, and you want to be
> converting to linear as the tiles are read into the texture cache... ugh,
> you don't want those tiles to be uint8 or you'll lose a lot of precision in
> the darks. So in addition to converting sRGB to linear, you also want to
> convert from uint8 to, I dunno, maybe uint16 or half for storage in the
> cache? Which also makes it consume twice as much cache space?
>
> (By the way, `info -a -stats foo.tx` is also your friend for inspecting
> value ranges.)
>
>
> On Jan 10, 2021, at 4:09 PM, Larry Gritz <l...@larrygritz.com> wrote:
>
> That's right, the FLOAT here just means "give me the values as floats",
> and it does not imply any color space conversion.
>
> So, the question is why the --colorconvert linear sRGB doesn't end up with
> a 1x1 miplevel that's farther from 0.5. I also would have the same
> expectation as you.
>
> Let me look a bit through the code...
>
>
> On Jan 10, 2021, at 3:41 PM, Søren Ragsdale <sor...@gmail.com> wrote:
>
> I assumed oiio.FLOAT describes the data type and that script wouldn't know
> whether the texture it was reading was UINT8 linear, gamma22, or sRGB.
>
> That assumption seems to be correct. I changed the script to UINT8 and I'm
> still getting basically the same result. Black is 0 and white is 255 but
> 50% gray should be higher than 128 due to the nonlinear sRGB LUT:
>
> $ python ~/scripts-dev/miplevels.py checker_uint8_sRGB.tx
>> 0 512x512=262144 min=0 med=255 max=255
>> 1 256x256=65536 min=0 med=255 max=255
>> 2 128x128=16384 min=0 med=255 max=255
>> 3 64x64=4096 min=0 med=255 max=255
>> 4 32x32=1024 min=127 med=127 max=155
>> 5 16x16=256 min=127 med=127 max=142
>> 6 8x8=64 min=127 med=127 max=135
>> 7 4x4=16 min=127 med=129 max=131
>> 8 2x2=4 min=128 med=129 max=129
>> 9 1x1=1 min=129 med=129 max=129
>>
>
> As a sanity check I made a uniform 50% grey texture and the values are at
> 188, consistent with sRGB 50% grey:
>
> $ iinfo --stats grey_float32_lin.tif
>> grey_float32_lin.tif :  512 x  512, 3 channel, float tiff
>>     Stats Min: 0.500000 0.500000 0.500000 (float)
>>     Stats Max: 0.500000 0.500000 0.500000 (float)
>>     Stats Avg: 0.500000 0.500000 0.500000 (float)
>>     Stats StdDev: 0.000000 0.000000 0.000000 (float)
>>     Stats NanCount: 0 0 0
>>     Stats InfCount: 0 0 0
>>     Stats FiniteCount: 262144 262144 262144
>>     Constant: Yes
>>     Constant Color: 0.500000 0.500000 0.500000 (float)
>>     Monochrome: Yes
>>
>
> $ maketx --oiio -d uint8 --unpremult --colorconvert linear sRGB
>> grey_float32_lin.tif -o grey_uint8_sRGB.tx
>>
>
>
> $ python ~/scripts-dev/miplevels.py grey_uint8_sRGB.tx
>> 0 512x512=262144 min=188 med=188 max=188
>> 1 256x256=65536 min=188 med=188 max=188
>> 2 128x128=16384 min=188 med=188 max=188
>> 3 64x64=4096 min=188 med=188 max=188
>> 4 32x32=1024 min=188 med=188 max=188
>> 5 16x16=256 min=188 med=188 max=188
>> 6 8x8=64 min=188 med=188 max=188
>> 7 4x4=16 min=188 med=188 max=188
>> 8 2x2=4 min=188 med=188 max=188
>> 9 1x1=1 min=188 med=188 max=188
>
>
> On Sun, 10 Jan 2021 at 18:48, Solomon Boulos <bou...@cs.stanford.edu>
> wrote:
>
>> Doesn’t get as float convert from sRGB to Linear in your miplevels.py? If
>> you don’t want conversion, open it as int8.
>>
>> On Sun, Jan 10, 2021 at 10:39 Søren Ragsdale <sor...@gmail.com> wrote:
>>
>>> I have "checker_float32_lin.tif", a simple RGBA black and white
>>> checkerboard. Each black or white square is 8 pixels wide, and every pixel
>>> value is either 0.0 or 1.0.
>>>
>>> I'm using OIIO to turn this float32 scene-linear TIFF into a uint8 sRGB
>>> albedo texture:
>>>
>>> maketx --oiio -d uint8 --unpremult --colorconvert linear sRGB
>>> checker_float32_lin.tif -o checker_uint8_sRGB.tx
>>>
>>> I've written miplevels.py (see attached) which prints the min, median,
>>> and max values of the first color channel for each mipmap level of the
>>> texture. Here's the output:
>>>
>>> $ python ~/scripts-dev/miplevels.py checker_uint8_sRGB.tx
>>>> 0 512x512=262144 min=0.0 med=1.0 max=1.0
>>>> 1 256x256=65536 min=0.0 med=1.0 max=1.0
>>>> 2 128x128=16384 min=0.0 med=1.0 max=1.0
>>>> 3 64x64=4096 min=0.0 med=1.0 max=1.0
>>>> 4 32x32=1024 min=0.498039245605 med=0.498039245605 max=0.607843160629
>>>> 5 16x16=256 min=0.498039245605 med=0.498039245605 max=0.556862771511
>>>> 6 8x8=64 min=0.498039245605 med=0.498039245605 max=0.529411792755
>>>> 7 4x4=16 min=0.498039245605 med=0.505882382393 max=0.51372551918
>>>> 8 2x2=4 min=0.501960813999 med=0.505882382393 max=0.505882382393
>>>> 9 1x1=1 min=0.505882382393 med=0.505882382393 max=0.505882382393
>>>
>>>
>>> As the mipmaps decrease in size the median value converges on 0.5.
>>> Except this is a sRGB texture. The value for 50% grey should be around
>>> 0.737 in sRGB space.
>>>
>>> It appears maketx is converting the values from linear to sRGB then
>>> scaling to create the mipmaps. When the source and destination color space
>>> are specified I think maketx should scale in scene linear color space,
>>> *then* convert to sRGB before saving each mipmap.
>>>
>>> Is this a bug? Is there a flag or workaround that I should know about?
>>>
>>>
>>> https://paroj.github.io/gltut/Texturing/Tut16%20Mipmaps%20and%20Linearity.html
>>> _______________________________________________
>>> Oiio-dev mailing list
>>> Oiio-dev@lists.openimageio.org
>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>>
>> _______________________________________________
>> Oiio-dev mailing list
>> Oiio-dev@lists.openimageio.org
>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>
> <miplevels.py>_______________________________________________
> Oiio-dev mailing list
> Oiio-dev@lists.openimageio.org
> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>
>
> --
> Larry Gritz
> l...@larrygritz.com
>
>
>
>
> _______________________________________________
> Oiio-dev mailing list
> Oiio-dev@lists.openimageio.org
> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>
>
> --
> Larry Gritz
> l...@larrygritz.com
>
>
>
>
> _______________________________________________
> Oiio-dev mailing list
> Oiio-dev@lists.openimageio.org
> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>
_______________________________________________
Oiio-dev mailing list
Oiio-dev@lists.openimageio.org
http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org

Reply via email to