如何等待纹理完成从 Three.js 中的 JSON 模型加载?

Posted

技术标签:

【中文标题】如何等待纹理完成从 Three.js 中的 JSON 模型加载?【英文标题】:How to wait for textures to finish loading from JSON model in Three.js? 【发布时间】:2014-01-09 19:30:48 【问题描述】:

我有一个基于 AlteredQualia 的蒙皮示例成功加载的 JSON 模型。但是,我不想在模型完成加载之前显示它。正如您在此示例中看到的,模型首先出现,然后加载它们的纹理资源:http://alteredqualia.com/three/examples/webgl_animation_skinning_tf2.html

我在网页中添加了一个不透明的 div,然后使用 JSONloader.load() 函数的回调将那个 div 移开。不幸的是,当网格被添加到场景中时触发了这个回调,这似乎没有被仍在加载的蒙皮图像所阻挡,所以我最终“揭示”了一个不完整的场景。

我应该如何解决这个问题?我已经看到有一个函数 THREE.ImageUtils.loadTexture() 有一个回调函数,但它似乎没有涉及到这个网格被声明和定义的用例:

var mesh = new THREE.SkinnedMesh(geometry,new THREE.MeshFaceMaterial(materials));
//geometry and materials are both parameters of jsonloader.load callback

我查看了 MeshFaceMaterial 和 SkinnedMesh 的源代码,但在那里找不到解决方案。

感谢您提供的任何帮助。

【问题讨论】:

【参考方案1】:

这是一个愚蠢到可笑的作弊,但它可以作为一个黑客。我同意至少需要单独实现图像加载和其他一切,因此不需要图像的东西不会玩弄他们的小电子拇指。也就是说,如果优化不是您的问题......

var texture = THREE.ImageUtils.loadTexture(url); 
while (texture.image.width == 0);

【讨论】:

这可能有效,但不能保证有效。实际上,在您的 javascript 退出当前事件之前,浏览器应该什么都不做。您正在等待的事实意味着您从未退出该事件。基本上,您很幸运,您测试的任何浏览器/版本都没有完全冻结。最重要的是,即使在连接速度很慢的情况下它不会冻结,浏览器也可能会因为花费的时间太长而杀死你的 JavaScript。您还可以在旋转等待时拒绝用户的机器。 这对我来说看起来像是“忙着等待”......不要这样……【参考方案2】:

这有点小技巧,但在 three.js 的第 10362 行(修订版 61),您会看到 image.onload = function()(它位于主 THREE.Loader 原型中)。我设法将其追踪为从 JSON 模型加载的纹理的回调函数。

如果您在该函数中添加自己的回调,您可以跟踪纹理的加载时间。

正如我之前所说,这是一个 hack(它对特定应用程序帮助很大)而不是解决方案,请非常小心地修改库代码。您可能会破坏您不知道自己正在破坏的东西。

【讨论】:

感谢您的建议,我认为现在修改源代码有点太新手了。【参考方案3】:

目前没有正确整理。目前在加载所有内容时没有回调或事件调度:/

【讨论】:

有解决方法吗?也许扫描 json 文件中的材质并为每个图像文件创建独立的纹理只是为了缓存它们? 嘿,好吧,它没有!我首先使用 loadTexture 加载它们,但即使在那之后 JSONloader 仍然获取图像文件而不是从缓存中获取它(在 chrome 和 firefox 中测试)。 network monitor screenshot 我也尝试使用 window.onload 但该事件只触发一次。

以上是关于如何等待纹理完成从 Three.js 中的 JSON 模型加载?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Three.js 中用 ShaderMaterial 替换 Collada 导入的纹理?

Three.js中同一网格面上的多个透明纹理

three.js如何使纹理“生成”纹理坐标,就像搅拌器循环一样

Three.js - 从文件输入加载 Collada 文件(和纹理)

如何将图像和纹理添加到 Three.js JSON 对象文件

如何在three.js中使用mtlLoader和objLoader中的多个纹理?