Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Building with different texture compression settings for WebGL

Discussion in 'Addressables' started by JolanHuyvaertDieKeure, Apr 20, 2022.

  1. JolanHuyvaertDieKeure

    JolanHuyvaertDieKeure

    Joined:
    Mar 1, 2021
    Posts:
    9
    Hello,

    For our current WebGL project we are making use of the new WebGLTextureSubtarget option in Unity 2021 when building from script so we can serve different content based on the texture compression formats supported by the browser. For example, DXT is supported on most desktop browsers and ASTC is supported on most mobile browsers.

    Now, some of our textures are Addressable. When building the addressables with the player, the textures in the built addressables still use the texture compression settings from the editor, while the non-addressable texture compression settings are properly overridden because of the WebGLTextureSubtarget. What would be a good way to also override the texture compression settings for addressable textures?

    Kind regards
     
  2. Unitiblis

    Unitiblis

    Joined:
    Aug 7, 2018
    Posts:
    13
    I am trying something similar. First I thought Profiles are the way to go. But they are pretty much bound to the Platform: Building one Profile will wipe a previous build coming from a different profile, when you build for the same platform (WebGL in my case).

    While searching for options I stumbled over one of the official Addressable examples
    This example comes with a custom Addressable Data Builder which auto-creates bundle-variants based on Texture scaling. This sounded pretty familiar to my issue so I gave it a try.

    Since I am developing a 2D game I only experimented with SpriteAtlas for now. Next step is Textures for Particle Effects. So far, it looks promising: As in the example, I have groups with custom schemas as a marker for my custom Data Builder. If my Data Builder detects said schema, it looks for texture compression variants which are configured in the schema. For every variant, it
    • clones the SpriteAtlas
    • overrides the WebGL platform/texture settings for this spriteatlas
    • adds it to a new group which is named after the variant (eg ingameSprites_astc)
    • labels every atlas in said group (eg ingameSprites_astc)

    Loading the addressables is a simple (using UniTask):
    Code (CSharp):
    1. await Addressables.LoadAssetsAsync<SpriteAtlas>(label, null);
    where label contains the prefix, eg 'ingameSprites' as well as the texture format as suffix, eg '_dxt'. Actually, I am thinking about passing a List of labels/keys there and use MergeMode.Intersect to avoid nasty string concatenations...

    This probably works so well because of the possibility of LateBinding for SpriteAtlases, which I also make use of.

    Anyhow, the runtime knows about the supported texture format by querying it from JavaScript in a similar way as it is described in Create builds for desktop and mobile browsers from a script
    Code (JavaScript):
    1. var c = document.createElement("canvas");
    2. var gl = c.getContext("webgl");                                
    3. var gl2 = c.getContext("webgl2");
    4.  
    5. if ((gl && gl.getExtension('WEBGL_compressed_texture_s3tc')) ||
    6.   (gl2 && gl2.getExtension('WEBGL_compressed_texture_s3tc'))) {      
    7.     window.textureCompressionFormat = 1;
    8. } else if((gl && gl.getExtension('WEBGL_compressed_texture_astc')) ||
    9.   (gl2 && gl2.getExtension('WEBGL_compressed_texture_astc'))) {
    10.     window.textureCompressionFormat = 4;
    11.     dataFile = "/WebGL_astc.data";                                
    12. } else if((gl && gl.getExtension('WEBGL_compressed_texture_etc')) ||
    13.   (gl2 && gl2.getExtension('WEBGL_compressed_texture_etc'))) {
    14.     window.textureCompressionFormat = 3;
    15.     dataFile = "/WebGL_etc.data";
    16. }
    window.textureCompressionFormat is accessed via jslib

    As mentioned, next step is getting Prefabs with ParticleEffects managed in a similar way. This will probably look even more like the Addressable Variants example mentioned in the beginning. But loading / referencing them might be more tricky, because there is no LateBinding.

    My current idea is to store an AssetReference to the Prefab in a ScriptableObject. When building the AddressableBundle, a custom build script will prefill said ScriptableObject with the actual asset path of the prefab (asset path is same as addressable path in my setup) before bundles get processed. This will allow me to load the Asset via addressable path (aka key) and additional label (dxt, etc2, astc). Let's see where this is going....
     
    Last edited: Sep 7, 2022