Loading of compressed textures based on device


#1

Hi all,

Up until now I have been using uncompressed textures, but looking at the documentation it seems like using compressed textures will really help with vRAM efficiency. The issue is that while the in-editor compressed files work great, there is no documentation on how to load correct textures via my own JS. I can load a pvr or dxt file individually, but I can’t find any documentation on how the system Asset class loads AssetVariants class with the correct data via the constructor (or any other interface for that matter).

I am currently loading our uncompressed textures as such:

var asset_handle = new pc.Asset("asset_"+resource_name, "texture", { url: "https://s3.us-east-2.amazonaws.com/"+resource_uri});

How would I go about changing this call to specify the variations? I thought of using device.extCompressedTextureS3TC / device.extCompressedTextureETC / etc etc… but that seems messy considering you guys already have that detection logic working. Anything I’m missing?

Thanks!


#2

Bumping this one last time.

I looks like using device.extCompressedTextureS3TC would work, but just seems messy. Would love to hear of a better solution.


#3

It’s tricky as the engine works on a fallback system based on what textures have compressed versions and the platform hardware support.

It’s ultimately one asset for all variants of the same image (e.g JPEG, DDS, PVR etc).

I’m not 100% sure how it is loaded in the asset registry without exporting a project and going through the calls on load.

The areas I would look at in the engine are:




#4

Thanks for the help. I looked through the codebase and it seems like they never made a generic way to let people load fallback variants through pc.Asset. Fortunately, it’s not too difficult to do on your own! Here is my method in case someone wants to do the same thing.

First, I put in a GPU capabilities check in the loader. I do that within my loading screen-

pc.script.createLoadingScreen(function (app) {}

On my server, my images are all stored as

https://<CDN URI>/<RESOURCE ID>-<EXTENSION PART>

So for example, my different formats for an image foobar.jpg would be

JPG: https://foobar.com/foobar.jpg
DXT: https://foobar.com/foobar-dxt.dds
ETC1: https://foobar.com/foobar-etc1.ktx
ETC2: https://foobar.com/foobar-etc2.ktx
PVR: https://foobar.com/foobar-pvr.ktx

In the loading script I store the extension in a variable based on the capabilities.

    app.ename = ".jpg";
    
    if(app.graphicsDevice.extCompressedTexturePVRTC) {
        app.ename = "-pvr.ktx";
    } else if(app.graphicsDevice.extCompressedTextureS3TC) {
        app.ename = "-dxt.dds";
    }
    else if(app.graphicsDevice.extCompressedTextureETC) {
        app.ename = "-etc2.ktx";
    }
    else if(app.graphicsDevice.extCompressedTextureETC1) {
        app.ename = "-etc1.ktx";
    } else {
        // nada
    }

Then when I’m loading my assets, I do something like this-

var index = ...
var foobar = ...

var ename = ".jpg";
            
if(this.app.ename) {
    ename = this.app.ename;
}

var _asset_handle = new pc.Asset("asset_"+index, "texture", { url: "https://foobar.com/"+foobar[index].uri+ename });

Works well for me. Hope it helps somebody else! (And it would be nice if something like this were added to PC itself to abstract this away)