I load a GLTF 2.0 (.GLB) file with embedded textures in Three.js scene. I have 2
elements in which I want to show the texture as image. Right now the approach I use is very slow and freezes my browser. This is code that I use to extract image from material’s texture
// Convert material to JSON
var jData = material.toJSON();
var images = jData.images;
var textures = jData.textures;
const maps = [
"map", // Diffuse
"normalMap", // Normal
"aoMap", // Ambient Occlusion
"roughnessMap", // Roughness
"metalnessMap", // Metalness
"envMap", // Environment Map
];
let map = jData[maps[m]];
// MAP -> TEXTURE
let textureData = textures.find((i) => {
return i.uuid === map;
});
// TEXTURE -> IMAGE
let imageData = images.find((i) => {
return i.uuid === textureData.image;
});
// set <img> element's src to base64 data
img.src = imageData.url;
How do you extract the Image file or reuse the already existing image in memory with
, efficiently ?
Im not sure what you’re doing there. Why do you convert it to JSON? The images of textures from a gltf are already valid img images, actually their original binary format and not a blown up base64 string.
If I get the Material.map.image.src value and set my
element’s src attribute in HTML DOM. The image is not rendered.
The value is something like this blob:http://localhost:3000/de58c09d-21b4-4836-92fb-0a73ce0c9b85
But this does not render image in HTML UI
The issue is the GLTF loader calls URL.revokeObjectURL()
after it has been loaded, so the URL is no longer available to load the file from. What you could do is either using the original img element and insert it to the dom ( i don’t know what you want to do with it) or draw the image to a canvas, create a blob (png or jpg) and a url from it to load it like the gltf loader did.
I’ll try this and see if this works. Adding original
element seems straightforward approach.
I am building a GLTF model editor for my personal project and need to display texture maps for a material with
element
I create thumbnails for this case, but if you use the original then using the dom element will be a better option than cloning the image, you could also do with texture.data.cloneNode() if you don’t need access to the content.
texture.data.cloneNode()
you mean texture.clone() ? or is it something different.
For thumbnail purpose, how do you suggest I proceed?
The data property holds the img element of the embeded textures, cloneNode clones the dom element like your attempt to assign the url to the new elements src property, it should work with revoked blob urls too since it’s the image in memory.
Thanks, solved it.
here’s code for others who encounter similar situation
var c = $('#mycanvas').get(0);
var ctx = c.getContext('2d');
// draw image fit to canvas
ctx.drawImage(material.texture.image, 0, 0, material.texture.image.width, material.texture.image.height, 0, 0, c.width, c.height);