microsoft / glTF-Toolkit

A collection of tools for modifying and optimizing glTF assets
MIT License
295 stars 41 forks source link

Need help with MSFT_LOD generation for Threejs #56

Open Wellan-Arthur opened 2 years ago

Wellan-Arthur commented 2 years ago

Hello, With threejs, we use https://github.com/takahirox/three-gltf-extensions to successfully load GLTF models that already include MSFT_LOD. (working GLTF model : https://github.com/takahirox/three-gltf-extensions/tree/main/examples/assets/gltf/Torus/glTF-lod)

But when we try making our own with WindowsMRAssetConverter, no luck doing so, with multiple scenarios:

case 1 : multiple levels are active at the same time and with wild scales (red and green are 2 separate LODs) image Command used on Windows : .\scripts\WindowsMRAssetConverter.exe ./src/models/LOD0Arbre2.gltf -o ./dist/models/arbre.glb -lod ./src/models/LOD1Arbre2.gltf ./src/models/LOD2Arbre2.gltf ./src/models/LOD3Arbre2.gltf ./src/models/LOD4Arbre2.gltf -screen-coverage 0.5 0.45 0.25 0.05 0.001

case 2 : we get Vector errors image

Can you help us ? I can share the assets if needed for testing.

robertos commented 2 years ago

Hi @Wellan-Arthur,

The WindowsMRAssetConverter specifically compresses the meshes with Draco, converts the textures to DDS and enforces some rules about how the GLB file will be loaded in Windows MR. I recommend you use the gltf-Toolkit as a library, or modify WindowsMRAssetConverter to do what you want specifically. I also highly recommend looking at the generated (merged) GLTF to see if that makes sense to you - the scale shouldn't change, for example, but it's possible that your input GLTFs have different dimensions.

The "vector too long" error happens when a vector is allocated to have more than 10^19 elements. I'm pretty sure that's not the case here, are you using sparse accessors?

Wellan-Arthur commented 2 years ago

Thank you for your quick response @robertos, I just downloaded the exe last week from the release page and tried it in the terminal. May setting the platform parameter to "all" help ?

For the vector too long, the command i used was .\scripts\WindowsMRAssetConverter.exe .\src\models\Psphere_LOD_1.gltf -o ./dist/models/psphere.gltf -lod .\src\models\Psphere_LOD_2.gltf .\src\models\Psphere_LOD_3.gltf -screen-coverage 0.5 0.45 0.25 and here are the assets : sphere_lods.zip

robertos commented 2 years ago

WindowsMRAssetConverter is not the right tool if you want to merge LODs only. It will always make changes to the textures and meshes, and there's no guarantee of compatibility with any other loading system that's not Windows Mixed Reality. Setting the platform to "all" will create even more DDS textures for HoloLens and Desktop support.

You can merge them manually (follow the documentation here: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Vendor/MSFT_lod) or you can write a new tool or modify WindowsMRAssetConverter to only call the LOD merging functions you need.

As for the specific assets, your largest asset (LOD0) has 179k triangles, which looks a bit extreme for the level of detail of the shape in question. You could try to use your LOD1 as base. Additionally, your LOD3 is missing a texture ("Capture.png"), so it doesn't load correctly.

I did not debug the tool to see what caused the "vector too long". For the scaling I tried looking at the min and max values of the accessors don't match / are not close between LODs:

LOD0

 { 
        "bufferView" : 0,
        "componentType" : 5126,
        "count" : 90599,
        "max" : [
            1.6575839519500732,
            1.9634791612625122,
            1.6632860898971558
        ],
        "min" : [
            -1.4283250570297241,
            -1.7366538047790527,
            -1.9631317853927612
        ],
        "type" : "VEC3"
    },

LOD1

{
        "bufferView" : 0,
        "componentType" : 5126,
        "count" : 10199,
        "max" : [
            1.49282705783844,
            1.6971750259399414,
            2.0540969371795654
        ],
        "min" : [
            -1.3869609832763672,
            -1.5039387941360474,
            -1.5132321119308472
        ],
        "type" : "VEC3"
    },

LOD2

 {
        "bufferView" : 0,
        "componentType" : 5126,
        "count" : 439,
        "max" : [
            1.09893798828125,
            1,
            1.425253987312317
        ],
        "min" : [
            -1.0919990539550781,
            -1,
            -1
        ],
        "type" : "VEC3"
    },

LOD3

 {
        "bufferView" : 0,
        "componentType" : 5126,
        "count" : 4,
        "max" : [
            1,
            1,
            4.371138828673793e-08
        ],
        "min" : [
            -1,
            -1,
            -4.371138828673793e-08
        ],
        "type" : "VEC3"
    },

This is what I get by opening all 4 GLTFs with 3D Builder in the same scene just to check it out:

image

Wellan-Arthur commented 2 years ago

This was indeed the reason why I tried using WMRAC. Understood, I will try the manual way first.

Thank you for your detailed explanations!

About size, the first asset was indeed intended to be massive as the worst case scenario with no consideration to practical use. So I suppose that it can be discarded as an issue.

For scaling, the original LOD have all the same size when individually loaded in threejs. Those min-max values seems to come from WMRAC generation imo.

Here are the original files : trees_lod.zip The command used : .\scripts\WindowsMRAssetConverter.exe ./src/models/LOD0Arbre2.gltf -o ./dist/models/arbre.glb -lod ./src/models/LOD1Arbre2.gltf ./src/models/LOD2Arbre2.gltf ./src/models/LOD3Arbre2.gltf ./src/models/LOD4Arbre2.gltf -screen-coverage 0.5 0.45 0.25 0.05 0.001