Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
511 views
in Technique[技术] by (71.8m points)

three.js - How to use async/await when loading a material texture image

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

Please log in or register to reply this article.

OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...