Pre-uploading of pc.Texture

I’ve got a jpeg texture and the first time it’s drawn there’s a costly gl.texImage2d call with Image Decode that takes together about 100ms and causes a short freeze.

I’ve tried calling the uploadTexture myself : pc.app.assets.findByTag('preupload-texture').forEach(tex => tex.resource.device.uploadTexture(tex.resource) )

but I get errors: playcanvas-stable.js:4623 WebGL: INVALID_ENUM: texImage2D: invalid format playcanvas-stable.js:4651 WebGL: INVALID_ENUM: generateMipmap: invalid texture target

1 Like

Please provide a simple small project that takes 5 mins to make, with replica of the problem, that dramatically saves time for people that can help you.

Launch: https://playcanv.as/p/Uk8x35nf/
Project: https://playcanvas.com/project/453671/overview/texture-loading-forum-3212

Click anywhere to toggle the Box. First time around there’s a short freeze.
By the way: Shadows don’t work with material tiling properly.

I’ve submitted a bug report on the tiling issue.

What about the main issue?
Should I devise a hack in which I render each element once or is there a better way?

If I were you, yes, I’d render the box somewhere out of view on the first frame in order to force the image date into VRAM.

Hi everyone,

I hate to revive a very old thread, but we are facing basically the same problem, where we would want manually upload a texture to GPU on scene load in order to prevent frame drops during the game.

Has this been updated over the last 5 years? Are there any other fixes for this, or is the “best practice” still to place objects with that texture in view for the first frame in order to get the texture uploaded to GPU?

1 Like

Hi @Sam_RDX,

I’m afraid yes, that’s the current workaround, keep for at least a frame all models in view to force the engine to compile the required shaders and uploaded textures to the GPU.

Another workaround is to turn off your cameras Frustum Culling in the editor, then after one frame has passed turn it back on via JavaScript. This will load everything on the first frame and prevent any hick ups during gameplay. One issue with this method is that it will cause a delay/pause at the beginning of the game.

2 Likes

That’s a very good trick! If you make sure that all models are enabled somewhere in your scene it will do the trick.

1 Like

Thanks for all the suggestions!

Unfortunately, in our case it is a bit more complicated, as we have unticked pre-load on all textures in order for them to not be loaded on game-startup / in main menu. So when we switch to the game scene these textures may still be mid-loading in the first frame and the time the loading operation will take is not predictable. I.e. rendering the texture with a cam in the first frame won’t work since it will not upload the texture to GPU, since it is not fully loaded yet.

As a workaround we will probably now implement a script, which waits for all scene assets to be fully loaded, then render the entire scene with a cam and then disable our loading UI overlay.

It would still be nice to have a better way of manually uploading textures to GPU. Do you happen to know whether such a feature is planned for the future, or whether there is an existing issue on GitHub for this?

Thanks!

2 Likes

@mvaligursky something to comment on this?

1 Like

Partially related: Investigate parallel shader compilation · Issue #3559 · playcanvas/engine · GitHub

1 Like

@yaustar is a guru of loading, he might have some ideas.

We have some plans in the future to improve the texture API, and have this ticket so far:

Feel free to comment on it with your request, or even better create a separate issue and link them together.

2 Likes

IIRC, the main hit is when the texture is first used as it gets uploaded to the GPU on the main thread.

Having an API to manually upload textures to the GPU would be great so users can control when the stutter happens and potentially phase it over several frames.

Wondering if it’s possible to do this on separate thread? Would that require offscreen canvas support?

1 Like

If you do it on a separate thread, you need to do all rendering on a separate thread. There’s only a single thread a WebGl calls can be called from, you cannot do rendering on one thread and resource creation on another.

2 Likes

This is getting released with the engine 1.57 this week: Test for ImageBitmap support at startup by slimbuck · Pull Request #4598 · playcanvas/engine · GitHub

and it helps to speed up texture loading quite a lot.

3 Likes

Thanks for all the feedback and thanks @yaustar for adding to the GitHub issue. Really appreciate your help!

@yaustar @mvaligursky Thanks for your help! Since this effects all our games and It’s hard for me to estimate the complexity of the issue: Do you have a rough estimate on when you’ll adress the issue?

Thanks a lot,
Rene & Team

1 Like

Has the recent change to use ImageBitmap in 1.57 helped in your case @Sam_RDX ?