ktx_create(1)

πŸ“¦ version 4.4.2, in nixos 26.05, nixpkgs unstable

πŸŽ€ ktx_create(1) β€” KTX Tools Reference πŸŽ€

okay bestie, buckle up, because ktx_create is the one that actually makes your KTX2 files from scratch and it has, like, a lot of options. no cap. the man page name is ktx_create, it lives in the KTX Tools Reference, and it is genuinely iconic once you get the vibe. let's go πŸ’…


🌸 NAME

ktx_create β€” ktx create

Create a KTX2 file from various input files. that's it, that's the whole job 🫢


✨ SYNOPSIS

ktx create [option...] input-file... output-file

πŸ¦‹ DESCRIPTION

ktx create can create, encode and supercompress a KTX2 file from the input images you pass as the input-file... arguments, and then save it as the output-file. literally the last positional argument is always treated as the output-file β€” that's the rule, no exceptions πŸ’€

If the input-file is '-' the file will be read from the stdin. If the output-path is '-' the output file will be written to the stdout. pipes, we love to see it πŸŽ€

Each input-file must be a valid EXR (.exr), PNG (.png) or Raw (.raw) file. PNG files with luminance (L) or luminance + alpha (LA) data will be converted to RGB as LLL and RGBA as LLLA before processing further. noted, bestie β€” it handles that for you ✨

The input file formats must be compatible with the requested KTX format enum and must have at least the same level of precision and number of channels. Any unused channel will be discarded silently. silently! she's not gonna warn you, she's just gonna do it πŸ™ˆ

The number of input-files you specify must match the expected number of input images based on the used options. so like, do the math before you run it, otherwise it's giving error energy 😭


πŸ”₯ OPTIONS

πŸ’– General Options

The following are available:

  • --format <enum> β€” the KTX format enum that specifies the data format for the images in the created texture. the enum names match the VkFormat names without the VK_FORMAT_ prefix. The VK_FORMAT_ prefix is ignored if present. Case insensitive. Required. πŸ”₯

If the format is an ASTC format, a texture object with the target format R8G8B8_{SRGB,UNORM} or R8G8B8A8_{SRGB,UNORM} is created then encoded to the specified ASTC format. The latter format is chosen if alpha is present in the input. SRGB or UNORM is chosen depending on the specified ASTC format. The ASTC-specific and common encoder options listed below become valid, otherwise they are ignored. This matches the functionality of the ktx encode command when an ASTC format is specified. she's consistent like that πŸ’…

When used with --encode it specifies the target format before the encoding step. In this case it must be one of:

  • R8_UNORM
  • R8_SRGB
  • R8G8_UNORM
  • R8G8_SRGB
  • R8G8B8_UNORM
  • R8G8B8_SRGB
  • R8G8B8A8_UNORM
  • R8G8B8A8_SRGB

The format will be used to verify and load all input files into a texture before performing any specified encoding.

  • --encode basis-lz | uastc β€” encode the texture with the specified codec before saving it. This option matches the functionality of the ktx encode command. With each choice, the specific and common encoder options listed below become valid, otherwise they are ignored. Case-insensitive.
    • basis-lz: supercompress the image data with transcodable ETC1S / BasisLZ. RED images will become RGB with RED in each component (RRR). RG images will have R in the RGB part and G in the alpha part of the compressed texture (RRRG). When set, the basis-lz options become valid. πŸ”₯
    • uastc: create a texture in high-quality transcodable UASTC format. When set the uastc options become valid. πŸ‘‘
  • --1d β€” create a 1D texture. If not set the texture will be a 2D or 3D texture.
  • --cubemap β€” create a cubemap texture. If not set the texture will be a 2D or 3D texture. six faces, main character energy 🌈
  • --raw β€” create from raw image data.
  • --width β€” base level width in pixels. Required with --raw. For non-raw, if not set, the image width is used, otherwise the image is resampled to this width and any provided mip levels are resampled proportionately. For non-raw it enables use of the 'Generate Mipmap' options listed under --generate-mipmap to tune the resampler.
  • --height β€” base level height in pixels. Required with --raw. For non-raw, if not set, the image height is used, otherwise the image is resampled to this height and any provided mip levels are resampled proportionately. For non-raw it enables use of the 'Generate Mipmap' options listed under --generate-mipmap to tune the resampler.
  • --depth β€” base level depth in pixels. If set the texture will be a 3D texture. 🧊
  • --layers β€” number of layers. If set the texture will be an array texture.
  • --levels β€” number of mip levels. This is the number of level images to include in the texture being created. If --generate-mipmap is specified this number of level images will be generated, otherwise this number of input images must be provided. Generates an error if the value is greater than the maximum possible for the specified dimensions of the texture or, for non-raw, the dimensions of the base level image as possibly modified by --scale. ⚠️
  • --runtime-mipmap β€” runtime mipmap generation mode. Sets up the texture to request the mipmaps to be generated by the client application at runtime.
  • --generate-mipmap β€” causes mipmaps to be generated during texture creation. If --levels is not specified the maximum possible mip level will be generated. This option is mutually exclusive with --runtime-mipmap and cannot be used with SINT, UINT or 3D textures or --raw. When set it enables the use of the following 'Generate Mipmap' options. ✨
  • --mipmap-filter <filter> β€” specifies the filter to use when generating the mipmaps. Case insensitive. Ignored unless --generate-mipmap, --scale, --width or --height are specified for non-raw input.

