1

I am trying to create an animation in three.js with two scenes running at the same time. The first one has a fixed texture, which works as the background for the page, while the second one has a rotating cube. This is the part of the code where I am getting the issue:

THREE.ImageUtils.crossOrigin = '';
var texture = THREE.ImageUtils.loadTexture('https://i.imgur.com/eoWNz.jpg');
var backgroundMesh = new THREE.Mesh( 
    new THREE.PlaneGeometry(2, 2, 0),
    new THREE.MeshBasicMaterial({
         map: texture
    }));

I tried to follow this example and this question to solve the issue with the security concerning cross-origin images by using a simple http server with python, but still the background remains black.

Do you by any chance have an idea of what am I doing wrong? This is the fiddle with the complete code.

Thanks in advance for your replies!

EDIT:

Locally I get this error: THREE.Material: 'map' parameter is undefined. in three.min.js:428

Community
  • 1
  • 1
d_z90
  • 1,213
  • 2
  • 19
  • 48
  • +1 for a nice fiddle. But is the fact that it won't load not related to the fact that `fiddle` doesn't allow cross origin sources? – Wilt Mar 09 '16 at 15:31
  • I needed to paste the complete code somewhere :) I have edited the question with the error I get locally. Maybe it gives you a better idea of what is going wrong. – d_z90 Mar 09 '16 at 15:36
  • 1
    Yes it is undefined because the texture wasn't loaded... :) – Wilt Mar 09 '16 at 15:51
  • Apparently now from the `localhost` I don't get anymore errors in the `console` with this code: `var loader = new THREE.TextureLoader(); var texture = loader.load('https://imgur.com/gallery/eoWNz');`. But still, the background remains black. – d_z90 Mar 09 '16 at 16:12
  • Did you follow [the documentation](http://threejs.org/docs/#Reference/Loaders/TextureLoader)? I don't see a `onLoad` callback in your comment. The second argument should be a callback. In the callback you should add the texture to the background... – Wilt Mar 09 '16 at 16:15
  • Now I did, but I still get the same problem. I should get a `console.log('Error')` but nothing happens. That's weird – d_z90 Mar 09 '16 at 16:27

2 Answers2

1

There were several issues that I ran into. Most importantly you used this url for the image:

https://i.stack.imgur.com/HEJtH.jpg

But that link points to a web page.
The actual image is located on this url:

https://i.stack.imgur.com/V1527.jpg

To allow cross origin you have to set the crossOrigin property on the loader to true:

var loader = new THREE.TextureLoader();
loader.crossOrigin = true;

And you had two scenes I am not sure why, I removed one.

Here a working fiddle with the end result.

Wilt
  • 41,477
  • 12
  • 152
  • 203
  • Thanks a ton man! Well the idea of the two scenes because I wanted to create something like this: https://activetheory.net/. Just one thing: do you know why the background does not cover the whole window and is in front of the cube? – d_z90 Mar 09 '16 at 17:48
  • 1
    @d_z90 Its in front because you set `backgroundMesh.material.depthTest = false;` and `backgroundMesh.material.depthWrite = false;`. I don't know why you did that. You loaded it on a `PlaneGeometry` with size 2 x 2 so it is only 2 x 2 in size... If you want to load it as background you shouldn't load it on a geometry... – Wilt Mar 09 '16 at 17:50
  • Thanks a lot man! I struggled on this issue for two hours :) What do you suggest to do then. Because I saw that is the only way to set the background of the scene as a custom image.. – d_z90 Mar 09 '16 at 17:55
  • @d_z90 I added another answer with an alternative solution – Wilt Mar 10 '16 at 08:11
1

To set a static background for your canvas you can simply set background-image in css for your body or your container. It is important to set your renderer to transparent for this to work (otherwise the background of the renderer is covering your background image). To do this set the renderer alpha to true:

// Create renderer and set alpha to true
renderer = new THREE.WebGLRenderer({
    alpha: true
});

And then the following css will do the job:

div#container {
  position: relative;
  height: 100%;
  width: 100%;
  background-image: url("https://i.imgur.com/eoWNz.jpg");

  /* some additional styling to center it nicely */
  background-repeat: no-repeat;
  background-position: center;
  position: fixed;
  -webkit-background-size: cover;
  -moz-background-size: cover;
  -o-background-size: cover;
  background-size: cover !important;
}

Demonstrated here in this fiddle.

Wilt
  • 41,477
  • 12
  • 152
  • 203
  • Cool! This is a possible alternative. I am just afraid that I will have issues with the window resizing. But on the other side, I just need to render once the texture on a flat dimension, tessellate it, and explode + re-compact it on mouse hover. I will give it a shot ;) Thanks a ton @Wilt! – d_z90 Mar 10 '16 at 08:48