Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Three.TextureLoader is not loading images files

So I've been messing around with THREE and Node for a while, and up until now, I have been loading textures using the TextureLoader class as follows:

var loader = new THREE.TextureLoader;
loader.crossOrigin = '';

function createSphere ( radius , segments , rings ) {

  var geometry = new THREE.SphereGeometry(radius , segments , rings);

  var material = new THREE.MeshPhongMaterial({

        map: loader.load('./images/...'),
        bumpMap: loader.load('./images/...'),
        ect...

  });

  return new THREE.Mesh ( geometry, material )
}

It was working fine, and then I decided that instead of loading the textures when I created the material that I would like to pre-load all my textures, so I made a a small utility to do just that:

var loader = new THREE.TextureLoader;
loader.crossOrigin = '';

var textureMap = {

earthTex : {file : 'earth_no_ice_clouds.jpg', message : 'Loading Global Land Masses'},
earthBumpTex : {file : 'earth_bump.jpg', message : 'Loading Global Depth'},
earthSpecTex : {file : 'earth_specular.png', message : 'Loading Water'},
earthCloudTex : {file : 'earth_clouds.png', message : 'Loading Clouds'},
earthCultureTex : {file : 'earth_cultural.png', message :'Loading Country Borders'},
earthLookUpTex : {file : 'earth_lookup.jpg', message :'Loading Country Projections'},
moonTex : {file : 'moon.jpg', message :'Loading Lunar Surface'},
moonBumpTex : {file : 'moon_bump.jpg', message : 'Loading Lunar Depth'},
skyDomeTex : {file : 'galaxy_3.png', message : 'Loading Galaxy'}

};

Object.size = function(obj) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
}

function loadTextures(  ) {

    var path = "./images/";
    var size = Object.size(textureMap);
    var count = 0;

    for(var key in textureMap) {
        var textureItem = textureMap[key];
        var texture = loader.load(path + textureItem.file);
        console.log(texture);
    }
}

loadTextures();

Whenever I run this in my browser (Chrome) with the developer tools open, the THREE.texture object that ends up being logged has its image property set to 'undefined' and its src property set to " ". I do not understand why this is happening, and I have not changed any of the paths for my .png or .jpg files nor the location of the file in which I am using my the TextureLoader.

When I try to run the first snippet of code up top, the error also occurs and now I cannot seem to load any textures into my application.

Any help in understanding why this has happened all of a sudden would be greatly appreciated.

EDIT

I edited the first code block in an attempt to make my issue more clear. I wasn't using promises or callbacks or anything of the sort before. I was just calling my 'createSphere' function and similar functions from my scene initialization function. It used to work fine, and I had no problems loading textures.

Now, using the same program structure from before, the first code block doesn't work.

like image 840
LambShank Avatar asked Feb 21 '16 19:02

LambShank


1 Answers

You're not calling it correctly. TextureLoader.load() returns immediately (with an empty, still to be populated THREE.Texture object ... it populates only when the request completes), and it doesn't wait for the image to be loaded.

Instead, as you can read in its documentation here you can feed it with callback methods which will be called when loading is complete, finished, or in progress.

Taking the example from the documentation:

// instantiate a loader
var loader = new THREE.TextureLoader();

// load a resource
loader.load(
    // resource URL
    'textures/land_ocean_ice_cloud_2048.jpg',
    // Function when resource is loaded
    function ( texture ) {
        // do something with the texture
        var material = new THREE.MeshBasicMaterial( {
            map: texture
         } );
    },
    // Function called when download progresses
    function ( xhr ) {
        console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
    },
    // Function called when download errors
    function ( xhr ) {
        console.log( 'An error happened' );
    }
);

If you want to wait for all the textures to be loaded, that's going to get more complicated. One way is to use Promises, here is an answer to a very similar question I've given before: Is there a way to wait for THREE.TextureLoader.load() to finish?

like image 115
Leeft Avatar answered Nov 15 '22 21:11

Leeft