0
votes

I have a problem with three.js in combination with tween.js. The problem is, that the timer of a tween.js animation starts, before the texture of a sphere is displayed.

I'm building a panorama viewer with three.js for Firefox. The panorama images are mapped to a sphere and the camera is in its center. It is possible to change the displayed panorama to virtually visit different rooms (this is done by turning different spheres with different textures visible). When the room is changed, a light is animated with tween.js to turn the room dark. Then the light goes up again and the new panorama image is displayed.

The problem is, that it needs some time to display the image, if a room is visited for the first time. That happens because the image is not loaded into memory before it is displayed.

That wouldn't be bad if the room remained dark until the panorama is completely loaded into memory and ready to display. But the animation timer of tween.js starts before the image is displayed.

The result is, that the light is not turning on slowly by animation, as desired, instead it takes a short time to display the new panorama and then the light is completely turned on without any animation at all. The duration of the animation is set to 500 ms and it takes roughly the same amount of time to display the panorama image.

My question is, is there a way to know, when a texture is rendered? So that I can trigger the animation when the image is displayed?

Three.js version is r71.

//after light turns dark, the panorama is changed and light goes up again
tweenDarkenLight.onComplete( function() { 

  roomModule.setRoomVisible(); //sets new room visible

  tweenEnhanceLight.start(); //start of animation to enlighten the scene
});

The textures for all rooms/panoramas are loaded and attached to spheres when the app starts. But each of them remains invisble until the user selects one of them.

texture = new THREE.Texture();

loader = new THREE.ImageLoader( manager );

//the url for each panorama is stored in roomAssetArray
loader.load( roomAssetArray.panorama, 

  function ( image ) {

  texture.image = image;
  texture.needsUpdate = true;
});
1
Can you provide a jsfiddle please, or at the very least share the section of code where you are loading this texture. It's also helpful to mention the version of three.js which you are using. - Leeft

1 Answers

1
votes

You need to tie together your room visibility code with your tween.start() code.

I assume somewhere in your code you call loadTexture(). The third argument of that is a callback which is called on successful loading of the texture. So I would do something to the effect of:

texture = THREE.ImageUtils.loadTexture( "room.jpg", {}, function() {
    // room texture has been loaded

    // do the tween
}

Update:

Another option would be to add a render call just before the tween or after the code that changes the visibility of the spheres. That way at least one pass through the textured geometry would be made.