Jump to content

Time between texture load and rendering


Recommended Posts

Hello,
 
I have a Digital Elevation Model (DEM) formed by several grounds (tiles).
 
For each tile I want to move from wireframe to texture instantly so I wrote this (it works but the transition is not direct)
 
material.diffuseTexture = tex;
material.wireframe = false;
 
I saw it was not so easy, then I copy the createTexture function of engine in my Utils and put my "material.wireframe = false;" in the onload of image, like that:
 


RANDO.Utils.createTexture = function (engine, material, url, scene, noMipmap, invertY) {
    var texture = engine._gl.createTexture();
    var img = new Image();
    scene._addPendingData(texture);
    texture.url = url;
    texture.noMipmap = noMipmap;
    texture.references = 1;
    engine._loadedTexturesCache.push(texture);
    
    
    img.crossOrigin = 'anonymous';
    img.onload = function() {
        prepareWebGLTexture(material, texture, scene, img.width, img.height, invertY, noMipmap, function (potWidth, potHeight) {
            var isPot = (img.width == potWidth && img.height == potHeight);
            if (!isPot) {
                engine._workingCanvas.width = potWidth;
                engine._workingCanvas.height = potHeight;

                engine._workingContext.drawImage(img, 0, 0, img.width, img.height, 0, 0, potWidth, potHeight);
                
                material.wireframe = false;
            }

            engine._gl.texImage2D(
                engine._gl.TEXTURE_2D,
                0,
                engine._gl.RGBA,
                engine._gl.RGBA,
                engine._gl.UNSIGNED_BYTE,
                isPot ? img : engine._workingCanvas
            );
            
        });
       
    }
    
    img.onerror = function() {
        scene._removePendingData(texture);
    };
    
    img.src = url;
    
    return texture;
};

 

 

 

There is again a time between wireframe disabling and texture display.

 

So the time do not come from the loading of Image object but from the display of Image object ?

 

I don't know how to do this immediate shift. If somebody have an answer...

 

Thank you

Link to comment
Share on other sites

The time you have noticed is due to compilation time of the shader. As soon as you add a texture the shader must be recompiled to take this information in account. The best idea here should be to have a white texture always attached to your object even when in wireframe mode so that the switch to real texture won't trigger a compilation

Link to comment
Share on other sites

I'm not really sure to understand :

  • I apply the material with a white texture, and wireframe true
  • Once the scene is ready :
  • I use the createTexture function of engine to load my final texture.
  • I set the property "_texture" of my material.diffuseTexture with the texture just created.
  • Set wireframe to false

I 've done this but the switch is not direct.

 

Here is the demo so you'll see the result : https://kostar111.github.io/rando3D/

Link to comment
Share on other sites

Ok I created textures, I do some others things (drape the trek etc) which take time and let textures be loaded.

After that, I give these textures to the tile and it works with my computer.

 

It's a trick but I think I could do better if I can know exactly when the textures are loaded. Maybe this is a low level problem but if you have an element of answer about that...

 

Anyway, thank you for your time and for babylonjs it's very simple of use =)

Link to comment
Share on other sites

Ok I fixed the problem and here is my solution

// Load tile's textures over the DEMfunction texture () {    var count = finalTextures.length;    var checked = [];    for (var it in finalTextures){        checked.push(false);    }        loop();    function loop (){        var it = 0;        var chunk = 50;        apply();        function apply () {            var cnt = chunk;            while (cnt-- && it < finalTextures.length) {                if (!checked[it] && finalTextures[it].isReady) {                    checked[it] = true;                    var property = tilesKeys[it];                                        // Set the texture when it's loaded                    var material = scene.getMeshByName("Tile - " + property).material;                    material.diffuseTexture._texture = finalTextures[it];                    material.wireframe = false;                    count--;                }                it++;            }            if (it < finalTextures.length) {                setTimeout (apply, 1);            }else if (count > 0) {                setTimeout (loop, 1);            }        };    }    console.log("Textures applied !" + (Date.now() - RANDO.START_TIME) );};

Basically I relaunch the loop() function while textures are not all ready.

It is not simple because the loop is very big for certain datasets. This is why I have an apply() function which divide it by chunk of 50 textures.

 

Thank you ! Result is exactly what I expected !

https://kostar111.github.io/rando3D/demo/v1/

 

Link to comment
Share on other sites

  • 2 weeks later...

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...