Files
2025-11-30 08:35:03 +02:00

4.0 KiB

How To

The API provides the loading classes KtxTexture for KTX™ 2.0 files and BasisUniversalTexture for Basis Universal files, which both offer the following async loading methods:

  • LoadFromUrl for loading URLs (including file URLs starting with file://)
  • LoadFromStreamingAssets for loading relative paths in the StreamingAssets folder
  • LoadFromBytes for loading from memory

Loading Textures

using KtxUnity;

async void Start() {

    // Create KTX texture instance
    var texture = new KtxTexture();

    // Linear color sampling. Needed for non-color value textures (e.g. normal maps)
    bool linearColor = true;

    // Load file from Streaming Assets folder (relative path)
    var result = await texture.LoadFromStreamingAssets("trout.ktx", linearColor);

    // Alternative: Load from URL
    // var result = await texture.LoadFromUrl("https://myserver.com/trout.ktx", linearColor);

    // Alternative: Load from memory
    // var result = await texture.LoadFromBytes(nativeArray, linearColor);

    if (result != null) {
        // Use texture. For example, apply texture to a material
        targetMaterial.mainTexture = result.texture;

        // Optional: Support arbitrary texture orientation by flipping the texture if necessary
        var scale = targetMaterial.mainTextureScale;
        scale.x = result.orientation.IsXFlipped() ? -1 : 1;
        scale.y = result.orientation.IsYFlipped() ? -1 : 1;
        targetMaterial.mainTextureScale = scale;
    }
}

Using as Sprite

If you want to use the texture in a UI / Sprite context, this is how you create a Sprite with correct orientation:

using KtxUnity;

async void Start() {

    // Create a basis universal texture instance
    var texture = new BasisUniversalTexture();

    // Load file from Streaming Assets folder
    var result = await texture.LoadFromStreamingAssets("dachstein.basis");

    if (result != null) {
        // Calculate correct size
        var pos = new Vector2(0,0);
        var size = new Vector2(result.texture.width, result.texture.height);

        // Flip Sprite, if required
        if(result.orientation.IsXFlipped()) {
            pos.x = size.x;
            size.x *= -1;
        }

        if(result.orientation.IsYFlipped()) {
            pos.y = size.y;
            size.y *= -1;
        }

        // Create a Sprite and assign it to the Image
        GetComponent<Image>().sprite = Sprite.Create(result.texture, new Rect(pos, size), Vector2.zero);

        // Preserve aspect ratio:
        // Flipping the sprite by making the size x or y negative (above) breaks Image's `Preserve Aspect` feature
        // You can/have to calculate the RectTransform size yourself. Example:

        // Calculate correct size and assign it to the RectTransform
        const float scale = 0.5f; // Set this to whatever size you need it - best make it a serialized class field
        var rt = GetComponent<RectTransform>();
        rt.sizeDelta = new Vector2(result.texture.width*scale, result.texture.height*scale);
    }
}

Note: You can still use the Preserve Aspect Image option, if you encode your KTX/Basis files with flipped Y axis (see Creating Textures )

Advanced

Developers who want to create advanced loading code should look into classes KtxTexture/BasisUniversalTexture and TextureBase directly.

When loading many textures at once, using the low-level API to get finer control over the loading process can yield great performance gains. Have a look at TextureBase.Load for starting and details.

Trademarks

Unity is a registered trademark of Unity Technologies.

Khronos® and the Khronos Group logo are registered trademarks of the The Khronos Group Inc.

KTX™ and the KTX logo are trademarks of the The Khronos Group Inc.