taisei/doc/BASISU.rst
Andrei Alexeyev a5fd6fe5d9
Texturing overhaul: GPU compression, sRGB sampling, swizzles, etc. (#240)
* 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
2020-08-15 14:51:12 +03:00

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*