Possible options are: box | tent | bell | b-spline | mitchell | blackman | lanczos3 | lanczos4 | lanczos6 | lanczos12 | kaiser | gaussian | catmullrom | quadratic_interp | quadratic_approx | quadratic_mix. Defaults to lanczos4. πŸŽ€

  • --mipmap-filter-scale <float> β€” the filter scale to use. Defaults to 1.0. Ignored unless --generate-mipmap, --scale, --width or --height are specified for non-raw input.
  • --mipmap-wrap <mode> β€” specify how to sample pixels near the image boundaries. Case insensitive. Ignored unless --generate-mipmap, --scale, --width or --height are specified for non-raw input.

Possible options are: wrap | reflect | clamp. Defaults to clamp.

⚠️ Avoid mipmap generation if the Output TF (see TRANSFER FUNCTION HANDLING below) is non-linear and is not sRGB. like, seriously, don't πŸ’€
  • --scale β€” scale images as they are loaded. Cannot be used with --raw. It enables use of the 'Generate Mipmap' options listed under --generate-mipmap to tune the resampler.
  • --normalize β€” normalize input normals to have a unit length. Only valid for linear normal textures with 2 or more components. For 2-component inputs 2D unit normals are calculated. Do not use these 2D unit normals to generate X+Y normals with --normal-mode. For 4-component inputs a 3D unit normal is calculated. 1.0 is used for the value of the 4th component. Cannot be used with --raw. 🧚
  • --swizzle [rgba01]{4} β€” KTX swizzle metadata.
  • --input-swizzle [rgba01]{4} β€” pre-swizzle input channels.
  • --assign-tf <transfer function> β€” force the created texture to have the specified transfer function, ignoring the transfer function of the input file(s). Possible options match the khr_df_transfer_e enumerators without the KHR_DF_TRANSFER_ prefix. The KHR_DF_TRANSFER_ prefix is ignored if present. Case insensitive. The options are: linear | srgb | srgb_eotf | scrgb | scrgb_eotf | itu | itu_oetf | bt601 | bt601_oetf | bt709 | bt709_oetf | bt2020 | bt2020_oetf | smpte170m | smpte170m_oetf | smpte170m_eotf | ntsc | ntsc_eotf | slog | slog_oetf | slog2 | slog2_oetf | bt1886 | bt1886_eotf | hlg_oetf | hlg_eotf | pq_oetf | pg_eotf | dcip3 | dcip3_eotf | pal_oetf | pal625_eotf | st240 | st240_oetf | st240_eotf | acescc | acescc_oetf | acescct | acescct_oetf | abobergb | adobergb_eotf. See TRANSFER FUNCTION HANDLING below for important information. πŸ‘€
  • --assign-oetf <transfer function> β€” deprecated and will be removed. Use --assign-tf instead.
  • --assign-primaries <primaries> β€” force the created texture to have the specified color primaries, ignoring the color primaries of the input file(s). Possible options match the khr_df_primaries_e enumerators without the KHR_DF_PRIMARIES_ prefix. The KHR_DF_PRIMARIES_ prefix is ignored if present. Case insensitive. The options are: none | bt709 | srgb | bt601_ebu | bt601_smpte | bt2020 | ciexyz | aces | acescc | ntsc1953 | pal525 | displayp3 | adobergb.
