SkinXX Material order not respected ACROSS Static Mesh LODs when importing from a Multi-LOD FBX

https://files.sshnuke.net/zz_office02_s06.eprf.fbx

In this FBX i have the following materials: ~152_Skin00, ~151_Skin01, ~14Z_Skin02, ~150_Skin03, ~154_Skin04, ~153_Skin05, ~0wl_Skin06, ~04d_Skin07, ~060_Skin08, ~14Y_Skin09, ~155_Skin10

BaseLOD uses Skin00, Skin01, Skin02, Skin03, Skin04, Skin05, Skin06, Skin07, Skin08

LOD1 uses Skin00, Skin01, Skin02, Skin03, Skin04, Skin05, Skin06, Skin07, Skin08 (same as baselod)

LOD2 uses Skin09 (simplified low res texture atlas covering the entire object)

So, I depend on the material order being correct to programmatically switch building skins and such for variety.
I expected the StaticMesh->Materials array (for when you set them per instance) to be of length 10 (0-9, as 10 isnt used), and have them in the correct SkinXX order as specified in the FBX.

What i got was this: ~152 (Skin00), ~151 (Skin01), ~14Z (Skin02), ~150 (Skin03), ~154 (Skin04), ~153 (Skin05), ~0wl (Skin06), ~04d (Skin07), ~060 (Skin08), ~152 (Skin00), ~151 (Skin01), ~14Z (Skin02), ~150 (Skin03), ~154 (Skin04), ~153 (Skin05), ~0wl (Skin06), ~04d (Skin07), ~060 (Skin08), ~14Y (Skin09)

(Easiest way to view this array is just to import the static mesh, obviously with LODs enabled and materials enabled, then “Asset Actions->Create Blueprint from this”, and then look at the Materials array on the StaticMeshComponent)

It’s obvious what’s happening here, the SkinXX sorting and deduplicating is happening as if the LODs were imported separately, which is exactly what i wanted to avoid by putting them all in one FBX file iwth LODGroups. More accurately, it happens inside ImportStaticMeshAsSingle which is run once for each LOD index (and without any context from other LODs), regardless if the LODs are in one fbx or not, so the SkinXX sorting is happening PER LOD, then those skins are ADDED to the materials array, so you get duplicate materials in the array if more than one LOD uses it (and the order could also be incorrect, it isn’t in this case, but it would be if LOD0 was using Skin09 before any others were)

I’ve tried to refactor that method so that the material remapping happens after all the LODs have been imported in a separate method, but the logic is too obfuscated for me to follow correctly, too much of it relies on only importing one LODIndex at a time.

So could you guys help me out by fixing this behaviour to work across LODs as I expect it to ?

Hi rajkosto -

Your FBX is importing correctly for me and as intended. I have 3 LODs (LOD 0, 1 and 2). LOD 0 references Materials resour thru resour9, LOD 1 references Materials resour thru resour9, LOD 2 references resour10. Each LOD is a separate mesh and must have its own set of material elements. There is no way for two LODs to share Elements, they can share Materials in their elements but not elements themselves.

Thank You

Eric Ketchum

This is not true. StaticMesh->SectionInfoMap contains the mapping for all the LODs and which element of StaticMesh->Materials they index into. StaticMesh->Materials could be deduplicated and SectionInfoMap updated to reflect that.
Also you must have ‘short file names’ or something turned on, because my material names are the full name which includes the ~ identifier with the actual material name after it
Go look at the StaticMeshComponent for the generated StaticMesh and see that it has 18 material slots, not 9. I do not care about the ‘per-lod’ materials that the static mesh editor UI shows, only the per-instance stuff that i can override.

Here’s a .uasset I generated with the modified importer code that does exactly what I want (changing a material in the static mesh editor for one LOD changes it for the others that use it as well, and when making a StaticMeshComponent out of it, the Materials array is exactly 10 items long and in the correct order): https://files.sshnuke.net/zz_office02_s06_eprf.uasset

Place it in Content/resources and mess with it’s materials to see that what I wanted was 100% possible and doesn’t break stock 4.7.6.

I’ve implemented the change myself, it works for my purposes but breaks if you’re importing LODs separately and the files don’t have the same SkinXX slots in them.

https://github.com/EpicGames/UnrealEngine/pull/1147

Works good enough for me, do what you will with it.