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
import sys import OpenImageIO as oiio import numpy as np def miplevels(fpath): b_all = oiio.ImageBuf(fpath) for miplevel in range(0, b_all.nmiplevels): # open the mipmap level b = oiio.ImageBuf(fpath, 0, miplevel) # get all the pixels pixels = b.get_pixels(oiio.FLOAT) # slice pixels from the first channel pixels = pixels[::b.nchannels] # sort pixel values pixels = np.sort(pixels) print "{0} {1}x{2}={3} min={4} med={5} max={6}".format( miplevel, b.ymax - b.ymin + 1, b.xmax - b.xmin + 1, len(pixels), pixels[0], pixels[len(pixels) / 2], pixels[-1]) if __name__ == "__main__": miplevels(sys.argv[1])
_______________________________________________ Oiio-dev mailing list Oiio-dev@lists.openimageio.org http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org