Note 🫢 bt601-ebu and bt601-smpte, supported in previous releases, have been replaced with names consistent with khr_df_primaries_e. so use the new names, bestie, the old ones are gone.
  • --assign-texcoord-origin <corner> β€” force the created texture to indicate that the texture coordinate origin s=0, t=0 is at the specified corner of the logical image. Case insensitive. Possible options are top-left | bottom-left. -front | -back can be appended and one of these is required when --depth is specified. Must be top-left if --cubemap is specified. Absent --convert-texcoord-origin, the effect of this option is to cause KTXorientation metadata indicating the specified origin to be written to the output file. Example values are "rd" (top-left) and "ru" (bottom-left) or, when --depth is specified, "rdi" (top-left-front) and "rui" (bottom-left-front). πŸŽ€
  • --convert-tf <transfer function> β€” convert the input image(s) to the specified transfer function, if different from the transfer function of the input file(s). If both this and --assign-tf are specified, conversion will be performed from the assigned transfer function to the transfer function specified by this option, if different. Cannot be used with --raw. Case insensitive. The options are: linear | srgb. The following srgb aliases are also supported: srgb_eotf | scrgb | scrgb_eotf. See TRANSFER FUNCTION HANDLING below for more information. 🌈
  • --convert-oetf <transfer function> β€” deprecated and will be removed. Use --convert-tf instead.
  • --convert-primaries <primaries> β€” Converts the input image(s) to the specified color primaries if they’re different from the color primaries of the input file(s) or the ones set by --assign-primaries. If you specify both this and --assign-primaries, conversion happens from the assigned primaries to the primaries you gave this option, if different. Not allowed when --assign-primaries is set to 'none'. Cannot be used with --raw. Possible options match the khr_df_primaries_e enumerators without the KHR_DF_PRIMARIES_ prefix. The KHR_DF_PRIMARIES_ prefix is ignored if present. Case insensitive. The options are: bt709 | srgb | bt601_ebu | bt601_smpte | bt2020 | ciexyz | aces | acescc | ntsc1953 | pal525 | displayp3 | adobergb
Note: bt601-ebu and bt601-smpte, supported in previous releases, have been replaced with names consistent with khr_df_primaries_e.
  • --convert-texcoord-origin <corner> β€” Converts the input image(s) so the texture coordinate origin s=0, t=0 is at the specified corner of the logical image. If both this and --assign-texcoord-origin are specified, conversion will be performed from the assigned origin to the origin specified by this option, if different. The default for images in KTX files is top-left, which corresponds to the origin in most image file formats. Cannot be used with --raw. Case insensitive. Possible options are: top-left | bottom-left. -front | -back can be appended and one of these is required when --depth is specified. Must be top-left if --cubemap is specified.

Input images whose origin does not match corner will be flipped vertically. KTXorientation metadata indicating the specified origin is written to the output file. Example values are "rd" (top-left) and "ru" (bottom-left) or, when --depth is specified, "rdi" (top-left-front) and "rui" (bottom-left-back). Generates an error if the input image origin is unknown as is the case with raw image data. Use --assign-texcoord-origin to specify the orientation.

