Как использовать async / await при загрузке изображения текстуры материала

#three.js

#three.js

Вопрос:

У меня есть .obj и .mtl с изображением текстуры, которое я хочу отобразить. Сцена статична, поэтому я хочу выполнить рендеринг, явно вызвав renderer.render() команду один раз (и не использовать animate()), после загрузки ресурсов и просмотра текстуры. Но текстура не видна.

Чтобы дождаться загрузки текстуры, я:

  • при загрузке файлов .mtl и .obj вызывайте LoadAsync() вместо load()
  • добавьте await перед некоторыми вызовами (mtlLoader.LoadAsync, materials.preload, OBJLoader.LoadAsync).
  • слегка измените файл MTLLoader, OBJLoader, по сравнению со ссылкой (из threejs/releases/three.js-r120/examples/jsm/loaders/MTLLoader.js )
    (изменения должны учитывать асинхронные / ожидающие изменения)

Изменения работают, но я не совсем понимаю, почему, и хотел бы знать.
В частности, у меня есть вопрос относительно размещения async / await в одной из функций (MTLLoader.MaterialCreator::создать)

В example13_MTLLoader.js , это поток программы:

 MTLLoader.MaterialCreator::preload
  MTLLoader.MaterialCreator::create
    MTLLoader.MaterialCreator::createMaterial_
 

в example13_OBJLoader.js , это поток программы:

 OBJLoader::parse
  MTLLoader.MaterialCreator::create
 

Я поместил async/await в MTLLoader.MaterialCreator функции: preload, create, createMaterial_ .
Рациональным было дождаться загрузки текстуры, прежде чем продолжить программу.


UseCase1
В этом случае:

  • Текстура загружается до продолжения работы программы. Это можно увидеть в журнале, где:
    • материал определен objLoader.materials.materials {test2: MeshPhongMaterial}
    • изображение карты определено objLoader.materials.materials.test2.map.image <img crossorigin=​"anonymous" src=​"http:​/​/​127.0.0.1:​8080/​./​test2.jpg">​
  • Но текстура не отображается
    Код для этого случая можно увидеть здесь

UseCase2
Если я извлекаю из async/await MTLLoader.MaterialCreator::create

  • Текстура НЕ загружается до продолжения работы программы. Это можно увидеть в журнале, где:
    • список материалов пуст objLoader.materials.materials {}
    • тест материала 2 не определен objLoader.materials.materials.test2 undefined
  • Но текстура отображается …
    Код для этого случая можно увидеть здесь
    (по какой-то причине мне нужно несколько раз нажать Run в jsfiddle, чтобы увидеть текстуру, в противном случае отображается только белое пятно)

Единственное изменение между 2 случаями заключается в значении MTLLoader.MaterialCreator::doUseCreateWithAsync = false/true (поведение для 2 случаев одинаково для одного рендеринга или animate() )

Почему при размещении async/await в MTLLoader.MaterialCreator::create, текстуре не видно?

Спасибо