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