Note: ktx create cannot rotate or flip incoming images, except for a y-flip, so use an image processing tool to reorient images whose first data stream pixel is not at the logical top-left or bottom-left of the image before using as input here. Such images may be indicated by Exif-style orientation metadata in the file.
  • --fail-on-color-conversions β€” Generates an error if any input images would need to be color converted.
  • --warn-on-color-conversions β€” Generates a warning if any input images are color converted. Adds warnings for explicitly requested and visually lossless implicit conversions to that generated for visually lossy conversions.
  • --no-warn-on-color-conversions β€” Disable all warnings about color conversions including that for visually lossy conversions. Overrides --warn-on-color-conversions should both be specified.
  • --fail-on-origin-changes β€” Generates an error if any of the input images would need to have their origin changed.
  • --warn-on-origin-changes β€” Generates a warning if any of the input images have their origin changed.
  • --zstd <level> β€” Supercompress the data with Zstandard. Cannot be used with ETC1S / BasisLZ format. Level range is [1,22]. Lower levels give faster but worse compression. Values above 20 should be used with caution as they require more memory.
  • --zlib <level> β€” Supercompress the data with ZLIB. Cannot be used with ETC1S / BasisLZ format. Level range is [1,9]. Lower levels give faster but worse compression.
  • -h, --help β€” Print this usage message and exit.
  • -v, --version β€” Print the version number of this program and exit.

✨ Specific and Common Encoding Options ✨

The following are available. Specific options become valid only if their encoder has been selected. Common encoder options become valid when an encoder they apply to has been selected. Otherwise they are ignored.

🌈 ASTC 🌈

  • --astc-quality <level> β€” The quality level configures the quality-performance tradeoff for the compressor; more complete searches of the search space improve image quality at the expense of compression time. Default is 'medium'. The quality level can be set between fastest (0) and exhaustive (100) via the following fixed quality presets:
    • fastest β€” equivalent to quality = 0
    • fast β€” equivalent to quality = 10
    • medium β€” equivalent to quality = 60
    • thorough β€” equivalent to quality = 98
    • exhaustive β€” equivalent to quality = 100
  • --astc-perceptual β€” The codec should optimize for perceptual error, instead of direct RMS error. This aims to improve perceived image quality, but typically lowers the measured PSNR score. Perceptual methods are currently only available for normal maps and RGB color data.

πŸ¦‹ basis-lz πŸ¦‹

  • --clevel <level> β€” ETC1S / BasisLZ compression level, an encoding speed vs. quality tradeoff. Range is [0,6], default is 1. Higher values are slower but give higher quality. Use --qlevel first.
  • --qlevel <level> β€” ETC1S / BasisLZ quality level. Range is [1,255]. Lower gives better compression/lower quality/faster. Higher gives less compression/higher quality/slower. --qlevel automatically determines values for --max-endpoints, --max-selectors, --endpoint-rdo-threshold and --selector-rdo-threshold for the target quality level. Setting these options overrides the values determined by -qlevel which defaults to 128 if neither it nor --max-endpoints and --max-selectors have been set.
Note: Both of --max-endpoints and --max-selectors must be set for them to have any effect. If all three options are set, a warning will be issued that --qlevel will be ignored.
Note also: --qlevel will only determine values for --endpoint-rdo-threshold and --selector-rdo-threshold when its value exceeds 128, otherwise their defaults will be used.
  • --max-endpoints <arg> β€” Manually set the maximum number of color endpoint clusters. Range is [1,16128]. Default is 0, unset.
  • --endpoint-rdo-threshold <arg> β€” Set endpoint RDO quality threshold. The default is 1.25. Lower is higher quality but less quality per output bit (try [1.0,3.0]). This will override the value chosen by --qlevel.
  • --max-selectors <arg> β€” Manually set the maximum number of color selector clusters from [1,16128]. Default is 0, unset.
  • --selector-rdo-threshold <arg> β€” Set selector RDO quality threshold. The default is 1.25. Lower is higher quality but less quality per output bit (try [1.0,3.0]). This will override the value chosen by --qlevel.
  • --no-endpoint-rdo β€” Disable endpoint rate distortion optimizations. Slightly faster, less noisy output, but lower quality per output bit. Default is to do endpoint RDO.
  • --no-selector-rdo β€” Disable selector rate distortion optimizations. Slightly faster, less noisy output, but lower quality per output bit. Default is to do selector RDO.

🧚 uastc 🧚

  • --uastc-quality <level> β€” This optional parameter selects a speed vs quality tradeoff as shown here:
    • Level 0 β€” Fastest β€” 43.45dB
    • Level 1 β€” Faster β€” 46.49dB
    • Level 2 β€” Default β€” 47.47dB
    • Level 3 β€” Slower β€” 48.01dB
    • Level 4 β€” Very slow β€” 48.24dB

