[SOLVED] Basis Compression iOS/Android issue

I’m having a problem with the VRAM usage of a compressed 4096x4096 image.

Basis reports that the VRAM will be 11.2MB, and it is on Desktop. However in iOS it is double that at 22.4MB. I use the launch profiler to read the VRAM usage.

If I select legacy compression and PVR then the launch profiler does report 11.2MB on iOS.

Is this an issue with Basis?
It seems I can select Basis and Legacy PVR at the same time. Will that cover all the bases?

Here is a simple project with only the Basis selected.

https://playcanvas.com/editor/scene/1161524

@slimbuck might know more.

Actually Android is also showing 22.4 MB

https://launch.playcanvas.com/1161524?profile=true&debug=true

Hi @Kulodo133,

I think I ran into this problem before. Try publishing a build and then checking your VRAM usage. I’m pretty sure it doesn’t quite work the same when using Launch from the editor.

@eproasim do you know how I can check the VRAM in a published build?

I checked pc.app.stats.vram in web inspector for a published build and still get 11 MB for Desktop and 22MB on iOS

https://playcanv.as/p/l3FfMMG9/

Hi @Kulodo133,

Could you run the following in the debugger on your device: pc.basisTargetFormat() ? What does that report?

Thanks!

@slimbuck on iOS ( 14.5.1) it reports “astc”

Thanks, yes I expected as much.

The engine has a priority order when choosing which compression format to use at runtime. You can see the priority here.

IOS devices now support both ASTC and PVR. Since ASTC in general is higher quality than PVR, the basis transcoder uses ASTC. The downside is that ASTC requires twice the VRAM compared to PVR.

I believe most developers consider download size as crucial, but would choose higher quality textures over VRAM savings. Is the VRAM cost prohibitive in your case?

Thanks!

1 Like

Yes in my case I need the VRAM saving. Could you make it so the choice is based on the editor inspector Basis settings? If not, can I patch it somehow?

We could definitely make this configurable. Please create an issue for this here.

Not sure when we will have time to make this nicely configurable, so in the meantime you could probably provide your own version of pc.basisTargetFormat. Please note that this approach is likely to break in future as we work on the engine. Also this code untested!

pc.basisTargetFormat = function () {
    if (device.extCompressedTexturePVRTC) {
        return 'pvr';
    } else if (device.extCompressedTextureASTC) {
        return 'astc';
    } else if (device.extCompressedTextureS3TC) {
        return 'dxt';
    } else if (device.extCompressedTextureETC) {
        return 'etc2';
    } else if (device.extCompressedTextureETC1) {
        return 'etc1';
    } else if (device.extCompressedTextureATC) {
        return 'atc';
    }
    return 'none';
}

(I just reordered the list and placed PVR first).

OK I’ll create an issue. Thanks for the patch example. Out of interest I note that if I select both Basis and Legacy options then the resulting asset folder will contain both basis and legacy files. Will the legacy files be used in preference to the basis file?

Yes correct. You can see the texture ‘variant’ priority order here.

Hi @slimbuck. I attempted to patch the function ( see link below ) but the engine doesn’t call it, the original is called. It is however called when I manually call it from the console. I’ve set the loading type to “after engine” so I think I patched it before it is used. Any ideas where I’m going wrong?

https://playcanvas.com/editor/scene/1161524

@Kulodo133, I gave a try your sample but I am having trouble as well patching that method. It seems that the issue isn’t the order the patch.js is executed.

Even if you set preload to false on both the texture and the material and initially disable the cube to avoid loading the basis texture, so the patch is definitely applied and can be confirmed in console, still it’s not respected.

I’ve tried patching both pc.basisTargetFormat and even pc.basisTranscode though the patched methods aren’t called by the engine when the cube is enabled and the transcode job is requested by the engine.

@yaustar any idea how to patch this?

1 Like

@slimbuck I created the issue https://github.com/playcanvas/engine/issues/3191

I can’t find a way to patch this as the basisTargetFormat is a global function in the engine and is scoped out in the build so there’s no way to change the function that is referenced internally.

I also tried to patch the BasisParser, but again, it’s not exposed in the pc namespace.

It looks like you may need to use your own fork of the engine if you need to override the Basis formats order

3 Likes

OK thanks for trying. As I’m hosting my site with PlayCanvas I’ll stick with legacy pvr compression, which is a shame as that pvr file is 11.2 MB and the basis file only 1.5MB. I’ll keep an eye on the engine issue I raised.

1 Like

I found a way to disable compression formats. https://playcanvas.com/editor/scene/1161524

function disableSomeBasisFormats(app) {
    
    // Called from the from the custom loading screen because at that point, the app has been created but no assets have been loaded yet.
    // Include logic here to disable desired formats based on the device type eg iOS, Android, Desktop etc.
    
    app.graphicsDevice.extCompressedTextureASTC = null;
    app.graphicsDevice.extCompressedTextureETC = null;
    app.graphicsDevice.extCompressedTextureETC1 = null;
   
    // on iOS this leaves PVR which uses less VRAM.
}
3 Likes

The issue was solved in engine release 1.44.1.

3 Likes