Three js texture is not aligned with UV - three.js

I am trying to apply texture to exported from blender model with unwraped UV, however the texture is not mapped corretly.
I have exported a UV layot from blender and marked one island in red to check the texture offset
gltfLoader.load('v3.glb',
(file) => {
bowtie_Mesh = file.scene.children.find((child) => child.name === 'bowtie003');
bowtie_Mesh.material = new THREE.MeshBasicMaterial({
map: new THREE.TextureLoader().load('uv 2.png')
})
scene.add(bowtie_Mesh)
});

The problem was in flipped Y axis. Adding texture.flipY = false solves the problem
const uvTex = new THREE.TextureLoader().load('uv 2.png')
uvTex.encoding = THREE.sRGBEncoding;
uvTex.flipY = false;
gltfLoader.load('v3.glb',
(file) => {
bowtie_Mesh = file.scene.children.find((child) => child.name === 'bowtie003');
bowtie_Mesh.material = new THREE.MeshBasicMaterial({
map: uvTex
})
scene.add(bowtie_Mesh)
});

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;

Json 3D model only using 1 pixel of a texture

I'm having this weird issue, my 3D object is only taking 1 pixel (bottom left) of my texture, this is how i'm loading the object
loaderFrame.load('./models/filterFrame/filterFrame.json',(geometry) =>
{
const mat = new THREE.MeshBasicMaterial({
map: new THREE.TextureLoader().load('./models/filterFrame/textura_polar.jpeg'),
transparent: true,
morphTargets: true
});
mat.transparent = true;
// mat.morphTargets = true;
frameMesh = new THREE.Mesh(geometry, mat);
frameMesh.scale.multiplyScalar(frameOptions.frameScale);
frameMesh.frustumCulled = false;
frameMesh.transparent = true;
frameMesh.renderOrder = 0;
}
);
This is because your loaded object doesn't have proper UV mapping. If UVs are nonexistent, or if they're all 0, 0, then it's only going to sample from the bottom-left corner of your texture.
To fix this, open your model in a 3D editor and make sure the UVs are properly positioned across the texture plane. I don't know what your model looks like, but here's a basic example:

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 texture is not showing up

I am trying to apply a texture to my 3D model with Three JS.
I tried a lot of ways from the Three JS Examples but for any reasons nothing is working.
Here is how I apply the texture to my model:
//LOADING TEXTURE
var textureLoader = new THREE.TextureLoader();
var diffuse = textureLoader.load( "models/Carbon.png" );
diffuse.encoding = THREE.sRGBEncoding;
diffuse.wrapS = THREE.RepeatWrapping;
diffuse.wrapT = THREE.RepeatWrapping;
diffuse.repeat.x = 1;
diffuse.repeat.y = 1;
var normalMap = textureLoader.load( "models/Carbon_Normal.png" );
normalMap.wrapS = THREE.RepeatWrapping;
normalMap.wrapT = THREE.RepeatWrapping;
var material = new THREE.MeshPhysicalMaterial({
roughness: 0.5,
clearcoat: 1.0,
clearcoatRoughness: 0.1,
map: diffuse,
normalMap: normalMap
});
// LOADING MODEL
var loader = new THREE.GLTFLoader();
loader.load("models/stairs.gltf", function(gltf){
model = gltf.scene
model.traverse((newModel) => {
if (newModel.isMesh){
newModel.material = material;
newModel.castShadow = true;
newModel.receiveShadow = true;
}
});
scene.add(model);
});
I appreciate any help!
When loading a texture for a glTF model, you have to set Texture.flipY to false to satisfy the uv convention of glTF.
diffuse.flipY = false;
normalMap.flipY = false;
Besides, you always have to ensure that your model has texture coordinates. You can do this by checking if the geometries of your meshes have an uv attribute. If this attribute is missing, I suggest you generate texture coordinates in a DCC tool like Blender.
three.js R112

Three.js r72 - Texture marked for update but image is undefined?

Three.js r72
I'm trying to use the same texture with different offsets and repeats, but after I clone the texture and apply needsUpdate I keep getting an error "Texture marked for update but image is undefined". I check the cloned texture and the image property is undefined. Shouldn't the clone method have referenced the source image from the texture in the textures Object.
var textures = {}
var materials = {}
textures.skin = THREE.ImageUtils.loadTexture('skin.png');
textures.skin.minFilter = THREE.NearestFilter;
textures.skin.magFilter = THREE.NearestFilter;
skin.map_data.forEach(function(item) {
var mats = []
item.maps.forEach(function(item) {
var tex = textures.skin.clone();
tex.needsUpdate = true;
tex.offset.x = ((1 / skin.width) * item.offset_x)
tex.offset.y = ((1 / skin.height) * item.offset_y)
tex.repeat.x = ((1 / skin.width) * item.width);
tex.repeat.y = ((1 / skin.height) * item.height);
var mat = new THREE.MeshBasicMaterial({
map: tex
});
mats.push(mat);
})
materials[item.name] = new THREE.MeshFaceMaterial(mats)
})
Texture loading is asynchronous. You need to put the bulk of your code in the loader callback.
texture = THREE.ImageUtils.loadTexture( 'filename.jpg', undefined, function() {
// the rest of your code here...
var tex = texture.clone();
tex.needsUpdate = true;
}
See how it is done in http://threejs.org/examples/misc_ubiquity_test2.html.
three.js r.72

Resources