Preload Textures and Images in ThreeJS? - javascript

i wanted to ask if there is a simple solution to preload Textures and Images in ThreeJs.
I load them all into an array: myTextureArray.push(new THREE.ImageUtils.loadTexture('../textures/floor_red.jpg');
How can i check if and when all Textures are loaded successfully ?
Here is an older Version Link: http://museum.baraq.de/
Thanks for help!

There is a Loading Manager in Three.js you can use to keep track of your loaded Textures or Objects.
Example implementation:
var textureManager = new THREE.LoadingManager();
textureManager.onProgress = function ( item, loaded, total ) {
// this gets called after any item has been loaded
};
textureManager.onLoad = function () {
// all textures are loaded
// ...
};
var textureLoader = new THREE.ImageLoader( textureManager );
var myTextureArray = [];
var myTexture = new THREE.Texture();
myTextureArray.push( myTexture );
textureLoader.load( 'my/texture.jpg', function ( image ) {
myTexture.image = image;
} );
Tested in Three.js r71.

Related

Three.js Texture Loader Disposes but Seems to Stay in Memory

I load multiple textures in my three.js app, which are equirectangular images. I try to follow three.js documentation to get a reference to each texture I load so I can dispose() it when not needed to free up memory. However, renderer.info.memory seems to continue showing disposed textures count as if it does not dispose my texture from memory.
Here is a simplified and shortened code from my app.
var allTextures=[
{path: a, textureRef: null, texture: null},
{path: b, textureRef: null, texture: null}
];
function loadTexture(textureObj){
var loader = new THREE.TextureLoader();
textureObj.textureRef = loader.load(textureObj.path, function(texture){
textureObj.texture = texture;
}, function ( xhr ) {}, function ( xhr ) {});
}
// load first texture
var t = allTextures[0]
loadTexture(t);
// dispose first texture
setTimeout(function () {
var _t = allTextures[0];
_t.textureRef.dispose();
_t.textureRef = null;
console.log(renderer.info.memory); // ex: {geometries: 15, textures: 20}
},5000);
As a result, my app works poorly on the mobile device refreshing the page when around 20 textures are being shown loaded in memory.
Am I correctly disposing the textures? What else can be verified to understand why textures are not offloaded?

How do we know the end of three js material changed process can be done?

How do we know the end of this process can be done?
material.map = new THREE.Texture( canvas );
material.map.needsUpdate = true;
Because if not then it is complete snapshot is sometime black result
var snapshotData = renderer.domElement.toDataURL(strMime);
What can be do successfully changed material callback?
Thank you :)
You can try putting it inside the onload funtion for checking if the texture is loaded or not
var textureLoader = new THREE.TextureLoader();
var texture = textureLoader.load(texturePath, function()
{
//the code below executes only after the texture is successfully loaded
mesh.material.map = texture;
mesh.needsUpdate = true;
//write the code to be executed after the texture is mapped
})
I hope this is helpful.

Three.js skybox not loading

I am completely new to Three.JS and cant seem to get my head around getting a skybox to appear in my scene. I'm not getting any errors from my code, which has left me stumped. Any help would be greatly appreciated.
function createSky(){
var imageList = "CubeMap"
THREE.ImageUtils.crossOrigin = '';
var faces = ["HDR0001",
"HDR0002",
"HDR0003",
"HDR0004",
"HDR0005"];
var imgType = ".jpg";
var skyGeo = new THREE.CubeGeometry (500, 500, 500);
var matFacesArray = [];
for (var i = 0; i < 6; i++) {
matFacesArray.push( new THREE.MeshBasicMaterial({
map: THREE.ImageUtils.loadTexture( imageList + faces[i] + imgType ),
side: THREE.BackSide
}));
}
var sky = new THREE.MeshFaceMaterial ( matFacesArray );
var skyBox = new THREE.Mesh ( skyGeo, sky );
scene.add ( skyBox );
}
Where are you watching your log for warnings/errors?
Seems strange you are not getting any feedback since THREE.ImageUtils.loadTexture is deprecated, use TextureLoader.load instead, this warning should show up if you are using a somewhat later version of three js.
Also, what browser are you using? I find that Firefox is usually a bit more generous with showing textures than Chrome for example. This has to do with cross-origin image load and can be a problem when you try to run your code locally.

