How do I get the THREE.JS InstancedMesh working? - three.js

I'm trying to use the THREE.JS InstancedMesh to make copies of an imported gltf file, but nothing shows up in the scene. This is the code I've used so far:
const equatorMaterial = new THREE.MeshStandardMaterial({color: 0x242526, metalness:1,
opacity:0.8, roughness:0.8} )
let ball;
const loader = new GLTFLoader()
loader.load( './ball.gltf', function ( gltf ) { //load sphere
gltf.scene.traverse(function(model) {
if (model.isMesh) {
//model.castShadow = true;
ball = model.geometry
}
});
let mesh = new THREE.InstancedMesh(ball, equatorMaterial, 20)
scene.add( mesh )
}, undefined, function ( error ) {
console.error( error );
} );

Related

How to load a glb file in three.js

My goal is to run a website locally with the back-written in flask and the front end with three.js, everything works fine because i do not see any errors in the console (devtools) but for some reason it is not showing the model, I have the camera, scene and render, I also loaded the model and added to the scene
<body>
<script src="https://threejs.org/build/three.js" >
import * as THREE from 'three';
let scene, camera, renderer, stats, model;
const loader;
camera = new THREE.PerspectiveCamera(75, window.Width / window.Height, 0.1, 1000);
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.Width, window.Height);
document.body.appendChild(renderer.domElement);
loader = new GLTFLoader();
loader.load( "{{ url_for('static', filename='free_1975_porsche_911_930_turbo.glb') }}",
function ( gltf ) {
scene.add( gltf.scene );
gltf.animations; // Array<THREE.AnimationClip>
gltf.scene; // THREE.Group
gltf.scenes; // Array<THREE.Group>
gltf.cameras; // Array<THREE.Camera>
gltf.asset;
},
function ( xhr ) {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
function ( error ) {
console.error( error );
}
);
function animate()
{
requestAnimationFrame( animate );
renderer.render( scene, camera );
};
animate();
</script>
</body>
why isn't this code showing the model in the browser
the model from sketchfab

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;

Three.js | Unable to access imported object property outside loader.load

I want to move an imported object(.obj) on every render/animate function call.
So, I made a copy of the object so as to access it outside the loader.load but everytime I call companion.position I'm getting this error. ( companion is a global variable )
Also, I tried object.traverse in render function and I got the same error (traverse got replaced with position in error).
Please help. Thanks in advance.
Following is where I'm loading the obj and copying it to companion.
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath( 'obj/' );
mtlLoader.load( 'satellite.mtl', function( materials ) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( 'obj/' );
objLoader.load( 'satellite.obj', function( object ) {
object.position.z = 300;
object.scale.set( 0.25, 0.25, 0.25 );
object.rotation.y = Math.PI;
object.traverse( function( child ) {
if ( child instanceof THREE.Mesh ) {
child.castShadow = true;
if ( child.material !== undefined ) child.material.side = THREE.DoubleSide;
}
});
companion = object;
scene.add( object );
});
});
You can use the following pattern:
var parent = new THREE.Group();
scene.add( parent );
In your load code replace
// companion = object;
// scene.add( object )
// with
parent.add( object ); // will add the object to the parent but also to the scene
then in your animate() function you can do something like:
parent.position.x = ....

How can i set materials to collada child in THREE.js

i created a scene in blender it contains some meshs with out materials then i exported it to collada, i load it to three.js scene with colladaloader everything is ok but when i put some materials to children using the following code :
loader.load( "../models/islands/"+islandselected.getAttribute("data-model")+".dae", function(object){
scene.remove("island");
plane=object.scene;
plane.name=islandselected.innerHTML;
plane.traverse(function(child){
if(child.children[0]){
if(child.children[0].geometry){
console.log(child)
var t = new THREE.ImageUtils.loadTexture( '../models/islands/'+child.name+'.jpg' );
t.wrapS = t.wrapT = THREE.RepeatWrapping;
t.repeat.set( 50, 50 );
var ma= new THREE.MeshBasicMaterial( {map:t} );
child.children[0].material=ma
}
}
});
plane.scale.set(100,100,100);
scene.add(plane);
});
i get errors in console :
[.WebGLRenderingContext]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 1
empcreator.jsp:1 WebGL: too many errors, no more errors will be reported to the console for this context.
var model,mat;
var loader = new THREE.ColladaLoader();
var lastTimestamp = 0;
var progress = 0;
loader.load( 'obj/mymodel.dae', function ( collada ) {
model = collada.scene;
model.children[3].children[0].material = new THREE.MeshPhongMaterial({map:THREE.ImageUtils.loadTexture('obj/images/myimage.jpg')});
console.log(model.material);
model.scale.x = model.scale.y = model.scale.z = 0.10;
model.rotation.y = 0.80;
scene.add( model );
}
//you will need to modify a little to work it, i took it from my old project

threejs wireframe not working with OBJMTLLoader

am loading my object in threejs using OBJMTLLoader, the wireframe control is working alone for OBJLoader, but for the OBJMTLLoader it doesn't working
var loader = new THREE.OBJMTLLoader();
loader.load( 'obj/male02/male02.obj', 'obj/male02/male02_dds.mtl', function ( object ) {
object.children[0].geometry.computeFaceNormals();
var geometry = object.children[0].geometry;
console.log(geometry);
THREE.GeometryUtils.center(geometry);
geometry.dynamic = true;
var material = new THREE.MeshLambertMaterial({color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors });
mesh = new THREE.Mesh(geometry, material);
scene.add( mesh );
} );
function wireframe(){
//alert('hhhhhh');
mesh.material.wireframe = true;
mesh.material.color = new THREE.Color( 0x6893DE );
}
but it causing the following error, so my model is not showing on the viewer,
so here i want to know that we can create wireframe on any kind of 3d models??
object.children[0].geometry is undefined
Even though the OBJMTLLoader returns a THREE.Object3D object which does have .children, you should not assume that the .children is of type THREE.Mesh. So you should actually traverse() the THREE.Object3D in order to find the THREE.Mesh.
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh )
// do something with the geometry
} );

Resources