在three.js中同步与异步纹理加载

时间:2017-02-07 18:30:38

标签: asynchronous three.js textures

我在午餐时间一直在玩Three.js,实施旧的NEHE演示(到目前为止已达到#30)。一个令人讨厌的方面是新的异步纹理加载器。我有一个着色器材质演示,其中的材质创建如下:

var uniforms = {
    tOne: { type: "t", value: THREE.ImageUtils.loadTexture( "images/cover.png" ) },
    tSec: { type: "t", value: THREE.ImageUtils.loadTexture( "images/grass.png" ) }
};
var material_shh = new THREE.ShaderMaterial({
    uniforms: uniforms,
    vertexShader: vertShader,
    fragmentShader: fragShader
});
var mesh = new THREE.Mesh( cubeGeom, material_shh );
gfxScene.add(mesh);

这样可以正常工作,但是三个.js在控制台中对我抱怨不推荐使用loadTexture。 (为什么?)。无论如何,我可以写它来使用像这样的textureLoader:

var textureLoader = new THREE.TextureLoader();
var cover, grass;
textureLoader.load( "images/cover.png", function( texture ) {
    cover = texture;
});

textureLoader.load( "images/grass.png", function( texture ) {
    grass = texture;

   var uniforms = {
        tOne: { type: "t", value: cover  },
        tSec: { type: "t", value: grass  }
    };

    var material_shh = new THREE.ShaderMaterial({
        uniforms: uniforms,
        vertexShader: vertShader,
        fragmentShader: fragShader
    });

    var mesh = new THREE.Mesh( cubeGeom, material_shh );
    gfxScene.add(mesh);
});

这也有效,但似乎相当复杂。我知道asynch对Web应用程序等有好处,但是......并且它假设我保证在grass.png之前加载cover.png。这实际上是有保证的吗?我宁愿坚持使用同步loadTexture实用程序,但也许有充分的理由不使用loadTexture(除了它已被弃用)。 TIA。

1 个答案:

答案 0 :(得分:1)

TextureLoader.load()返回纹理对象,因此,如果您没有想到要同步加载,那么您可以以相同的方式使用新的TextureLoader

var textureLoader = new THREE.TextureLoader();
var uniforms = {
    tOne: {type: "t", value: textureLoader.load("images/cover.png")},
    tSec: {type: "t", value: textureLoader.load("images/grass.png")}
};

编辑#1

对于同步加载,您可以使用LoadingManager。它目前不是最优雅的API,但它应该适用于简单的情况。此示例适用于版本r84

function loadTextures(urls, callback) {

    var textures = [];

    var onLoad = function() {
        callback(null, textures);
    };

    var onProgress = function() {};

    var onError = function(url) {
        callback(new Error('Cannot load ' + url));
    };

    var manager = new THREE.LoadingManager(onLoad, onProgress, onError);

    var loader = new THREE.TextureLoader(manager);

    for (var i=0; i<urls.length; i++) {
        textures.push(loader.load(urls[i]));
    }
}

var urls = [
    "images/cover.png",
    "images/grass.png"
];

loadTextures(urls, function(error, textures) {
    if (error) {
        console.log(error);
        return;
    }
    // Main code goes here using the textures array
});
相关问题