Trigger event after scence changed and everything like assets and materials completly loaded on canvas

Hello Team,
I’m working on a task for 4-5 days but can’t find the solution.
I have to save multiple screenshots in a loop every time with a different albedo texture applied to it.
I have implemented this functionality,
I’m achieving the same as when every user changes the texture it gets applied to mesh and downloaded automatically.
But the problem is when I run this functionality in the loop
like I give multiple textures in array form and loop through them and load mesh with each texture but I don’t recreate the engine, camera, and scene every time when texture updates, I just update the already created scene assets.
so the code for updating texture executes very fast because of this my code for taking screenshots runs before all asset changes apply on canvas, because of this I end up with a blank canvas image downloaded only.

I’m asking that is there any way by which we can pause the further execution till loading everything on Canvas gets complete and then iterate the loop ?

Your response will be beneficial to me
I really appreciate any help you can provide.

I wasn’t sure if you recreate the texture or just set another texture to mesh’s material, so I put in a boolean to switch between both ways. Either way you can use addOnce on onLoadObservable of texture or the static function WhenAllReady() of BaseTexture:

3 Likes

Thank you so much, I’ll try and let you know.

Depending on what you are doing, you might also be able to use scene.whenReadyAsync or scene.executeWhenReady functions.

1 Like

Hello sir,
scene.executeWhenReady function worked this helped me to get a filled canvas image, earlier I was getting blank images because the CreateScreenshotUsingRenderTarget function was hitting meanwhile the scene was taking time to load.
But my problem is not resolved yet

I’m explaining my code steps

  1. user selects the textures he/she wants to apply to the mesh
    and clicks on the button & expects to get a number of screenshots with all textures applied on the mesh one by one.
    For example, if the user selects 3 textures he expects 3 downloads with each texture.

to do so, I created an engine, arch rotate camera, lights, and scene, and rendered it.
first time I create all and on the next iteration of the loop I check if the engine is already created I update the texture to the pbrmaterial by using
following
mymaterial.albedoTexture = new BABYLON.Texture(newfabric, this.scene);

after this, I wrote the code to take a screenshot

 material.albedoTexture.onLoadObservable.addOnce(this.CreateScreenshotfun('filename);

this don’t work immediately or don’t stop iteration of loop till it download the screenshot with just applied texture.

CreateScreenshotfun function(){  
scene.executeWhenReady(()=>{
      BABYLON.Tools.CreateScreenshotUsingRenderTarget(
            this.engine, this.camera, {
                width: width,
                height: heigth,
                precision: percision
            },data => this.downloadImage(data, filename), "image/png",
            sharpness
        );  
        });
}

downloadImage function

      
        if ("download" in document.createElement("a")) {
            var a = window.document.createElement("a");
            a.href = data;
            a.setAttribute("download", filename);
            a.click();
        } else {
            var newWindow = window.open("");
            newWindow.document.title = filename;
            var img = newWindow.document.createElement("img");
            img.src = data;
            img.alt = filename;
            newWindow.document.body.appendChild(img);
        }
    }

this also is not working it is not giving a pause on the fabrics loop while one screenshot gets downloaded, each loop over user-selected fabrics keeps going on without waiting for the download functionality to complete.

the expectation is while the loop runs it applies the first fabric then downloads the screenshot and then applies the next fabric and downloads screenshots again and this chain will go until the selected fabrics are done with the loop.
Any help will be appreciated
thanks

If you can put this code in playground or codepen, that will make it much easier to help.

1 Like

Here I have created playground, I hope this would help you to understand the issue easily.

Uncomment the line number 170
//takescreenshot();
to check the output.

Thanks

Is this what you want?

PG: https://playground.babylonjs.com/#Z1VL3V#554

1 Like

Yes, exactly I want this, Thank you so much for helping me.
But one issue is still there,
that is when we give the large size images, the scene downloads the screenshot even before it gets applied.
in above PG texture link

is not getting applied to the mesh.

look at the image named testimage8.png

Texture file size is 2MB.

Thank you

I don’t see this on my machine. Maybe the texture isn’t loading at all. Can you try this PG and paste the console log.

PG: https://playground.babylonjs.com/#Z1VL3V#555

Thanks
Now all images are getting applied.
uploaded console log for your reference.
Thank you so much.



I didn’t change the code besides adding some console logs, so I don’t know why it didn’t work before.