Threebox 和 Mapbox:为什么纹理和形状在同一 GLTF 模型的连续实例中消失?

Threebox and Mapbox: Why are textures and shapes disappearing on consecutive instances of the same GLTF model?

我正在使用 Mapbox-gl (2.2.0) 和出色的 Threebox (2.2.3) 插件将同一 GLTF 模型的多个实例添加到场景中。

第一个模型正确渲染,第二个模型存在于场景中,但丢失纹理 and/or 个形状。

可以加载不同的模型并且它们不会相互冲突,但是当每个模型的第二个和连续实例丢失纹理 and/or 形状时会发生相同的行为。

Two different (but similar) models, loaded twice. The first instance of each model renders correctly, the second instance does not

Mapbox 2.0 之前的版本工作正常,所以我认为这是一个错误或我误解的功能。如果能在最新版本上使用 3D 地形,那就太好了。

下面是相关的代码,从右到右:

    let map = new mapboxgl.Map({
        style: "mapbox://styles/mapbox/satellite-v9?optimize=true",
        center: [7.059806068014609, 46.058219779837316],
        zoom: 9.848554211380023,
        pitch: 85,
        bearing: -154.1,
        container: 'map',
        antialias: true, 
        hash: true
    });

    map.on('style.load', function () {

        map.addLayer({
            id: '3D-overlay',
            type: 'custom',
            renderingMode: '3d',
            onAdd: function (map, mbxContext) {

                window.tb = new Threebox(
                    map,
                    map.getCanvas().getContext('webgl'),{});

            },

            render: function (gl, matrix) {
                tb.update();
            }
        });

        addBike(1);
        addBike(2);

    });

    function addBike(num){

        var options = {
            obj: "./gltf/cyclist/scene.gltf",
            type: 'gltf',
            scale: 10,
            units: 'meters',
            rotation: {x: 90, y:177, z:0},
            anchor: 'auto'
        }

        tb.loadObj(options, function (model) {

            tb.add(model);

            model.setCoords([6.927566+(num/10), 45.984111 + (num/10), 4000]);

            model.traverse(function (object) {
                object.frustumCulled = false;
            });

            model.playAnimation({ animation: 0, duration: 1000000000 });

            model.selected = true;

        })

    }

这是一个 github 文件库:

https://github.com/nickshreck/threebox-mapbox-gltf-issue.git

运行 npm i,将一个mapbox token放入main.js,然后npm run dev

非常感谢

感谢您以如此详细和清晰的方式报告如此棘手的问题。它帮助我确定了 Threebox 代码中的一个问题。 This issue has been resolved adding a new attribute to tb.loadObj that now accepts clone: false. It's already available in the code repo, and it will be published as npm module v2.2.4 soon. In the meantime you can use the bundle file from github.

您的函数 addBike 现在看起来像这样:

    function addBike(num){

        var options = {
            obj: "./gltf/cyclist/scene.gltf",
            type: 'gltf',
            scale: 10,
            units: 'meters',
            rotation: {x: 90, y:177, z:0},
            anchor: 'auto',
            clone: false //objects won't be cloned
        }

        tb.loadObj(options, function (model) {

            tb.add(model);

            model.setCoords([6.927566+(num/10), 45.984111 + (num/10), 4000]);

            model.traverse(function (object) {
                object.frustumCulled = false;
            });

            model.playAnimation({ animation: 0, duration: 1000000000 });

            model.selected = true;

        })

    }

我还建议您在 addLayer 方法外部而不是内部声明 tb 对象。这将触发一些与真实阳光和地形层相关的自动行为,并删除重复的灯光。

        window.tb = new Threebox(
            map,
            map.getCanvas().getContext('webgl'),
            {
                realSunlight: true,
                sky: true,
                terrain: true,
                enableSelectingObjects: true,
                enableTooltips: true
            }
        );

        map.on('style.load', function () {

            map.addLayer({
                id: '3D-overlay',
                type: 'custom',
                renderingMode: '3d',
                onAdd: function (map, mbxContext) {

                    addBike(3);
                    addBike(4);

                },

                render: function (gl, matrix) {
                    tb.update();
                }
            });


        });

再次感谢!