我在午餐时间一直在玩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。
答案 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
});