如何在THREE.js中使用预加载的图像作为纹理

时间:2015-02-24 15:43:25

标签: javascript three.js image-preloader

此特定项目具有非画布回退例程,该例程也使用预加载例程。图像添加和加载适当,但我无法弄清楚如何在THREE.js中使用它们,因为THREE.js将使用自己的图像加载器来基本上重新加载图像。

**这里是JS **

function MAIN_PRELOAD() {

 var Preload_List = [];
 var Preload_Loaded = 0;
 var Preload_Errors = 0;

 function preload_scene() {

  // Skip Empty List...
  if(SceneAssets.length < 1) return;
  for(var i in SceneAssets) {

   // Skip Blanks...
   if(SceneAssets[i]['material']['map'].length < 1) continue;

   // Skip Repeats...
   if(Preload_List.indexOf(SceneAssets[i]['material']['map']) >= 0) continue;

   // Add to list...
   console.log('Image added to preloader: '+SceneAssets[i]['material']['map']);
   Preload_List[Preload_List.length] = SceneAssets[i]['material']['map'];

  }
 }

 function preload_masks() {

  // Skip Empty List...
  if(MaskLayer['textures'].length < 1) return;
  for(var i in MaskLayer['textures']) {

   // Skip Blanks...
   if(MaskLayer['textures'][i].length < 1) continue;

   // Skip Repeats...
   if(Preload_List.indexOf(MaskLayer['textures'][i]) >= 0) continue;

   // Add to list...
   console.log('Image added to preloader: '+MaskLayer['textures'][i]);
   Preload_List[Preload_List.length] = MaskLayer['textures'][i];

  }
 }

 function preload_finished() {

  console.log('Preloading has finished!');
  // NYI: Hide the loading overlay...
  init();
  animate();

 }

 function preload_init() {

  // Preload Assets...
  preload_scene();
  preload_masks();

  // Finish if empty...
  if(Preload_List.length < 1) {
   preload_finished();
   return;
  }

  // Iterate if filled...
  for(var i in Preload_List) {

   // Enclosure for event trapping...
   (function(i) {

    var imageElement = document.createElement('img');

    imageElement.onload = function() {
     console.log('Image "'+Preload_List[i]+'" done loading!');
     Preload_Loaded ++;
     if(Preload_Loaded + Preload_Errors == Preload_List.length) {
      preload_finished();
     }
    };

    imageElement.onerror = function() {
     console.log('Image "'+Preload_List[i]+'" failed to load...');
     Preload_Errors ++;
     if(Preload_Loaded + Preload_Errors == Preload_List.length) {
      preload_finished();
     }
    };

    imageElement.src = Preload_List[i];

   })(i);

  }

 }
 preload_init();

}

MAIN_PRELOAD();

目前尚未实现的是一个实体覆盖,可以在演示文稿预加载完成之前屏蔽所有内容。

要明确的是,我的应用程序的两个部分都可以自行运行,但是当所有内容都加载并添加到场景中时,会出现一个大的处理断断续续,这对整体用户体验不利。

当它根据需要加载屏蔽层时,演示文稿中也会出现周期性的断断续续的情况,并且每次都会从新的HTTP请求而不是通过THREE.ImageUtils.loadTexture()的浏览器缓存中执行此操作。< / p>

我最好的猜测是,我必须以某种方式使用预加载器中创建的未悬挂的img元素作为THREE.ImageUtils.loadTexture()的替代品,我无法找到任何人在任何地方做同样的事情而且我认为如果能让它工作,这将是一个很好的方法来缓存THREE.js的场景资产。

还将考虑解决此问题的其他方法。

使用THREE.js r70

1 个答案:

答案 0 :(得分:3)

var texture;
var imageElement = document.createElement('img');
imageElement.onload = function(e) {
    texture = new THREE.Texture( this );
    texture.needsUpdate = true;
    init();
};
imageElement.src = "myimage.png";

init() {
    material = new THREE.MeshPhongMaterial( { map : texture } );
}

这是一个fiddle来演示 注意:在小提琴中,我使用图像dataUrl,这样我就可以将图像用作纹理而不会出现CORS错误。在网站上,您应该能够按正常情况将图像src设置为文件路径。