6

I have a local file in which I try to load texture like this:

var texture = THREE.ImageUtils.loadTexture( 'image.jpg' );
var cubeGeo = new THREE.CubeGeometry( 50, 50, 50 );
var cubeMat = new THREE.MeshBasicMaterial( { map: texture } );
var cube = new THREE.Mesh( cubeGeo, cubeMat );
scene.add( cube );

The image doesn't show (the cube is black). When I move the whole folder to a server, and load it from there, the image is displayed.

My question is, why does it work when the files are on a server and not when they are on my computer? All files have been copied so it is not a problem with missing files. I also tried with absolute path but still no result. Do I have to change some settings on my computer? I am trying this on Windows 7 with Chrome 32.0.1700.76 m (latest version at the time of writing this) and I am using THREE.js r64. No other libraries are used.

Daew
  • 419
  • 1
  • 4
  • 14
  • There's a big difference in functionality between a file that's loaded on a desktop via a double click and a file loaded on a server. Usually it's a matter of security restrictions, particularly with Internet Explorer, but often a server has processes available that aren't available on a desktop double click. That's why we have servers rather than just connecting desktops. – KellyCode Jan 16 '14 at 02:31
  • Oh, and I'm pretty sure loadTexture uses a url to access the texture and that's only available from a server. WampServer is great for windows and easy to install. You can drop your files in it's www directory and access them in a browser using localhost/ – KellyCode Jan 16 '14 at 02:41
  • 1
    See if [this](https://github.com/mrdoob/three.js/wiki/How-to-run-things-locally) three.js wiki article helps you -- and check your console for errors. – WestLangley Jan 16 '14 at 06:40
  • 1
    @WestLangley: thank you, `--allow-file-access-from-files` solved it. Apparently browsers have protection against loading of local files. – Daew Jan 16 '14 at 17:16

4 Answers4

9

Your problem is due to security restrictions.

Run a local server.

For more info, see the three.js wiki article How to Run Things Locally.

three.js r.112

WestLangley
  • 102,557
  • 10
  • 276
  • 276
  • @Bakuriu Assuming the use case of the original OP, then the image is in the same folder as the html file. Open a terminal into this folder, run `python3 -m http.server` and then point your browser to `localhost:8000`. Solves it for me. – Tim MB Apr 11 '18 at 18:19
3

If you need to use textures in your project, you can convert images to base64 strings and then just assign them to your variables

Here is the sample: https://codepen.io/tamlyn/pen/RNrQVq

var texture = new THREE.Texture();
texture.image = image;
image.onload = function() {
texture.needsUpdate = true;
};

Where image was read from the base64 string

So you can create res.js and just write there all the textures :) it's not very good, because if you change some images, you have to reconvert them to base64, but it works in any browser (even Ms edge)

proggamer12
  • 192
  • 10
1

To further explain (because I was confused as well), you can install a local server (I used node - http://nodejs.org/download/ to download node).

After, to install server cd to your project directory and run in command line:

npm install http-server -g

To run:

http-server

Then go to the default local page

http://localhost:8080/

and you should see your project there.

mario
  • 1,503
  • 4
  • 22
  • 42
1

Probably late to the party, again.

You actually can do that without setting up a node server, unless ofcourse, you need a backend anyways.

You can basically do this by loading your local image into the browser by converting it into a Base64 string using the FileReader object.

After you convert the image to a Base64 string you can either save it to sessionStorage (limited to ~4 Mb on average), or keep the string saved in some variable while your "app" is running.

You can then convert the base64 string to a three.js texture, and apply it to an object in your scene. Note the asynchronous render call in the example below; You have to render the scene after the texture fully loads, otherwise, it simply won't show.

In the below case, I load the three.texture with my image that I've uploaded to sessionStorage.

TEXTURE = THREE.ImageUtils.loadTexture(
      sessionStorage.getItem('myBase64Img');
      {},
      function () { renderScene(); /* async call after texture is loaded */ }
    );

Cheers!

Ali Hammoud
  • 325
  • 2
  • 12