fungus1487
fungus1487

Reputation: 1809

Max Number of Textures WebGL

I have been looking for information regarding WebGL and the maximum number of textures/amount of memory that can be assigned for rendering. This is obviously hardware/device specific so am looking for a way to intelligently handle textures.

I currently have textures in 512x512 RGBA8 format. Potentially a user could have 270 textures loaded into memory. I understand that it works out at 4 bytes per pixel multiplied by 4/3 for mip maps. So a single texture plus mip maps would be in the region of 4 * 512 * 512 * 1.33 = 1.33MB. Resulting in a total of 359.1MB total to load the textures into memory.

This is a worst case and would be fine on mid/high end machines but I also want to optimize for mobile once WebGL is widely available on android and low spec machines.

If I reduce the textures to 256x256 I notice a loss in quality but this could be an option for low end devices. This results in a total of 4 * 256 * 256 * 1.33 = 0.33MB per texture and overall 89.1MB.

Is there anyway with the API to determine total available texture memory before attempting to load textures into WebGL context?

Also is there also a cap on the total number of textures that can be loaded into memory at one time?

I want to employ the above two parameters to have sensible defaults when a user loads my page.

Upvotes: 3

Views: 2491

Answers (2)

brita_
brita_

Reputation: 485

I believe this question is fully answered in Max number of textures in WebGL?

To know the texture limits, you can look up the guaranteed minimums for WebGL1 or 2. In this case, MAX_TEXTURE_IMAGE_UNITS is the guaranteed minimum that a fragment shader is able to bind with (16 textures for WebGL 2).

The official limits can be looked up in the spec. WebGL2 follows the GLES3 spec: https://registry.khronos.org/OpenGL-Refpages/es3.0/html/glGet.xhtml https://registry.khronos.org/OpenGL/specs/es/3.0/es_spec_3.0.pdf#page=286

In practice, implementations may support more.

The application can assume a limit chosen from the guaranteed or the practical minimum values, or it can dynamically query and bind the resources at runtime with

const maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);

Upvotes: 0

Andrew Rasmussen
Andrew Rasmussen

Reputation: 15109

To the best of my knowledge, there is no way to do this. From Toji's answer, it sounds like this is for security reasons.

I would consider who's going to be using your application and if this group of users is anything besides strictly users with great dedicated graphics cards on their desktops, then downsize the textures for everyone. Maybe you could allow a higher level of graphics as an option, but realize that this will probably cause an out of memory exception for some/most people.

If by chance you aren't ever using all of those textures at once, you could try to keep track of which ones you are using and only load those to memory (and unload textures using gl.deleteTextures). I'm guessing deleting and loading this many textures at runtime rather than all at startup time is going to take a lot of time so doing so carefully (only a few at a time) to maintain framerate would be smart. Not sure if you'd even be able to load a 1.33MB texture in one frame though, or if this even applies to your application.

Upvotes: 1

Related Questions