Issue with display when adding LoD from glb

Hello,
I’m using the following code to load GLB into LoD.

import * as THREE from 'three';
import GLTFLoader from 'three-gltf-loader';

const OrbitControls = require('three-orbitcontrols')

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

var renderer = new THREE.WebGLRenderer();
renderer.gammaOutput = true;
renderer.gammaFactor = 2.2;
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var controls = new OrbitControls(camera, renderer.domElement);    

camera.position.z = 1;
controls.update();

// Instantiate a loader
var loader = new GLTFLoader();

var lod = new THREE.LOD();
camera.position.x = 100;
camera.position.y = 100;

// Load a glTF resource
loader.load(
    // resource URL
    'Model.glb',
    // called when the resource is loaded
    function (gltf) {

        gltf.scene.traverse(function (child) {

            if (child.isMesh) {
                var geometry = child.geometry;
                var material = child.material;
                var mesh = new THREE.Mesh(geometry, material);
                //scene.add( mesh );
                lod.addLevel(mesh, 75);
            }

        });


    },
    // called while loading is progressing
    function (xhr) {

        console.log((xhr.loaded / xhr.total * 100) + '% loaded');

    },
    // called when loading has errors
    function (error) {

        console.log('An error happened');
        console.log(error);

    }
);

var light = new THREE.HemisphereLight();
scene.add(light);
scene.add(lod);

var animate = function () {
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
};

animate();

Only a few element of the model is displayed (a screenshot is available here http://the.ndero.ovh/file/threejs.png ). The whole scene is correctly displayed if i use scene.add(mesh) instead of lod.addLevel

Is this expected ?

Is it possible for you to share the glTF asset in this thread?

BTW: Instead of using the npm packages three-gltf-loader and three-orbitcontrols, it’s better to import GLTFLoader and OrbitControls from the three npm package like so:

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

More details about this approach: https://threejs.org/docs/index.html#manual/en/introduction/Import-via-modules

Thanks for the importation tip !
You can find the asset here (http://the.ndero.ovh/file/LOD_Model_10.glb).

The problem is that your asset consists of 10 single meshes:

In other words you call lod.addLevel(mesh, 75); ten times and thus overwrite the LOD setting. That’s the reasons why you see only a part of the scene.

Note: LOD.addLevel() is actually a bad name. It should be LOD.setLevel().

Hum thanks I didn’t catch this subtility. How should I proceed to add all the single meshes with LOD ?

I would try to merge all meshes with BufferGeometryUtils.mergeBufferGeometries(). When using the method, you end up with a single geometry and thus a single mesh.

The following example uses BufferGeometryUtils.mergeBufferGeometries().

https://threejs.org/examples/webgl_geometry_minecraft

The thing is if I merge the meshes, I would be loosing the materials info associated to each meshs, unless there is a way to merge the materials as well ?

No, that’s not possible. Well, it seems you hit a limitation of the library and you can’t use THREE.LOD with your model in its current state.

Thanks for the update !