2017-02-07 4 views
0

Ich habe während meiner Mittagspause mit Three.js herumgespielt und die alten NEHE-Demos implementiert (bis zu 30). Ein Aspekt, der nervig zu sein scheint, sind die neuen asynchronen Texturlader. Ich habe einen Shader-Material Demo, wo das Material wie folgt erstellt wird:synch vs. asynch texture Laden in three.js

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); 

Dies funktioniert gut, aber Three.js winselt mich in der Konsole, die Loadtexture ist veraltet. (Warum?). Wie auch immer, ich kann es schreiben einen textureLoader wie folgt zu verwenden:

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); 
}); 

Dies funktioniert auch, aber scheint ziemlich verworren. Ich verstehe, dass asynch gut für Web-Apps ist, aber ... und es geht davon aus, dass ich sicher bin, dass die cover.png vor grass.png geladen wird. Ist das garantiert? Ich würde lieber bei dem synchronen Dienstprogramm loadTexture bleiben, aber vielleicht gibt es einen guten Grund, loadTexture nicht zu verwenden (außer es ist veraltet). TIA.

+0

Sie können alle Ressourcen laden, müssen Sie zuerst mit 'THREE.LoadingManager()', und, wenn alles getan ist, dann rufen Sie die Funktion der Animation. – prisoner849

Antwort

0

TextureLoader.load() gibt die Textur-Objekt so, wenn Sie nicht concered sind über die Lasten zu synchronisieren, dann können Sie die neue TextureLoader in der gleichen Art und Weise verwenden:

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")} 
}; 

Edit # 1

Für eine synchrone laden Sie können die LoadingManager verwenden. Es ist im Moment nicht die eleganteste API, aber es sollte für einfache Fälle funktionieren. Dieses Beispiel gilt für Version 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 
}); 
+0

Ah, das ist nicht in der Dokumentation erwähnt, aber wenn Sie den Code selbst lesen, kann man das sehen. Vielen Dank. Erinnert mich wieder daran, dass mit drei. Js RTFC! – rkwright

+0

Hoppla. Es stellt sich heraus, dass dies nicht immer funktioniert. textureLoader gibt immer eine Textur zurück, aber manchmal wird das Bild geladen und manchmal ist es undefiniert. Im letzteren Fall erhält man den Fehler: "THREE.WebGLRenderer: Texture für die Aktualisierung markiert, aber Bild ist nicht definiert Texture" aus three.js Zeile 17571 (Version 82). Es sieht also so aus, als müsste ich zu der "veralteten" Methode zurückkehren oder gewundenen Code schreiben. Aber vielleicht fehlt mir noch etwas. – rkwright

+0

Ja, das Lesen des Codes hilft. Ich habe die Antwort mit einem Beispiel aktualisiert, um alle Texturen zu laden, bevor der Hauptcode ausgeführt wird. –