How to check item is loaded in the scene in three.js?

I use THREE.js Loading Manager to check the object or texture is loaded .
var Mesh;
var TLoader = new THREE.TextureLoader(manager);
var manager = new THREE.LoadingManager();
manager.onProgress = function ( item, loaded, total ) {
console.log( item, loaded, total );
};
manager.onLoad = function()
{
console.log(Renderer.domElement.toDataURL());
}
function renderModel(path,texture) {
var Material = new THREE.MeshPhongMaterial({shading: THREE.SmoothShading});
Material.side = THREE.DoubleSide;
var Loader = new THREE.JSONLoader(manager);
Loader.load(path,function(geometry){
geometry.mergeVertices();
geometry.computeFaceNormals();
geometry.computeVertexNormals();
TLoader.load(texture,function(texture){
Mesh = new THREE.Mesh(geometry, Material);
Mesh.material.map =texture;
Scene.add(Mesh);
});
});
}
and i just call the renderModel function in a loop .
But the console.log(Renderer.domElement.toDataURL()) output from the manager.onload function is giving only image of the some 3d models not all the ones in the scene
I just want to get 'Renderer.domElement.toDataURL()' when all the 3d models are rendered in the scene
now only the image of 2 or 3 models are getting ,but in scene all the items are loaded.
The renderer renders an image each frame. When the loading of all the objects is completed, the onLoad method of the manager is called immediately. So, the last objects were added to the scene and you retrieve the image data without giving the renderer a chance to render a new image. You need to wait for a new frame. Maybe a timeout with e.g. 200 milliseconds will help.
EDIT
You could also call the render method in your onLoad, so the renderer draws a new image before you call console.log.
manager.onLoad = function()
{
Renderer.render( Scene, camera );
console.log(Renderer.domElement.toDataURL());
}

accessing texture after initial loading in pixi.js

I'm using the pixi.js render engine for my current project in javascript. I'm loading a spritesheet defined in json, using the assetloader. Problem is I need to create sprites or movieclips well after the onComplete event that the assetloader uses, finishes. However the texture cache seems to not be accessible after that point. Here is some of the code below demonstrating the problem I'm coming across.
var spriteSheet = [ "test.json" ];
loader = new PIXI.AssetLoader(spriteSheet); // only using the flappy bird sprite sheet as a test
loader.onComplete = OnAssetsLoaded;
loader.load();
function OnAssetsLoaded() {
var sprite = PIXI.Sprite.fromFrame("someFrame.png"); //this works
}
var sprite2 = PIXI.Sprite.fromFrame("someFrame2.png"); //This does not work, tells me "someFrame2" is not in the texture cache
The sprite sheet must be fully loaded before the images get stored in the cache. Once the Sprite sheet has loaded, those assets will exist in the cache until you delete them.
The reason your code above fails is because the line var sprite2... executes before the sprite sheet has finished loading.
This example will continuously add a new Sprite to the stage every second.
//build stage
var stage = new PIXI.Stage(0x66FF99);
var renderer = PIXI.autoDetectRenderer(400, 300);
document.body.appendChild(renderer.view);
//update renderer
requestAnimFrame( animate );
function animate() {
requestAnimFrame( animate );
renderer.render(stage);
}
//Flag will prevent Sprites from being created until the Sprite sheet is loaded.
var assetsReadyFlag = false;
//load sprite sheet
var loader = new PIXI.AssetLoader([ "test.json" ]);
loader.onComplete = function(){
assetsReadyFlag = true;
};
loader.load();
//Add a new bird every second
setInterval( addBird, 1000);
function addBird()
{
//assets must be loaded before creating sprites
if(!assetsReadyFlag) return;
//create Sprite
var bird = PIXI.Sprite.fromFrame("bird.png");
bird.anchor.x = bird.anchor.y = 0.5;
bird.x = Math.random() * stage.width;
bird.y = Math.random() * height;
stage.addChild(bird);
};

Categories