Three.js renders geometry wrongly - javascript

Three.js often renders unnecessary surfaces when loading .obj files (I haven't tried other types).
In the screenshot I attached below, there are some triangle surfaces that look like webbed fingers. How do I get rid of it?
I think the .obj file is okay because it's rendered correctly in Blender. It's exported from sketchup and it wasn't webbed before exporting.
View in Blender
View in Three.js
Below is the code I'm using to load .obj
const loadManager = new THREE.LoadingManager();
loadManager.addHandler(/\.dds$/i, new DDSLoader());
const loadObj = (path, mtl) => {
return new Promise((res) => {
new OBJLoader(loadManager).setMaterials(mtl).load(
path,
async (object) => {
scene.add(object);
render()
res(object)
},
() => {
console.log("loading .obj, started at", new Date());
},
() => {
console.log("loading .obj got error");
}
);
})
}
I have no clue to fix this problem. I'll appreciate any kind of opinion.
Thanks.

Related

convert dae to gltf, horizontal vector invalidation

I converted .dae to .gltf through this tool, and display through three.js, and found that the horizontal vector of the model seems to be invalid.
Example file
Convert tool interface:
The situation when I use .dae file to display:
let loaderDae = new ColladaLoader();
loaderDae.load(`assets/untitled.dae`, (dae: any) => {
this.buildingModel = dae.scene;
this.buildingModel.position.multiplyScalar(0);
this.scene.add(this.buildingModel);
});
The situation when I use .gltf file to display:
let loaderGLTF = new GLTFLoader();
loaderGLTF.load(`assets/untitled.glft`, (glft: any) => {
this.buildingModel = glft.scene;
this.buildingModel.position.multiplyScalar(0);
this.scene.add(this.buildingModel);
});
After zooming in(or out):
The gloss of the texture is also not the same. I don't know if it's a file conversion problem or a lighting problem. I am using ambientLight:
let ambColor = new THREE.Color('rgb(118, 240, 147');
this.ambientLight = new THREE.AmbientLight(ambColor);
this.ambientLight.name = 'testname';
this.scene.add(this.ambientLight)

Load gltfs from firebase

I have a gltf file which exist in firebase storage folders and related textures are also located in that folders. I want to load that object into my view. I using THREE js for do this.
I tried get download url of gltf file and pass it it GLTFLoader. But model was not loaded to view.
I tried with this :
const loader = new GLTFLoader()
loader.load(
url,
(gltf) => {
gltf.scene.traverse( ( child ) => {
if ( child instanceof THREE.Mesh ) {
console.log(child.material.metalness)
if(child.material.metalness){
child.material.envMap = texture;
}
}
} );
var parent = gltf.scene;
var box = new THREE.Box3().setFromObject(parent)
var center = box.getCenter(new THREE.Vector3())
var size = box.getSize(new THREE.Vector3())
var maxAxis = Math.max(size.x,size.y,size.z)
parent.scale.multiplyScalar(1/maxAxis)
box.setFromObject(parent);
box.getCenter(center)
box.getSize(size)
parent.position.copy(center).multiplyScalar(-1)
scene.add(gltf.scene)
},
(xhr) => {
console.log((xhr.loaded / xhr.total) * 100 + '% loaded')
},
(error) => {
console.log(error)
}
)
If I load this file from local device, it is works fine and model display in view(all textures are load properly).
If anyone can help me how to load gltf file from firebase storage
I believe you should use getDownloadURL() from firebase like any other file. check this out Firebase Cloud
May not be the best solution but if you save the file as a .glb (binary version of .gltf), then there is only one file with textures already wrapped up in it. If not, you will need to store all the gltf data in one folder and load the whole lot including textures.

threejs import GLTF: why does the model show differently?

I'm new to threejs. I Exported a model in GLTF from Blender and imported to threejs(v93).
But the rendering effect in threejs is quite different with the one in blender.
How can I fix it?
the threejs code is:
const loader = new THREE.GLTFLoader();
loader.load(url,function(gltf){
let model = gltf.scene;
model.scale.set(3.5,3.5,3.5);
model.traverse(function(child){
if(child.isMesh){
child.material.emissive = child.material.color;
child.material.emissiveMap = child.material.map;
}
})
model.name = 'truck';
scene.add(model);
})
difference between threejs and blender

Is it possible to export 3D objects from a Three.js Canvas?

I have a canvas which is created by three.js and it is rendering a complex 3D object. Is it in any way possible to export that 3D object? Not talking about an image, I figured that out. I need the actual 3D object which is rendered inside canvas. I honestly don't even know what file format I am expecting here, anything that can be either processed or imported into another program. Here's how far I've gotten after a few hours of trying, but I just get an (almost) empty file..
function test() {
let canvas = document.querySelector("canvas");
const renderer = new THREE.WebGLRenderer({canvas});
let scene = new THREE.Scene();
renderer.render(scene, new Camera());
console.log(renderer);
console.log(scene);
let exporter = new GLTFExporter();
exporter.parse(scene, (gltf) => {
console.log("GOT GLTF");
saveLikeJSON(gltf);
}, {})
}
Here are my functions which I used to download the file:
function saveLikeJSON(json){
var dataJson = JSON.stringify(json);
downloadTextFile(dataJson,"p")
}
function downloadTextFile(text, name) {
const a = document.createElement('a');
const type = name.split(".").pop();
a.href = URL.createObjectURL( new Blob([text], { type:`text/${type === "txt" ? "plain" : type}` }) );
a.download = name;
a.click();
}
I am importing the canvas from another site using a script tag, and that's the target I want to export which contains a 3D object.

Loading a local glTF file into Javascript memory

I am using three.js and Capacitor to create a native iOS and Android app. I have some GLTF models that I want to load from some sort of asset folder that is bundled up with the code and delivered to a user, but I am not sure how to go about this.
This documentation on the GLTF Loader's load function, requires some sort of url. Parse, however, takes in a "glTF asset to parse, as an ArrayBuffer". How can I load this glTF file into memory and what is the best practice for doing so? I tried import * as Model from './models/myModel.gltf' but got a Cannot find module error.
Here my method to load a gltf file, I'm using reader to load any file in my scene, then it's parsing with loader.parse.
But if you want sample models folder I think you don't need reader method and parser. Just using load GLTF basic method and store your samples in an array or object.
I hope I helped you.
loadGltf(file, filename) {
reader.onload = readerEvent => {
const contents = readerEvent.target.result;
const loader = new THREE.GLTFLoader()
try {
loader.parse(contents, '', function (gltf) {
gltf.scene.traverse(function(child) {
if (child.isMesh) {
child.castShadow = true;
child.receiveShadow = true;
}
});
currentModel = gltf.scene;
scene.add(gltf.scene);
});
}
catch(error) {
alert("Your file " + Load.filename + " was not parsed correctly." + "\n\n" + "ERROR MESSAGE : " + error.message);
}
}
reader.readAsArrayBuffer(file);
}

Categories