Model texture atlas support?


It would be a huge benefit I think if the model object were improved to be able to load the texture data from an Atlas. This would allow 1) the developer to get a sense of the largest/smallest textures in the game and keep sizes reasonable and 2) allow Defold to generate a properly sized texture for UV referencing. However, I’m unsure of how difficult it would be. Has anyone else wanted such a feature or think it would be useful?



There are a few things that speak against this feature.
It’s not really like the sprites, where we generate the meshes at runtime.
Meshes/models can have a huge number of vertices and uv coordinates, and we don’t want to do runtime (re)generation of this data.

Each model instance can have a different texture, and as such a different uv set (since the texture might be placed anywhere inside the atlas), thus requiring a new uv set.

I don’t totally disregard the feature, but in general, this type of optimizations are done by the artist, creating a very detailed texture for one or more models.



I was thinking more of a compile time pass, where the Atlas is converted into a memory buffer which is written to the binary. Then the texture is set to use a specified range of the pixel data as the texture data for the model. This would be probably even a benefit for artists, as they would be able to simply create one UV per model and not have to worry about how the engine would build a model Atlas afterwords, or about having a power of 2 image size for each individual texture UV. This may require passing a vec4 to the shaders in order to determine the bounds of the UV within the generated texture Atlas however. But I think this could be done to the builtins without much work and wouldn’t impact existing projects. Maybe by creating an AtlasModel material perhaps?



Still, you wouldn’t want the same model, with two instances, each using a different texture, to generate two actual models in the runtime.

Also, remember you can swap textures at runtime.



Perhaps I’m confused about how the engine handles model texture data. If I create two models which use the same texture source, but each has UV mapping to 1/2 of the total width of the texture (one uses the first 50% and the other uses the last 50% for example), then would the engine only load this texture once into memory for all instances to share?



Each (file) resource is loaded once into memory.



I think it ought to work unless I am misunderstanding some aspect of the engine implementation (likely :blush ) UV data comes in with values from 0-1 so if those values were transformed to the bounds within the texture Atlas then a large collection of related models could all use the same resource for the UV mapping. I.e. if a texture is created by the artist with a texture size of 128x128 within a 256x256 texture Atlas, and it is placed 128 pixels to the right and at the top, then the float values for the UV map loaded via the model data could divided by 2 and offset by 0.5 in the x direction in order to map properly onto the resulting texture Atlas without requiring the artist to manage a cumbersomely large UV texture within their modeling software.



You already can UV multiple models onto the same textures manually. You just need a big enough texture to have all of the texture space you want. Really this is what we should be doing for 3d projects with lower scopes to reduce drawcalls. Often environments in 3D games of the past were many models but all used the same big texture. When you are getting into making a AAA game with PBR textures up the wazoo you can afford to invest into automation to optimize textures in this way.

1 Like