You are strongly encouraged to also specify --zstd to losslessly compress the UASTC data. This and any LZ-style compression can be made more effective by conditioning the UASTC texture data using the Rate Distortion Optimization (RDO) post-process stage. When uastc encoding is set the following options become available for controlling RDO:

  • --uastc-rdo β€” Enable UASTC RDO post-processing.
  • --uastc-rdo-l <lambda> β€” Set UASTC RDO quality scalar (lambda) to lambda. Lower values yield higher quality/larger LZ compressed files, higher values yield lower quality/smaller LZ compressed files. A good range to try is [.25,10]. For normal maps a good range is [.25,.75]. The full range is [.001,10.0]. Default is 1.0.
Note: Previous versions used the --uastc-rdo-q option which was removed because the RDO algorithm changed.
  • --uastc-rdo-d <dictsize> β€” Set UASTC RDO dictionary size in bytes. Default is 4096. Lower values=faster, but give less compression. Range is [64,65536].
  • --uastc-rdo-b <scale> β€” Set UASTC RDO max smooth block error scale. Range is [1.0,300.0]. Default is 10.0, 1.0 is disabled. Larger values suppress more artifacts (and allocate more bits) on smooth blocks.
  • --uastc-rdo-s <deviation> β€” Set UASTC RDO max smooth block standard deviation. Range is [.01,65536.0]. Default is 18.0. Larger values expand the range of blocks considered smooth.
  • --uastc-rdo-f β€” Do not favor simpler UASTC modes in RDO mode.
  • --uastc-rdo-m β€” Disable RDO multithreading (slightly higher compression, deterministic).

🌸 common 🌸

  • --normal-mode β€” Only valid for linear textures with two or more components. If the input texture has three or four linear components it is assumed to be a three component linear normal map storing unit length normals as (R=X, G=Y, B=Z). A fourth component will be ignored. The map will be converted to a two component X+Y normal map stored as (RGB=X, A=Y) prior to encoding. If unsure that your normals are unit length, use --normalize. If the input has 2 linear components it is assumed to be an X+Y map of unit normals.

The Z component can be recovered programmatically in shader code by using the equations:

nml.xy = texture(...).ga;              // Load in [0,1]
nml.xy = nml.xy * 2.0 - 1.0;           // Unpack to [-1,1]
nml.z = sqrt(1 - dot(nml.xy, nml.xy)); // Compute Z

For ETC1S / BasisLZ encoding, --encode basis-lz, RDO is disabled (no selector RDO, no endpoint RDO) to provide better quality.

  • --threads <count> β€” Explicitly set the number of threads to use during compression. By default, ETC1S / BasisLZ will use the number of threads reported by thread::hardware_concurrency or 1 if value returned is 0.
  • --no-sse β€” Forbid use of the SSE instruction set. Ignored if CPU does not support SSE. SSE can only be disabled for the basis-lz and uastc encoders. Ignored for other encoders.
  • --compare-ssim β€” Calculate encoding structural similarity index measure (SSIM) and print it to stdout. Requires Basis-LZ, UASTC or ASTC encoding.
  • --compare-psnr β€” Calculate encoding peak signal-to-noise ratio (PSNR) and print it to stdout. Requires Basis-LZ, UASTC or ASTC encoding.

πŸŒ€ TRANSFER FUNCTION HANDLING πŸŒ€

Okay bestie this is the part where it gets good. The diagram below shows literally every assignment and conversion that can take place, and yes we're gonna look at it together, don't scroll past it:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚          β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€1─────────────────►│         β”‚
β”‚          β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                      β”‚         β”‚
β”‚ Input    β”‚  β”‚           β”‚                      β”‚         β”‚
β”‚ Transfer β”‚  β”‚ --assign- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€2──────────►│Output   β”‚
β”‚ function β”‚  β”‚   tf      β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚Transfer β”‚
β”‚ from     β”‚  β”‚           β”œβ”€3─►│            β”‚    β”‚Function β”‚
β”‚ file     β”‚  β”‚           β”‚    β”‚ --convert- β”‚    β”‚         β”‚
β”‚ metadata β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚   tf       β”œ3,4β–Ίβ”‚         β”‚
β”‚          β”‚                   β”‚            β”‚    β”‚         β”‚
β”‚          β”œβ”€β”€β”€β”€β”€β”€β”€β”€4─────────►│            β”‚    β”‚         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ”€ Processing Paths

  1. Pass through. No options specified. (the chillest path, honestly)
  2. --assign-tf specified.
  3. --assign-tf and --convert-tf specified.
  4. --convert-tf specified.

