* WIP compressed textures, swizzles, sRGB sampling, ... * refactor texture type info & fix random bugs * fix preprocessing of sRGB textures * handle y-flipped basis textures * glcommon: better WebGL compat for compressed format detection * missed WEBGL_compressed_texture_pvrtc * implement compressed texture xcoding and uploading * Add basis_universal submodule * Reorganize texture loader code Clean up some code Isolate Basis Universal loader into a separate module * Add wrapper script for encoding .basis textures * basisu: honor custom metadata written by the mkbasis.py script * mkbasis.py: add --incredibly-slow and --dry-run * Move pixmap code from util/ to pixmap/ * Add an on-disk transcode cache for basis textures to speed up loads * Compress texture cache with zlib * Use readable format names for basisu cache filenames * basisu: mip bias test code * basisu: small caching cleanup * add TAISEI_BASISU_MIP_BIAS env variable * Improve OpenGL format matching heuristics * Document considerations for compressed format priority * Remove dead code * Enable two forgotten formats, BC3_RGBA and ATC_RGBA Also prefer BC7 over BC1/BC3 * Recognize GL_ANGLE_compressed_texture_etc for ETC2 textures * Default depth buffers to 24-bit; remove ANGLE hack * Fix glcommon_check_extension for GLES2/legacy gl * Add renderer feature bit for texture swizzle masks * glcommon: Fixup internal formats for GLES2 Sized internal formats are not allowed in GLES2 * Fix emscripten compile errors * Update basis_universal * remove more dead code * revert irrelevant stage4 change * shut up UBSan * basisu: shut up some debug spam * Add normalmap sampling helper to util.glslh * basisu: add a gray-alpha mode * mkbasis.py: Abort if image dimansions aren't multiples of 4 * Add basic Basis Universal encoding documentation (WIP) * doc/basisu: Add paragraph about modes; minor tweaks * basisu: workarounds for GL texture size requirements * gles20: fix uncompressed sRGB formats * Partial workaround for missing swizzles in gles2 and webgl * remove invalid assertion * New renderer API to expose glDrawBuffers-like functionality * stagedraw: disable all color outputs for copy_depth pass required for WebGL compatibility * support GL_ANGLE_request_extension * emscripten: include *.basis in gfx package Also fix a potential problem when more than one .pkgdir is used to construct emscripten packages * Don't rely on emscripten runtime to enable webgl extensions
142 lines
4.2 KiB
ReStructuredText
142 lines
4.2 KiB
ReStructuredText
|
|
Basis Universal
|
|
===============
|
|
|
|
.. contents::
|
|
|
|
Intro
|
|
-----
|
|
|
|
`Basis Universal <https://github.com/taisei-project/basis_universal>`__ is a GPU texture compression system with ability
|
|
to transcode images into a wide variety of formats at runtime from a single source. This document explains how to author
|
|
Basis Universal (``.basis``) textures for Taisei, and highlights limitations and caveats of our Basis support.
|
|
|
|
First-time setup
|
|
----------------
|
|
|
|
Step 1: The encoder
|
|
~~~~~~~~~~~~~~~~~~~
|
|
|
|
Compile the encoder and put it somewhere in your ``PATH``. Assuming you have a working and up to date clone of the
|
|
Taisei repository, including submodules, this can be done like so on Linux:
|
|
|
|
.. code:: sh
|
|
|
|
cd subprojects/basis_universal
|
|
meson setup --buildtype=release -Db_lto=true -Dcpp_args=-march=native build
|
|
meson compile -C build basisu
|
|
ln -s $PWD/build/basisu ~/.local/bin
|
|
|
|
Verify that the encoder is working by running ``basisu``. It should print a long list of options. If the command is not
|
|
found, make sure ``~/.local/bin`` is in your ``PATH``, or choose another directory that is.
|
|
|
|
The optimization options in ``meson setup`` are optional but highly recommended, as the encoding process can be quite
|
|
slow.
|
|
|
|
It's also possible to use `the upstream encoder <https://github.com/BinomialLLC/basis_universal>`__, which may be
|
|
packaged by your distribution. However, this is not recommended. As of 2020-08-06, the upstream encoder is missing some
|
|
important performance optimizations; see
|
|
`BinomialLLC/basis_universal#105 <https://github.com/BinomialLLC/basis_universal/pull/105>`__
|
|
`BinomialLLC/basis_universal#112 <https://github.com/BinomialLLC/basis_universal/pull/112>`__
|
|
`BinomialLLC/basis_universal#113 <https://github.com/BinomialLLC/basis_universal/pull/113>`__.
|
|
|
|
Step 2: The wrapper
|
|
~~~~~~~~~~~~~~~~~~~
|
|
|
|
The ``mkbasis`` wrapper script is what you'll actually use to create ``.basis`` files. Simply symlink it into your
|
|
``PATH``:
|
|
|
|
.. code:: sh
|
|
|
|
ln -s $PWD/scripts/mkbasis.py ~/.local/bin/mkbasis
|
|
|
|
Verify that it works by running ``mkbasis``.
|
|
|
|
Encoding TL;DR
|
|
--------------
|
|
|
|
Encode a **diffuse or ambient map** (sRGB data, decoded to linear when sampled in a shader):
|
|
|
|
.. code:: sh
|
|
|
|
# Outputs to foo.basis
|
|
mkbasis foo.png
|
|
|
|
# Outputs to /path/to/bar.basis
|
|
mkbasis foo.png -o /path/to/bar.basis
|
|
|
|
Encode a **tangent-space normal map** (special case):
|
|
|
|
.. code:: sh
|
|
|
|
mkbasis foo.png --normal
|
|
|
|
Encode a **roughness map** (single-channel linear data):
|
|
|
|
.. code:: sh
|
|
|
|
mkbasis foo.png --channels=r --linear
|
|
# Equivalent to:
|
|
mkbasis foo.png --r --linear
|
|
|
|
Encode **RGBA** color data and **pre-multiply alpha**:
|
|
|
|
.. code:: sh
|
|
|
|
mkbasis foo.png --channels=rgba
|
|
# Equivalent to:
|
|
mkbasis foo.png --rgba
|
|
|
|
Encode **Gray+Alpha** data and **pre-multiply alpha**:
|
|
|
|
.. code:: sh
|
|
|
|
mkbasis foo.png --channels=gray-alpha
|
|
# Equivalent to:
|
|
mkbasis foo.png --gray-alpha
|
|
|
|
Do **not** pre-multiply alpha:
|
|
|
|
.. code:: sh
|
|
|
|
mkbasis foo.png --no-multiply-alpha
|
|
|
|
Sacrifice quality to speed up the encoding process:
|
|
|
|
.. code:: sh
|
|
|
|
mkbasis foo.png --fast
|
|
|
|
For a complete list of options and their default values, see
|
|
|
|
.. code:: sh
|
|
|
|
mkbasis --help
|
|
|
|
Encoding details
|
|
----------------
|
|
|
|
Encoding modes
|
|
~~~~~~~~~~~~~~
|
|
|
|
Basis Universal supports two very different encoding modes: ETC1S and UASTC. The primary difference between the two is
|
|
the size/quality trade-off.
|
|
|
|
ETC1S is the default mode. It offers medium/low quality and excellent compression.
|
|
|
|
UASTC has significantly higher quality, but much larger file sizes. UASTC-encoded Basis files must also be additionally
|
|
compressed with an LZ-based scheme, such as deflate (zlib). Zopfli-compressed UASTC files are roughly 4 times as large
|
|
as their ETC1S equivalents (including mipmaps), comparable to the source file stored with lossless PNG or WebP
|
|
compression.
|
|
|
|
Although UASTC should theoretically work, it has not been well tested with Taisei yet. The ``mkbasis`` wrapper also does
|
|
not apply LZ compression to UASTC files automatically yet, and Taisei wouldn't pick them up either (unless they are
|
|
stored compressed inside of a ``.zip`` package). If you want to use UASTC nonetheless, pass ``--uastc`` to ``mkbasis``.
|
|
|
|
*TODO*
|
|
|
|
|
|
Caveats and limitations
|
|
-----------------------
|
|
|
|
*TODO*
|