I'm trying to update the image asset on a geometry after user interaction, basically loading low res assets to begin with and swapping to high res assets when the user interacts with it.
If I just use standard code like below:
var materials = [
new THREE.MeshPhongMaterial({ map:loader.load('assets/object/0.jpg' ) }),
new THREE.MeshPhongMaterial({ map:loader.load('assets/object/1.jpg' ) }),
new THREE.MeshPhongMaterial({ map:loader.load('assets/object/2.jpg' ) }),
new THREE.MeshPhongMaterial({ map:loader.load('assets/object/3.jpg' ) }),
new THREE.MeshPhongMaterial({ map:loader.load('assets/object/4.jpg' ) }),
new THREE.MeshPhongMaterial({ map:loader.load('assets/object/5.jpg' ) }),
];
target.material.map.needsUpdate = true;
var texture = new THREE.MeshFaceMaterial( materials );
target.material = texture;
The low res assets are cleared from the geometry showing the base colour, the high-res assets take a second to load and then appear on the geometry.
I need to load the assets and then swap them, and from some reading it seems like THREE.LoadingManager() is the way to go, however I'm a bit lost.
So far this is what I have but it's throwing errors....
var textureManager = new THREE.LoadingManager();
textureManager.onProgress = function ( item, loaded, total ) {
console.log(item+' = '+loaded / total * 100) + '%';
};
textureManager.onLoad = function () {
console.log(' loading complete');
var materials = [
new THREE.MeshPhongMaterial({ map:myTextureArray[0] }),
new THREE.MeshPhongMaterial({ map:myTextureArray[1] }),
new THREE.MeshPhongMaterial({ map:myTextureArray[2] }),
new THREE.MeshPhongMaterial({ map:myTextureArray[3] }),
new THREE.MeshPhongMaterial({ map:myTextureArray[4] }),
new THREE.MeshPhongMaterial({ map:myTextureArray[5] })
];
target.children[i].material.materials.map.needsUpdate = true;
var texture = new THREE.MeshFaceMaterial( materials );
target.children[i].material = texture;
};
var textureLoader = new THREE.ImageLoader( textureManager );
myTextureArray = [];
var myTexture = new THREE.Texture();
myTextureArray.push( textureLoader.load( 'assets/objtect1/hires/0.jpg', function ( image ) { myTexture.image = image; } ) );
myTextureArray.push( textureLoader.load( 'assets/objtect1/hires/1.jpg', function ( image ) { myTexture.image = image; } ) );
myTextureArray.push( textureLoader.load( 'assets/objtect1/hires/2.jpg', function ( image ) { myTexture.image = image; } ) );
myTextureArray.push( textureLoader.load( 'assets/objtect1/hires/3.jpg', function ( image ) { myTexture.image = image; } ) );
myTextureArray.push( textureLoader.load( 'assets/objtect1/hires/4.jpg', function ( image ) { myTexture.image = image; } ) );
myTextureArray.push( textureLoader.load( 'assets/objtect1/hires/5.jpg', function ( image ) { myTexture.image = image; } ) );
Any ideas where I might be going wrong?
For the benefit of anyone else, the problem was that I was using the ImageLoader, not TextureLoader.
Replace:
var textureLoader = new THREE.ImageLoader( textureManager );
With
var textureLoader = new THREE.TextureLoader( textureManager );
Related
Ok I have an fbx successfully loaded into Three.js exported from blender with all animation boxes checked. Ive tried all export settings from blender so that's not it.
This is how I bring the model in, and I am able to accurately determine whether the fbx has animations or not:
var geoFromScene = new THREE.Geometry();
var FBXLoader = require('three-fbx-loader');
var loader = new FBXLoader();
loader.load(string, function ( object ) {
object.traverse( function ( child ) {
if ( child.isMesh ) {
child.castShadow = true;
child.receiveShadow = true;
geoFromScene = (new THREE.Geometry()).fromBufferGeometry(child.geometry);
}
} );
var theModel = new THREE.Mesh();
theModel.geometry = geoFromScene;
theModel.material = material;
theModel.position.set(5,5,-8);
//theModel.rotation.set(new THREE.Vector3( 0, MATH.pi/2, 0));
theModel.scale.set(0.1, 0.1, 0.1);
localThis.scene.add(theModel);
localThis.mixer = new THREE.AnimationMixer(theModel);
if(theModel.animations[0])
{
var action = localThis.mixer.clipAction(theModel.animations[0]);
action.play();
} else {
console.log("No animations");
}
} );
In update (which does work, because I can print the animation.time):
this.mixer.update(this.clock.getDelta());
And yet the model is just static. Whats wrong here?
UPDATE:
code from example copy pasted-
var geoFromScene = new THREE.Geometry();
var FBXLoader = require('three-fbx-loader');
var loader = new FBXLoader();
loader.load( string, function ( object ) {
localThis.mixer = new THREE.AnimationMixer( object );
var action = localThis.mixer.clipAction( object.animations[ 0 ] );
action.play();
object.traverse( function ( child ) {
if ( child.isMesh ) {
child.castShadow = true;
child.receiveShadow = true;
}
} );
object.position.set(5,5,-8)
object.scale.set(0.1, 0.1, 0.1);
localThis.scene.add( object );
} );
in animate-
this.mixer.update(this.clock.getDelta());
All I get is the model armature it seems -
New approach:
var FBXLoader = require('wge-three-fbx-loader'); //https://www.npmjs.com/package/wge-three-fbx-loader
var loader = new FBXLoader();
loader.load( string, function ( object ) {
I plan to add equirectangular (or spherical) panorama support on top of existing 6 cube panorama. I found this library that easily does it by converting equirectangular image to 6 cubes:
https://github.com/spite/THREE.EquirectangularToCubemap
where we can simply use equiToCube.convert( texture, 1024 ):
renderer = new THREE.WebGLRenderer();
var loader = new THREE.TextureLoader();
loader.load( 'equirectangular-panorama.jpg', function( res ) {
var equiToCube = new EquirectangularToCubemap( renderer );
mesh = new THREE.Mesh(
new THREE.TorusKnotGeometry( 10, 3, 100, 32 ),
new THREE.MeshBasicMaterial( { envMap: equiToCube.convert( res, 1024 ) } )
);
scene.add( mesh );
} );
Seems simple. However, my 6 cube method to load images looks like this:
function getTextureCube(path, step, total){
var urls = ["1.jpg","2.jpg","3.jpg","4.jpg","5.jpg","6.jpg"];
var loader = new THREE.CubeTextureLoader();
var maxAnisotropy = renderer.getMaxAnisotropy();
var textureCube = loader.load(urls, function(texture){
texture.minFilter = THREE.NearestFilter;
texture.anisotropy = maxAnisotropy;
texture.wrapS = THREE.RepeatWrapping;
texture.repeat.x = -1;
}, function ( xhr ) {
log( (xhr.loaded / xhr.total * 100) + '% loaded' );
}, function ( xhr ) {
log( 'error loading texture', xhr );
});
return textureCube;
}
And I cannot successfully utilize equiToCube.convert( texture, 1024 ) for conversion which results in black screen instead of panorama.
function getEquirectangularTextureCube(path, step, total){
var loader = new THREE.TextureLoader(); // Note TextureLoader
var maxAnisotropy = renderer.getMaxAnisotropy();
var equiToCube = new EquirectangularToCubemap( renderer );
var textureCube = loader.load(path, function(texture){
texture.minFilter = THREE.NearestFilter;
texture.anisotropy = maxAnisotropy;
texture.wrapS = THREE.RepeatWrapping;
texture.repeat.x = -1;
}, function ( xhr ) {
log( (xhr.loaded / xhr.total * 100) + '% loaded' );
}, function ( xhr ) {
log( 'error loading texture', xhr );
});
return equiToCube.convert( textureCube, 2048 ); // Note .convert
}
A few thoughts to help: this returned texture is used in fragment shader and uniforms if that helps with answer. Also, I may be using equiToCube incorrectly - I did using it inside loader.load but unsuccessfully.
Any ideas how to integrate equirectangular (or spherical) panorama support will be appreciated.
How to multiple textures material use in Three.js?.Here three textures using and one 3D sofa.obj format file. I tried a lot of time. Below my code. What do I mistake in my code?
var loader = new THREE.OBJLoader();
var textureLoader = new THREE.TextureLoader();
threeDTexture = new THREE.ImageUtils.loadTexture( 'models/Sofa/Texturses/paradis_beige.jpg' );
threeDTexture2 = new THREE.ImageUtils.loadTexture( 'models/Sofa/Texturses/1.jpg' );
threeDTexture3 = new THREE.ImageUtils.loadTexture( 'models/Sofa/Texturses/2.jpg' );
loader.load('models/Sofa/sofa.obj', function (object) {
var geo = object.children[0].geometry;
var mats = [threeDTexture, threeDTexture2,threeDTexture3];
objct = new THREE.Mesh(geo, mats);
object.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material = objct;
}
});
object.position.x = posX;
object.position.y = 0;
object.position.z = posZ;
var size = new THREE.Box3().setFromObject(object).getSize();
object.scale.set(width/size.x, height/size.y, depth/size.z);
scene1.add(object);
console.log(object);
console.log(size);
console.log(width/size.x, height/size.y, depth/size.z);
},
function ( xhr ) {
returnValue = ( xhr.loaded / xhr.total * 100 ) + '% loaded';
console.log(returnValue);
},
function ( error ) {
console.log( 'An error happened' );
}
);
break
first, the textureLoader declared on line-2 is not in use;
second, belowing mats is not an Material Array, you should new MeshBasicMaterial(...) to wrap a texture, see the document here.
var mats = [threeDTexture, threeDTexture2,threeDTexture3];
objct = new THREE.Mesh(geo, mats); // Mesh will not accept this mats param!
I have collada model (.dae) displayed by this code, and I add THREE.DoubleSide but it dose not work how can i fix this?
var loadingManager = new THREE.LoadingManager( function() {
scene.add( car );
} );
var loader = new THREE.ColladaLoader( loadingManager );
var textureLoader = new THREE.TextureLoader();
var texture = textureLoader.load('./model/car_Red.jpg');
loader.options.convertUpAxis = true;
loader.load( './car.dae', function ( collada ) {
car = collada.scene;
car.traverse(function (node) {
if (node.isMesh)
{
node.material.map = texture;
node.material.side = THREE.DoubleSide;
}
});
console.log(car);
I am trying to add to texture to my central sphere (the earth) but when I try the object disappears. Can I have some guide to where I am going wrong. Thanks
Here is the link to my jsbin http://jsbin.com/cabape/edit?html,output . I am going to get the moon to rotate around the earth
//earth
var loader = new THREE.TextureLoader();
loader.load( 'http://simpletruthsforhealthyliving.com/js/earth.jpg', function ( texture ) {
var center = new THREE.SphereGeometry(20,20,20);
var materialShereCenter = new THREE.MeshPhongMaterial( { ambient: 0xee0011, color:0xff0000, specular: 0xee0000, shininess: 70,wireframe: false, map: texture } );
centralSphere = new THREE.Mesh(center, materialShereCenter);
centralSphere.position.z = 0;
centralSphere.position.x = 0;
centralSphere.position.y = 0;
scene.add(centralSphere);
});
This needed to be added as well
var texture = new THREE.Texture();
var loader = new THREE.ImageLoader();
loader.addEventListener( 'load', function ( event ) {
Texture1.image = event.content;
Texture1.needsUpdate = true;
} );
loader.load( 'http://simpletruthsforhealthyliving.com/js/earth.jpg' );