Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question WebGL memory

Discussion in 'Web' started by See_Sharp, Nov 30, 2020.

  1. See_Sharp

    See_Sharp

    Joined:
    Mar 3, 2016
    Posts:
    73
    I'm trying to load custom 3D models into the unity WebGL player. My first approach was to generate assetbundles and load those from my server. This works great when using very small models but just doesn't work with larger files:

    Desktop:
    - Assetbundle 30MB = Is this even loaded from the server? Woa so fast
    - Assetbundle 70MB = works flawlessly
    - Assetbundle 140MB = Crashes

    iPhone 11:
    - Assetbunde 30MB = reloads the page a few times (????) throws a few out of memory exceptions but after a few reloads it eventually comes through
    - Assetbundle 70MB = crashed
    - Assetbundle > 100MB = crashes

    I tried an older android phone, and being the careful man I am, feeding it a 13MB assetbundle. That thing didn't even know what happened and flipped from even starting to download this assetbundle.

    So, I googled the infamous "out of memory" exception and the only solution I came up with is "Increase player memory size". So I increased the webplayer memory to 512MB and later to 1024MB. No succcess.

    How does it happen that a project configured with 1024MB, an empty scene, crashed when loading an Assetbundle bigger than 140MB? My PC has 16GB of RAM, I'm sure it can spare 140MB...

    EDIT: I changed the webplayer memory size through an editorscript. I'm using unity version 2020.1.13f1

    Anyone suggestions?
     
  2. AgnosiaGames

    AgnosiaGames

    Joined:
    May 26, 2020
    Posts:
    57
  3. See_Sharp

    See_Sharp

    Joined:
    Mar 3, 2016
    Posts:
    73
    I cleaned up my previous answer as I was in a rush to deliver this to my client. I wrote another workaround that handles downloading and unzipping of the files completely outside the player, resulting in less ping ponging between unity and native js:

    Code (CSharp):
    1. window.fetchProjectLod = (projectId, orderOfLoading, nextLodLevelNam, persistedDataPath, FS, onDone) => {
    2.     fetch(`api/file/lod/${projectId}/${orderOfLoading}`).then(response => response.arrayBuffer()).then(arrayBuffer => {
    3.         var zip = new JSZip();
    4.         const dir = persistedDataPath + "/" + projectId.toString() + "/" + nextLodLevelNam;
    5.         FS.rmdir(dir, { recursive: true });
    6.         FS.mkdir(dir);
    7.         zip.loadAsync(arrayBuffer).then(entry => {
    8.             let keys = Object.keys(entry.files);
    9.             let index = 0;
    10.             keys.forEach(k => {
    11.                 index++;
    12.                 let file = entry.file(k);
    13.                 if (file != null) {
    14.                     file.async("uint8array").then(content => {
    15.                         FS.writeFile(dir + "/" + k, content);
    16.                         if (index >= keys.length) {
    17.                             FS.syncfs(false,
    18.                                 (err) => {
    19.                                     onDone();
    20.                                 });
    21.                         }
    22.                     });
    23.                 }
    24.                 else if (file.dir) {
    25.                     FS.mkdir(k);
    26.                 }
    27.             });
    28.         });
    29.     });
    30. };
    this function is called from my jslib file:

    Code (CSharp):
    1.        
    2. var FetchProjectLodPlugin = {
    3.     DownloadLodWebGL: function(projectId, levelOfLoading, persistedDataPath, nextLodLevelName) {
    4.         var pointerNextLodLevelName = Pointer_stringify(nextLodLevelName);
    5.         var pointerPersistedDataPath = Pointer_stringify(persistedDataPath);
    6.  
    7.  
    8.         window.fetchProjectLod(projectId, levelOfLoading, pointerNextLodLevelName, pointerPersistedDataPath, FS, function() {
    9.             FS.syncfs(false, function (err) {
    10.                 console.log('Downloaded and unzipped files.');
    11.                 SendMessage('GameContainer', 'OnWebGLLODSaved', levelOfLoading);
    12.             });
    13.         });
    14.     }
    15. };
    16.  
    17. mergeInto(LibraryManager.library, FetchProjectLodPlugin);
    18.  
    19.  
    Still using the JSZip library, I simplified the whole indexdb stuff by using the FS from emscripten directly. Now I can flawlessly download big zip files without having the worry about unity's memory.
     
  4. doctorpangloss

    doctorpangloss

    Joined:
    Feb 20, 2013
    Posts:
    269
    Use lower polygon count models. You can reduce on demand. Mobile WebGL and indeed all browser-based 3D solutions are fundamentally ill-suited for rendering high polygon count CAD, creative and architectural models.