Load a texture to a glTF through a canvas using Threejs - three.js

I am currently working on a project where I am trying to replace the texture of a 3D model with an image from a canvas that has the original texture and with same resolution. I have been able to successfully load the image from the canvas and apply it to the model's material, but the texture is appearing distorted and stretched.
Original glTF before using the canvas image as the texture
After using the canvas image as the model's texture
Currently this is the code I am using to load the image from the canvas to the glTF:
this.button.addEventListener("click", () => {
var image = new Image();
image.src = this.canvas.toDataURL();
image.onload = function()
{
var texture = new THREE.Texture(image);
texture.encoding = THREE.sRGBEncoding;
material.map = texture;
texture.needsUpdate = true;
}
});
I am wondering if anyone has any experience with this issue and can offer any suggestions or solutions. Any help would be greatly appreciated.
Thank you.

Related

ThreeJs add Texture to a GLTF object surface

I am trying to apply an image dynamically on a gltf loaded mesh.
The code to load the model looks like:
const gltfLoader = new GLTFLoader();
const url = 'resources/models/mesh.gltf';
gltfLoader.load(url, (gltf) => {
const root = gltf.scene;
scene.add(root);
})
When looking from top the element looks like a rounded rect:
When inspecting the imported mesh I can see that the BufferGeometry has a count of 18.000 points:
Everything works fine however if I apply the texture like this:
const texture = new THREE.TextureLoader().load( 'textures/land_ocean_ice_cloud_2048.jpg' );
const material = new THREE.MeshBasicMaterial( { map: texture } );
root.children[0].material = material;
The image is not visible but the mesh is now colored in 1 color.
Is it possible to apply the image just on the top face of the rect?
Hard to tell what the problem is without seeing the resulting image. However, I would just assign a new texture like this: root.children[0].material.map = texture instead of creating a whole new material, since you don't want to lose all the material attributes that came in the GLTF.
Additionally, MeshBasicMaterial always looks flat because it is not affected by lights.

Three.js adding texture gives complete object color of 1 pixel

I have this texture of 20x20pixels and and object from a collada 1.4.1 model.
So I want to give this object this new texture for testing
I do the following
var loader = new THREE.TextureLoader();
loader.load("/assets/images/texture2/TextureResource129.png", texture => {
var material = new THREE.MeshLambertMaterial({
map: texture
});
node.material = material;
material.needsUpdate = true;
});
Now what happens is that the object is in 1 color
How can I change the texture so it is just as the texture?
Instead of creating a new material that behaves differently than the one that comes in your Collada import, just change the texture of the existing material. Do this inside your texture loader callback:
node.material.uniforms.MatDiff2.value = texture;
That way you just change the texture input to the existing material.

Regarding image texture loading in three js

I want to load an image on to a plane.But I am having a problem in loading.So,here I am getting the image like this.
var texture = new THREE.ImageUtils.loadTexture('Silk.png');
var Silk = new THREE.Mesh(new THREE.PlaneBufferGeometry(15,15),new THREE.MeshPhongMaterial({map:texture,color:'skyblue'}));
scene.add(Silk);
Silk.position.z = -2;
And This is the result
I want only the image not the background
How can I do that?

Mesh with texture background color

I create a Mesh having a PlaneGeometry and the material defined by a texture loaded from a JPEG image. Everything is fine, excepting that there is a small amount of time before the texture image is loaded when the plane is displayed using a dark color. Is there a way to change this color to something else?
I tried the color option for material, but it is not applied.
var texture = new THREE.ImageUtils.loadTexture('/path/to/image');
texture.minFilter = THREE.LinearMipMapLinearFilter;
texture.magFilter = THREE.NearestFilter;
var material = new THREE.MeshBasicMaterial({
side : THREE.DoubleSide,
map : texture,
color : 0xf0f0f0
// this doesn't seem to work
});
var geometry = new THREE.PlaneGeometry(Math.abs(line.x1 - line.x0), depth);
var mesh = new THREE.Mesh(geometry, material);
That black color is the texture rendering without any texture data. The easiest fix is to load the texture and the mesh, but do not render the mesh until both have fully loaded.
Another option is to create a very small 1x1 texture that is the color you want, use that as your texture initially, and then change the mesh material to your final texture once the desired texture has fully loaded.

How to load textures from OBJ+MTL files in three.js?

I have a Maya file exported to OBJ and MTL. I can see the OBJ texture successfully, but how do I actually get the texture in? I looked at the "three.js" format in blender, which appears to be shape only, no texture.
This three.js example appears to load in the obj fine for the shape, but the texture appears to come from a jpg image and not an mtl:
loader.load('textures/ash_uvgrid01.jpg', function(image) {
texture.image = image;
texture.needsUpdate = true;
});
My question is, how do I get this "uvgrid01.jpg" image for my model? Is there some way to convert MTL to this .jpg format for the texture only? Or is there some other way I should be exporting the texture to be able to load it in?
You can use OBJLoader and MTLLoader, as seen in this example (at least three.js r77):
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath('obj/male02/');
mtlLoader.load('male02_dds.mtl', function(materials) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath('obj/male02/');
objLoader.load('male02.obj', function(object) {
object.position.y = -95;
scene.add(object);
}, onProgress, onError);
});

Resources