Re-using textures with different UV and level properties

Im interesting in using the “uscale”, “vscale” and “level” on a texture on a per model basis. (I am interseting in using level for normal maps to adjust the normal strength) So for example, id like to have 2 models in a scene using the same texture but with different “level” or scale properties.
My understanding is that since these properties are on the texture, I would have to first load the texture I need, then clone() the texture for each model in the scene (assuming I wanted each model to have unique texture transform values).

  1. When I clone the texture , is it possible to clone just the properties without the actual bytes to save memory? (eg, re-using the orignal buffer values but enabling me to use unique transforms)
  2. Is there a way to set these properties on a per-shader basis rather than a per-texture basis? I think this is possible with a custom material but im trying to stick with standardized PBRMaterial as we want to be gltf spec compliant.

I do realize that perhaps the most efficient thing to do is handle these uv transformations on the asset level aka. Force the artist to set the proper uv scale on the mesh itself at author time, and for things like texture levels, do that as well in photoshop …etc at author time. But the flexibility to do this on the fly across multiple models is a nice workflow for the artist.

Thanks,
Anupam

More than one material can use the same texture which is loaded and stored once. If you changed the scale at the assets level then you would need to load all the different texture assets.

I would suggest with a couple of different meshes you create two different materials using the same texture and change the material properties and see what happens.

2 Likes

Also wanted to note that if you use the same URL when creating a new texture, babylon will automatically use the same resource for both, so you are not loading the same texture twice.

1 Like

Hello @Anupam_Das just checking in, do you have any more questions about this? :slight_smile:

Thanks for asking. Well… unless there is a way to do UV Scaling operations on the geometry at runtime in an efficient way we’re going to have to do it on the Texture. And since we are re-using the same texture on multiple geos with different UV Transforms it seems the only way to do this efficiently is to Clone() the textures when the transforms differ form the one in “cache”. The downside to this approach is that it will take up more memory. Im open to other suggestions to accomplish the same thing if anyone has other ideas?

sure enough cloning the textures worked. Now we just have to be smarter about when to clone and when not to clone aka. Impliment our own texture caching scheme kinda. Since babylon already has its own internal texure caching scheme, it would be nice to just support something like this in the API. Like… if I need a texture with a specific transform and that combination does not exist in the cache, then resolve to cloning the texture else retrieve from cache.

How many textures are being cloned? I wouldn’t expect cloning textures use a ton of memory unless you have a large number of them. Cloning textures should not copy the texture data.

For fun testing, I did thousands and diddnt see much of noticeable impact…
In reality, there may be a few dozen clones at best.

What we are doing is pre-loading a bunch of textures. Then assigning those textures to various parts of a model. Some of those textures are being re-used in different parts of the model with differnt UV scale values. So basically I think our approach is going to be simply fetch the texture from our preloaded texture list, then when we apply the texture to the PBR material we simply clone() that texture so it can have its own independent transform and not share those with other textures. We can also optinally dispose that coned texture when we need to for clenliness.

3 Likes

Hi @Anupam_Das just checking in again, was your question answered? :slight_smile:

Solved. Turns out cloning textures does not take up any additional memory so this solution worked for my use case. For anyone who comes around this thread, if you need to re-use the same texture with different transforms, clone() may be useful in this situation.

3 Likes