2017-02-07 5 views
0

Я играю с Three.js во время моего обеденного перерыва, реализуя старые демоверсии NEHE (до № 30 до сих пор). Одним из аспектов, который кажется раздражающим, являются новые асинхронные загрузчики текстур. У меня есть шейдер материала демо, где материал будет создаваться так:synch vs. asynch texture loading 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); 

Это прекрасно работает, но three.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); 
}); 

Это тоже работает, но кажется довольно запутанным. Я получаю, что асинч хорош для веб-приложений и т. Д., Но ... И он предполагает, что мне гарантировано, что cover.png будет загружен до grass.png. На самом деле это гарантировано? Я предпочел бы просто использовать синхронную утилиту loadTexture, но, возможно, есть веская причина не использовать loadTexture (кроме устаревшего). ТИА.

+0

Вы можете загрузить все необходимые вам ресурсы, используя 'THREE.LoadingManager()', и, когда все будет готово, вызовите функцию анимации. – prisoner849

ответ

0

TextureLoader.load() возвращает объект текстуры, так что если вы не concered о синхронизации нагрузки, то вы можете использовать новый 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 
}); 
+0

Ах, это не упоминается в документации, но если вы прочитаете сам код, вы можете это увидеть. Благодарю. Напоминает мне еще раз, что с tr.js RTFC! – rkwright

+0

Упс. Оказывается, это не всегда работает. textureLoader всегда возвращает текстуру, но иногда изображение загружается, а иногда оно не определено. В последнем случае возникает ошибка: «THREE.WebGLRenderer: Текстура, помеченная для обновления, но изображение не определено Texture» из строки трёх.js 17571 (версия 82). Похоже, мне придется вернуться к методу «устаревших» или написать сложный код. Но, возможно, я все еще что-то упускаю. – rkwright

+0

Да, чтение кода помогает. Я обновил ответ на примере, чтобы загрузить все текстуры перед запуском основного кода. –