Jump to content

Passing textures to CubeTexture


royibernthal
 Share

Recommended Posts

I'm loading textures via AssetsManager and saving references to them before the scene is rendered.

When creating a CubeTexture I'd like to pass it references to the already loaded textures (via the constructor or any other way), instead of urls of the textures,

If I pass to CubeTexture urls of the textures then they are being loaded all over again before being displayed, which I'd like to avoid.

For instance instead of this constructor:

constructor(rootUrl: string, scene: Scene, extensions?: string[], noMipmap?: boolean, files?: string[]);

It'd be nice to have something like this:

constructor(textures: BABYLON.Texture[], scene: Scene, noMipmap?: boolean);

Does such a thing exist in one way or another or is it a feature request?

 

Are the textures supposed to be loaded all over again when their urls are passed to CubeTexture after the textures have already been loaded via AssetManager from the same urls? Is it a bug? Am I doing something wrong?

Link to comment
Share on other sites

Yeah I imagine this is how it's intended to work, however in practice I experience a small interval before textures are shown if I pass the urls, vs shown immediately if I pass references to textures loaded via AssetManager.

I experienced it for instance when using Sprite2D, since I need to pass a texture instance to the constructor I have the freedom to choose between passing a reference to a texture and creating a new texture instance from a url.

In CubeTexture I can't really do a comparison but it seems to be the interval I experienced when creating a new texture instance from a url.

 

I can try to reproduce the issue with Sprite2D, but I'd need to load multiple images for the interval to be noticeable. Do you know of image storage service that supports cross origin requests?

Github, imageshack and postimage seem to be blocking them, unless there's something I need to do on the playground side as well to make them work.

Link to comment
Share on other sites

  • 2 weeks later...

@Deltakosh

I found myself giving up on isolating the issue and proving textures are loaded twice, until today when I tried creating my own custom loading screen, and I finally found solid proof completely by chance :)

Since it's pretty much a waste of time to find a hosting service that supports cross-origin requests, I simply zipped my files for you:

https://www.dropbox.com/s/fqecy3ovbujjpn5/Babylon Loading Texture Test.zip?dl=1

 

You can see in this test that I'm loading all 6 images related to the skybox using AssetsManager, during that load the loading screen is displayed.

When it finishes loading I'm creating a CubeTexture and providing it the exact same images urls, and it looks like they are loaded all over again according to scene.getWaitingItemsCount().

 

You should see in your log something like this:

 

displayLoadingUI

5
2
1
hideLoadingUI
6
0

 

The numbers are returned by scene.getWaitingItemsCount().

displayLoadingUI and hideLoadingUI are self explanatory I believe.

 

Is it a bug or am I missing something?

 

The reason it bothers me is because there's quite a large interval between the time when the assets finish loading in my project and the time the skybox is displayed. (in my original project not in this isolated test)

Once the assets finish loading, I initialize everything and I immediately see all assets and meshes, except for the skybox which always takes a few extra seconds to show.

Link to comment
Share on other sites

It sounds as though you are loading the textures twice - if you are declaring the paths and/or URLs again when defining your cube texture. Why not use only the Assets Manager to load the textures into an array, and then call them from the array using their name attribure? Otherwise, it appears you're loading textures using the AssetsManager and simply caching them for no reason but to fill valuable memory. It's fine to declare your textures when creating the cube material, but I prefer Using the AssetsManager - and disposig of textures once they are of no further use.

The following code is a simple example from a post I wrote yesterday asking somewhat similar questions. There's allot more info than you need below, but this is how I use the AsstetsManager to load all my textures for my GUI, and then assign these to my buttons in the bGUI extension (see below). However, once loaded into an array, it doesn't matter what function you use to apply the textures; but avoids calling assets twice in your scene which not only has no benefit, but will increase your Major GC (garbge collection) causing increasingly poor performance on many devices. Also, dispose of any textures or assets once you are certain you no longer need them - or if you won't be using them again in your scene for some period of time; example: as in waiting to load a seperate level using the same texture(s). Simple memory management, however Major GC is a serious issue in many browsers, and often can dramatically slow your FPS while hidden as Major GC. 

The following code example uses only the AssetsManager to load an array and each asset's attributes (name and path in this case), and then calls the assets by name from the array later in the script. This is only a snippet to show how you might use the AssetsManager in your script, so there is much missing - but I hope you can see this yourself as soon as you read the example below:

window.addEventListener("DOMContentLoaded", function() {
    var canvas          = document.getElementById("game");
    var engine          = new BABYLON.Engine(canvas, true);
    var scene           = new BABYLON.Scene(engine);
    var camera          = null;
   
    var assets = []; 

    var loader = new BABYLON.AssetsManager(scene);


//Example to load textures and assets to call in scene
    var myLoad = [
        {name : "assetName1", src : "./filename1" },

        {name : "assetName2", src : "./filename2" },

    ];

    myLoad.forEach(function(obj) {
        var img = loader.addTextureTask(obj.name, obj.src);
        img.onSuccess = function(t) {
            assets[t.name] = t.texture;
        };
    });

    loader.onFinish = function() {

//if (logon_success == 1) {

        init3d(scene, canvas);
        scene.activeCamera.layerMask    = 1;
        setTimeout(function() {

        }

   }

},5)
 

And to use the objects loaded into the assets[] array, (below is an example specific to call textures from the array for the bGUI extension) and without declaring the asset and path redundantly, so the usage (only for creating a new bGUI button) is as follows:

var button_rev = new bGUI.GUIPanel("button_rev", assets["button_rev"], null, gui);

 

And if you need to follow in more detail, the function to initiate the scene and canvas is as follows:

function init3d (scene, canvas) {  

};

 

As mentioned, this is currently posted in a seperate topic, but the code example is the same - except I left out the line of code to lock the pointer (used primarily for IPad) to avoid scrolling ithin some browsers - in case anyone is wondering why I removed the first line from the post on "Custom Preloader Progress..."

DB

Link to comment
Share on other sites

If you'll read the previous posts you'll see that saving references to the textures is what I was initially doing, @Deltakosh said it's not necessary as bjs already manages its own cache. I might've misunderstood him though.

Regardless, even if I do save references to the textures, passing them to CubeTexture is not possible, I'm forced to pass urls to the constructor, which is basically the reason why I opened this thread. Correct me if I'm wrong or if I'm missing anything.

Link to comment
Share on other sites

In many constructors you can, but not in CubeTexture:

http://doc.babylonjs.com/classes/2.4/CubeTexture

unless there's some helper function I'm not aware of which can create a CubeTexture from a bunch of textures references.

 

EDIT: This helper function is possibly CubeTexture.createFromImages(), it's the first time I noticed it, I'll take a closer look at it tomorrow.

I'd still appreciate hearing from Deltakosh why the textures are loaded again when I pass urls if bjs takes care of managing the cache, even if this static function can take references to textures and solve my problem.

Link to comment
Share on other sites

14 minutes ago, Deltakosh said:

It looks related but for some reason my problem persists. Would you be able to take a closer look at this isolated project I made for you?

https://www.dropbox.com/s/fqecy3ovbujjpn5/Babylon Loading Texture Test.zip?dl=1

Link to comment
Share on other sites

Ok I know why it is not working :)

To create cube texture I need raw data from a img object and this data is not cached.

 

In your case here is what I suggest:

- Create a temp cube texture during loading time

- Wait for tempTexture.isReady to be true

- This texture will be cached and will allow subsequent identical cube textures to be load instantaneously 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...