πŸ” Details

Transfer function handling proceeds as follows, step by step, no skipping:

  • If --format specifies one of the *_SRGB{,_*} formats and Output Transfer Function is not sRGB (a.k.a scRGB) an error is generated. 🚨
  • If --format does not specify one of the *_SRGB{,_*} formats, an sRGB variant exists and Output Transfer Function is sRGB (a.k.a scRGB), an error is generated.
  • Otherwise, the transfer function of the output KTX file is set to Output Transfer Function.
  • If neither --assign-tf nor --convert-tf is specified:
    • If the Input Transfer Function is not sRGB (a.k.a scRGB) for *_SRGB{,_*} formats an implicit conversion to sRGB is done, equivalent to --convert-tf srgb.
    • If the Input Transfer Function is not linear for formats that are not one of the *_SRGB{,_*} formats, an implicit conversion to linear is done equivalent to --convert-tf linear.
  • Supported inputs for implicit or explicit conversion are linear, sRGB, ITU (a.k.a BT601, BT.709, BT.2020 and SMPTE170M) and PQ EOTF. An error is generated if an unsupported conversion is required. πŸ’€
  • Supported outputs for implicit or explicit conversion are linear and sRGB, An error is generated if an unsupported conversion is required.
  • Output Transfer Function for a format that is not one of the *_SRGB{,_*} formats can be set to a non-linear transfer function via --assign-tf.
  • A warning is generated if a visually lossy color-conversion is performed. sRGB to linear is considered visually lossy because there is a high chance it will introduce artifacts visible to the human eye such as banding. The warning can be suppressed with --no-warn-on-color-conversions. A warning or an error on any color conversion can be requested with --warn-on-color-conversions or --fail-on-color-conversions .

πŸ’‘ Note

When --format does not specify one of the SRGB{,} formats and Output Transfer Function is not linear:

  • the KTX file may be much less portable due to limited hardware support of such inputs.
  • avoid using --generate-mipmap as the filters can only decode sRGB.
  • avoid encoding to ASTC, BasisLz/ETC1S or UASTC. The encoders' quality metrics are designed for linear and sRGB.
🫢 genuinely bestie, take these three bullets seriously β€” this is the "trust me on this one" section.

πŸ†• Changes since last Release

  1. --assign-oetf and --convert-oetf are deprecated and will be removed. Use --assign-tf and --convert-tf instead. (not me calling the old flags ancient history 😭)
  2. The parameter value for --assign-tf can now be any of the transfer functions known to the Khronos Data Format Specification.
  3. A warning is now generated if a visually lossy color conversion will be performed. The warning can be suppressed with --no-warn-on-color-conversions.

🚦 EXIT STATUS 🚦

  • 0 - Success ✨
  • 1 - Command line error
  • 2 - IO failure
  • 3 - Invalid input file
  • 4 - Runtime or library error
  • 5 - Not supported state or operation
  • 6 - Requested feature is not yet implemented

πŸ“œ HISTORY πŸ“œ

Version 4.3

  • Initial version

Version 4.4

  • Reorganize encoding options.
  • Improve explanation of use of --format with --encode.
  • Improve explanation of ASTC encoding.

πŸ‘‘ AUTHOR πŸ‘‘

  • MΓ‘tyΓ‘s CsΓ‘szΓ‘r [Vader], RasterGrid www.rastergrid.com
  • Daniel RΓ‘kos, RasterGrid www.rastergrid.com
  • Mark Callow

And that's the whole page bestie, you ate that πŸŽ€ β€” this fine piece of documentation is Version 0.0.0, born Tue Jan 1 1980 00:00:00, and it lives its best life as ktx_create(1). Go forth and create some textures, ily πŸ’–πŸ¦‹

πŸ“¦ where this page comes from