How to use async/await when loading a material texture image

北慕城南 提交于 2021-01-28 11:27:07

问题


I have a .obj, and .mtl with texture image that I want to render. The scene is static so I want to render by explicitly calling the renderer.render() command once (and not use animate()), after the assets are loaded, and see the texture. But the texture is not seen.

To wait until the texture is loaded, I:

  • call loadAsync() instead of load(), when loading the .mtl and the .obj files
  • add await before some of the calls (mtlLoader.loadAsync, materials.preload, objLoader.loadAsync)
  • change the file MTLLoader, OBJLoader slightly, compared to the reference (from threejs/releases/three.js-r120/examples/jsm/loaders/MTLLoader.js)
    (the changes are to accommodate the async/await changes)

The changes work, but don't fully understand why, and would like to know.
Specifically, I have a question regarding placing async/await in one of the functions (MTLLoader.MaterialCreator::create)

In example13_MTLLoader.js, this is the program flow:

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

in example13_OBJLoader.js, this is the program flow:

OBJLoader::parse
  MTLLoader.MaterialCreator::create

I placed async/await in the MTLLoader.MaterialCreator functions: preload, create, createMaterial_.
The rational was to wait for the texture to be loaded before continuing the program.


UseCase1
In this case:

  • The texture is loaded before the program continues. This can be seen in the log where:
    • the material is defined objLoader.materials.materials {test2: MeshPhongMaterial}
    • the map image is defined objLoader.materials.materials.test2.map.image <img crossorigin=​"anonymous" src=​"http:​/​/​127.0.0.1:​8080/​./​test2.jpg">​
  • But the texture is not displayed
    The code for this case can be seen here

UseCase2
If I take-out the async/await from MTLLoader.MaterialCreator::create

  • The texture is NOT loaded before the program continues. This can be seen in the log where:
    • the materials list is empty objLoader.materials.materials {}
    • the material test2 is undefined objLoader.materials.materials.test2 undefined
  • But the texture is displayed...
    The code for this case can be seen here
    (for some reason I need to click Run in jsfiddle multiple times, to see the texture, otherwise only a white patch is seen)

The only change between the 2 cases is in the value of MTLLoader.MaterialCreator::doUseCreateWithAsync = false/true (the behaviour for the 2 cases is the same for single render or animate())

Why when placing async/await in MTLLoader.MaterialCreator::create, the texture is not seen?

Thanks

来源:https://stackoverflow.com/questions/65526329/how-to-use-async-await-when-loading-a-material-texture-image

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!