Updated textures stops animation in three.js - animation

Moving on from yesterday. I'm swapping out a texture on a .GLTF on page refresh. The texture now works fine and dandy...
But only on files that have no animation. The texture update however, seems to stop them in their literal tracks. I've not sure what's causing it or how to reload the animations.
Here's the code:
var creaturePath = "models/gltf/creature/";
var creatureFile = "creature_roar.gltf";
// load the model
var loader = new GLTFLoader().setPath( creaturePath ); // creature
loader.load( creatureFile, function ( gltf )
{
gltf.scene.traverse( function ( child )
{
if ( child.isMesh )
{
// override textures
texture.flipX = false;
texture.flipY = false;
my_material = new THREE.MeshBasicMaterial({map: texture});
// child.material = my_material; // this is the problem line
texture.needsUpdate = true;
}
} );
var model = gltf.scene;

If you replace the material, you have to ensure to set MeshBasicMaterial.skinning and/or MeshBasicMaterial.morphTargets to true. Otherwise skeletal and/or morph target animation won't be supported by the material.
three.js R113

Related

THREEJS - GLB Import & Mapping Image Texture

I'm trying to map an Image onto my GLB import, however the GLB is just showing up as black. Not really sure where I'm going wrong here.
let textureLoader= new THREE.TextureLoader();
let texture = textureLoader.load("images/pexels-luis-quintero-2471234.jpeg");
texture.flipY = true;
gltfLoader.load( file.path, (gltf) => {
gltf.scene.traverse( (child, key) => {
if(child.isMesh){
child.material = new THREE.MeshBasicMaterial();
let material = new THREE.SpriteMaterial( { map: texture } );
let sprite = new THREE.Sprite( material );
child.material.map = sprite;
}
});
** Added the texture to :-
child.material.map = texture
However the image does not fit to the dimensions of the GLB
An instance of THREE.Sprite is a 3D object similar to THREE.Mesh. You can't assign a sprite to the map property of a material. Do this:
child.material = new THREE.MeshBasicMaterial();
child.material.map = texture;
Besides, if you add a manually loaded color texture to a glTF asset, make sure to add:
texture.encoding = THREE.sRGBEncoding;

GLTF model is too dark

Trying to load this model of a car into my scene, here is how it looks in the glTF Viewer:
I followed that example. With this updated loading method, the model is still dark, and if I try to scale or position it, it completely disappears.
Here is how it's loaded:
const loader = new THREE.GLTFLoader();
const roughnessMipmapper = new RoughnessMipmapper( renderer );
loader.load( 'models/car_datsun/scene.gltf', function ( gltf ) {
gltf.scene.traverse( function (child) {
if (child.isMesh) {
roughnessMipmapper.generateMipmaps(child.material);
}
child.scale.set(0.5,0.5,0.5); //must comment this line out to appear
child.position.y += 10; //must comment this line out to appear
child.position.z += 20; //must comment this line out to appear
});
scene.add(gltf.scene);
}, undefined, function ( error ) {
console.error(error);
});
roughnessMipmapper.dispose();
I also have a light, which is meant to simulate the sun:
const light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.set(500,200,500); //looking at 0,0,0
scene.add(light);
Renderer is set to use sRGB:
renderer.outputEncoding = THREE.sRGBEncoding;

Update texture with three.js

I've got a textured model in three.js and I want to be able to swap out the texture defined in the .gltf file when the page loads. I've looked here for inspiration.
"images": [
{
"uri": "flat_baseColor.png"
},
// etc
So to update the texture I do
var images = [
"./textures/01.jpg",
// "./textures/01.jpg",
];
var texture = new THREE.TextureLoader().load( images[0] );
var my_material = new THREE.MeshBasicMaterial({map: texture});
// load the model
var loader = new GLTFLoader().setPath( 'models/gltf/' ); // trex
loader.load( 'creature_posed.gltf', function ( gltf )
{
gltf.scene.traverse( function ( child )
{
if ( child.isMesh )
{
// The textures go for a double flip, I have no idea why
// Texture compensation
texture.flipX = false;
texture.flipY = false;
child.material = my_material;
texture.needsUpdate = true;
}
} );
var model = gltf.scene;
Only the texture is considerably pale. :(
I've tested it against itself, so it's not the texture). What have a missed out?
When loading textures you'll need to pay attention to colorspace: if the texture has color data (like .map or .emissiveMap) it's probably sRGB.
texture.encoding = THREE.sRGBEncoding;
See GLTFLoader docs and color management in three.js. This assumes that renderer.outputEncoding = THREE.sRGBEncoding as well.
three.js r113

Three.js - Can we intersect with material ID of a model using raycaster?

I'have been trying to intersect only one material among 3 materials of the loaded model onclick using their ID's, however, the control continues to the entire model. Let me know if it is possible to intersec on basis of material ID's
var intersects = raycaster.intersectObjects( scene.children );
for ( var i = 0; i < intersects.length; i++ ) {
object.scene.traverse(function(child) {
if ( child instanceof THREE.Mesh ) {
if (child.material.name == "heap") {
child.material.color = new THREE.Color( 0x00ff00 );
}
}
})
}
You can update the material of a raycast object by means of accessing the material property on the object of an intersection result.
Something to keep in mind is that, when you do update the properties of a material object, you need to set needsUpdate = true so threejs knows that the material needs updating internally.
Consider the following code that achieves what you're after:
// If only interested in one intersection, you can use .intersectObject()
var intersection = raycaster.intersectObject( scene.children );
// If intersection found, update material in some way
if(intersection) {
// Extract object and material from intersection
var object = intersection.object;
var material = object.material;
/*
Manipulate your material as you need to
material.color = new THREE.Color( 1, 0, 0 );
*/
// Tell threejs that the material was changed and
// needs to be updated internally
material.needsUpdate = true;
}

Threejs: Terrain texture happens invisible/transparent

Three.js r62
I have a scene from .obj file with a few meshes.
https://dl.dropboxusercontent.com/u/8913924/terrain/index.html
I try to apply a texture to the "terrain" object.
Result is an invisible/transparent texture.
(if a texture applied to any other objects in the scene - everything seems ok)
check the demo above.
Notes:
.mtl file is empty;
Upload a texture and apply the one to all the objects of the scene:
/* prepare the texture */
var texture = THREE.ImageUtils.loadTexture( 'crate.gif' );
texture.needsUpdate = true;
Apply this texture to terrain and all other objects:
if ( ('string' == typeof o.type) && ( 'terrain' == o.type)){
/*work with terrain*/
//object.children[i].material = object.children[i].material.clone();
object.children[i] = new THREE.Mesh (object.children[i].geometry.clone(), object.children[i].material.clone());
object.children[i].material.color.setHex(0xffffff);
object.children[i].material.map = texture;
object.children[i].material.ownMaterial = true;
//console.log('terrain colored');
} else {
/*work with all other objects*/
object.children[i].material = object.children[i].material.clone();
object.children[i].material.ownMaterial = true;
object.children[i].material.map = texture;
}

Resources