Preserve tile aspect ratio in GLSL UDIM texture atlas by allowing maxU to be any value
The OpenGL implementation of UDIM support relies on a texture atlas built using rows of 10 tiles. As the number of UDIM texture grows, these tiles end up squished vertically. I have no recent value of production-level UDIM workflows, but I heard 500 tiles was not uncommon in the recent past, with a gap to have left and right side tiles well disciplined.
The optimal solution would be to allow the number of tiles per row to be closer to sqrt(maxTileIndex) when building the atlas. Even better would be to find maxU and maxV that minimizes the number of tiles while preserving the tile aspect ratio, which is akin to finding the best layout for a Jigsaw puzzle of X pieces (Youtube).
The value of maxU can always be retrieved since it is passed as the U value of the uv_scale parameter, so the mx_transform_uv() function on the GLSL side could be rewritten to:
vec2 mx_transform_uv(vec2 uv, vec2 uv_scale, vec2 uv_offset)
{
// To preserve tile aspect ratio we now unlock maxU
// Since it is hardcoded to 10 in the UDIM specifications,
// we need to remap the tile according to the maxU
// found in the uv_scale.x value.
int maxU = int(1.0/uv_scale.x);
int tileIndex = int(uv.y) * 10 + int(uv.x);
vec2 remapped = vec2(tileIndex % maxU, tileIndex / maxU);
remapped += fract(uv);
uv = remapped * uv_scale + uv_offset;
return uv;
}
Which would still work with current texture code since they always produce a value of 0.1 for uv_scale.u, but would unlock other layouts capabilities.
I managed to test the hypothesis in a local install of MaterialX and it works quite nicely. Is there any interest?