Threebox 和 Mapbox:为啥同一 GLTF 模型的连续实例上的纹理和形状会消失?
Posted
技术标签:
【中文标题】Threebox 和 Mapbox:为啥同一 GLTF 模型的连续实例上的纹理和形状会消失?【英文标题】:Threebox and Mapbox: Why are textures and shapes disappearing on consecutive instances of the same GLTF model?Threebox 和 Mapbox:为什么同一 GLTF 模型的连续实例上的纹理和形状会消失? 【发布时间】:2021-07-31 10:14:58 【问题描述】:我正在使用 Mapbox-gl (2.2.0) 和出色的 Threebox (2.2.3) 插件将同一 GLTF 模型的多个实例添加到场景中。
第一个模型正确渲染,第二个模型存在于场景中,但丢失了纹理和/或形状。
可以加载不同的模型并且它们不会相互冲突,但是当每个模型的第二个和连续实例丢失纹理和/或形状时会发生相同的行为。
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令牌放入main.js,然后npm run dev
非常感谢
【问题讨论】:
只是检查模型,看起来是对的,所以问题可能与克隆模型(包括纹理)性能的重大改进有关。我正在认真考虑向tb.addModel
添加一个允许不克隆模型的选项。
这是一个可怕的 hack,但只需以不同的名称重新加载相同的对象即可达到预期的最终结果。
嗯...我忘了!不是那么糟糕,因为它保持了最好的性能变化(纹理克隆)而不影响动画......顺便说一句,我应该保留加载对象而不克隆的选项,在那一刻我正在努力解决严重的内存问题和我默认进行了克隆,但打开了一个任务以添加选项以避免克隆并始终完全加载。
感谢您帮助确认问题并确定可能的原因。 Threebox 令人难以置信,它为 Mapbox 开辟了一个充满可能性的世界,尤其是现在他们已经在环境中实现了 3D。我将密切关注您的更新,并再次感谢您对更大社区的帮助。谢谢你的新任务,那太好了。
不,谢谢你的报告,我什么都没做……你成功了! :-)
【参考方案1】:
感谢您以如此详细和清晰的方式报告如此棘手的问题。它帮助我发现了 Threebox 代码中的一个问题。 This issue has been resolved 向tb.loadObj
添加一个新属性,该属性现在接受clone: false
。它已经在代码仓库中可用,并且很快将作为 npm 模块 v2.2.4 发布。同时你可以使用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();
);
);
再次感谢!
【讨论】:
顺便说一句,我在您的代码中看到了这样的导入...import Threebox from 'threebox-plugin/src/Threebox.js'
,老实说,我不明白它是如何工作的!我建议你像这样导入import Threebox from 'threebox-plugin';
这很漂亮,谢谢。我已经从回购中撤出,一切都按预期工作。在过去的一年里,我完全依靠 Threebox 帮助我解决了一些难题,所以我很高兴听到我得到了一些帮助作为回报。还感谢您提供有关在外部声明 tb 对象的提示,我已采纳您的建议。还有关于进口建议!
如果您有任何问题,请随时在 repo 或此处打开问题。我会尽快提供帮助或提供解决方法
你是一个绝对的传奇。我现在正在疯狂地建造并试图找出她真正的能力,所以当我找到对你感兴趣的东西时,我会这样做!再次感谢您,请尽快发言。以上是关于Threebox 和 Mapbox:为啥同一 GLTF 模型的连续实例上的纹理和形状会消失?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Mapbox Mapmatching API 输出与 mapbox-gl-js 一起使用?
用 jsodom 和 jest 测试 react-mapbox-gl