glb not showing up in three.js - javascript

So I have a glb that I just isnt showing up in the scene no matter where i position it maybe it's the code? (as i've tried glb's i know work with the same code and non appear) here are the relevant code parts:
var loader2 = new GLTFLoader();
loader2.load( 'https://jokertattoo.co.uk/gun.glb', function ( gltfgame ) {
hammer = gltfgame.scene;
gltfgame.scene.traverse( function ( child ) {
if ( child.isMesh ) {
child.frustumCulled = false;
child.castShadow = true;
child.receiveShadow = true;
}
});
hammer.position.y = 120;
scene.add(hammer);
});
and:
function hammerLoaded( geometry ) {
geometry.computeVertexNormals();
geometry.computeFaceNormals();
hammer.position.y = 120;
scene.add(hammer);
var wood = new THREE.MeshPhongMaterial( { color: 0xffffff, map: THREE.ImageUtils.loadTexture( "284-v7.jpg"), shininess: 100, side: THREE.DoubleSide } );
geometry.materials[0] = wood;
var metal = new THREE.MeshPhongMaterial( { color: 0x222222, specular: 0x888888, shininess: 10, metal: true } );
geometry.materials[1] = metal;
var h = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial() );
h.castShadow = true;
h.receiveShadow = false;
var scale = 3.5;
h.scale.set(scale,scale,scale);
h.rotation.x = Math.PI/2;
h.rotation.z = -Math.PI/2;
h.position.y = 12.0;
h.position.z = -26.5;
h.position.x = -6.2;
hammer.add(h);
}
heres a codepen also https://codepen.io/uiunicorn/pen/YzQjJmp
thanks for reading

Related

ThreeJS, adding Subdivision Modifier to Objectloader-based scene

I'm attempting to user the Subdivision Modifier on an objectloader-loaded scene. I am getting the following javascript error when attempting this:
"BufferSubdivisionModifier.js:514 Uncaught TypeError: Cannot read property 'array' of undefined"
My code is the following to load the object with the subdivision modifier.
var loader = new THREE.ObjectLoader();
loader.load("../js/brain2.json", function(object) {
var material = new THREE.MeshPhongMaterial( { color: 0x888888, specular: 0x222222, shininess: 20} );
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
var modifier = new THREE.BufferSubdivisionModifier( 1 );
child.material = material;
child.geometry.computeFaceNormals();
modifier.modify( child.geometry );
child.material.overdraw = 1
};
});
object.scale.set(15, 15, 15);
object.position.x = 1;
object.position.y = 1;
object.position.z = 1;
object.rotation.set( 1, 1, 1 );
scene.add( object );
});
If I had to guess, it's that the subdivision modifier dislikes the 'child.geometry' object?
Solution is to load geometries for the chilren.
var loader = new THREE.ObjectLoader();
loader.load("../js/brain2.json", function(object) {
var material = new THREE.MeshPhongMaterial( { color: 0x888888, specular: 0x222222, shininess: 20} );
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
child.material = material;
var geometry = new THREE.Geometry().fromBufferGeometry( child.geometry );
geometry.computeFaceNormals();
geometry.mergeVertices();
geometry.computeVertexNormals();
child.geometry = new THREE.BufferGeometry().fromGeometry( geometry );
var modifier = new THREE.BufferSubdivisionModifier(1);
modifier.modify(geometry);
child.material.overdraw = 1
};
});
object.scale.set(15, 15, 15);
object.position.x = 1;
object.position.y = 1;
object.position.z = 1;
object.rotation.set( 5, 1, 1 );
scene.add( object );
});

scene loaded via objectloader, bump map not rendering

attempting to apply a bump map to an object loaded, but no change is seen on the material
var loader = new THREE.ObjectLoader();
loader.load("../js/brain2.json", function(object) {
var mapHeight = new THREE.TextureLoader().load( "../js/texture.jpg" );
var material = new THREE.MeshPhongMaterial( { color: 0x888888, specular: 0xEEEEEE, shininess: 5} );
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
child.material = material;
child.material.bumpMap = mapHeight;
child.material.bumpScale = 1;
var geometry = new THREE.Geometry().fromBufferGeometry( child.geometry );
geometry.computeFaceNormals();
geometry.mergeVertices();
geometry.computeVertexNormals();
child.geometry = new THREE.BufferGeometry().fromGeometry( geometry );
var modifier = new THREE.BufferSubdivisionModifier(1);
modifier.modify(geometry);
child.material.overdraw = 1
};
});
object.scale.set(15, 15, 15);
object.position.x = 1;
object.position.y = 1;
object.position.z = 1;
object.rotation.set( 5, 1, 1 );
scene.add( object );
});
I've already fixed earlier issues with this code, including applying a subdivision modifier to it, but now it appears the bump map refuses to be applied.

Three.js: object light & displacementMap

I'm trying to make a realistic silver ring like this:
with different colors and size.
This is my result at this moment:
As you can see my ring is not smooth.
I don't know if it's a problem of the model, or of the code:
There are my models ( i'm using 2 model, one for the light silver and another for the dark one )
light: http://www.websuvius.it/atma/myring/assets/3d/anello-1/interno.obj
dark: http://www.websuvius.it/atma/myring/assets/3d/anello-1/esterno.obj
This is part of my code:
...
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 45, containerWidth / containerHeight, 0.1, 20000 );
scene.add(camera);
camera.position.set( 0, 150, 400 );
camera.lookAt(scene.position);
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setClearColor( 0xf0f0f0 );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( containerWidth, containerHeight );
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.enableZoom = false;
var ambientlight = new THREE.AmbientLight( 0xffffff );
scene.add( ambientlight );
var manager = new THREE.LoadingManager();
manager.onProgress = function ( item, loaded, total ) {};
var onProgress = function ( xhr ) {};
var onError = function ( xhr ) {};
var loader = new THREE.OBJLoader( manager );
var textureLoader = new THREE.TextureLoader( manager );
loader.load( path + '/assets/3d/anello-1/interno.obj', function ( object ) {
var backgroundTexture = textureLoader.load( path + '/assets/3d/texture/argento_standard_512_1024.jpg');
backgroundTexture.flipY = false;
var background = new THREE.MeshPhongMaterial({
map: backgroundTexture,
envMap: textureCube,
reflectivity:0.5
});
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
child.material = background;
}
});
object.position.y =-50;
scene.add(object);
}, onProgress, onError );
loader.load( path + '/assets/3d/anello-1/esterno.obj', function ( object ) {
var geometry = object.children[ 0 ].geometry;
var materials = [];
var scavoTexture = textureLoader.load( path + '/assets/3d/texture/argento_scuro_512_1024.jpg');
var material = new THREE.MeshPhongMaterial({
map: scavoTexture,
envMap: textureCube,
reflectivity:0.5
});
materials.push(material);
var customTexture = textureLoader.load( path + "/" + immagine);
customTexture.flipY = false;
var custom = new THREE.MeshPhongMaterial({
map: customTexture,
transparent: true,
opacity: 1,
color: 0xffffff
});
materials.push(custom);
esterno = THREE.SceneUtils.createMultiMaterialObject(geometry, materials);
esterno.position.y=-50;
scene.add(esterno);
}, onProgress, onError );
container = document.getElementById( 'preview3d' );
container.appendChild( renderer.domElement );
animate();
How can i get a better result?
I have to change my models? My code? Both?
Thanks
[EDIT]
Thanks, everyone for the comments.
This is the result now:
Now, i have another question. Is there a way to extrude the text and other elements? I have only a png element of the central part.
Thanks
[EDIT 2]
Now I'm making some experiment with displacementMap.
This is the result at this moment:
Now the problem is: the browser freeze due to heavily subdivided mesh.
This is a part of my code:
var external = new THREE.CylinderBufferGeometry( 3.48, 3.48, 4, 800, 400, true, -1.19, 5.54 );
var materials = [];
var baseMaterial = new THREE.MeshPhongMaterial({
color: 0x222222
});
materials.push(baseMaterial);
var textureMaterial = new THREE.MeshPhongMaterial({
map: image, //PNG with text and symbols
transparent: true,
opacity: 1,
reflectivity:0.5,
color: 0xc0c0c0,
emissive: 0x111111,
specular: 0xffffff,
shininess: 34,
displacementMap: image, //same as map
displacementScale: 0.15,
displacementBias: 0
});
materials.push(textureMaterial);
var externalObj = THREE.SceneUtils.createMultiMaterialObject(external, materials);
I think that the problem is the 800x400 segments of cylinder, that generate a mesh with 320000 "faces". There is a way to optimize the performance keeping this level of detail?
Thanks again.
P.s. maybe I have to open a new question?
Answering your new question: you could use your png also as displacement map. Have a look at the official example: https://threejs.org/examples/webgl_materials_displacementmap.html
But you probably need to heavily subdivide your "central part" for displacement.
Maybe in your case there will be your png as bump map sufficient enough, then you you might check out this example: https://threejs.org/examples/webgl_materials_bumpmap.html

How to update THREE material data?

I would like to change the material of a objects based on a radio button selection. A color change works in my current example. Unfortunately it does not update the whole material.
How do I tell THREE to update its internal data accordingly?
Materials
var lederfaserMap = THREE.ImageUtils.loadTexture( 'textures/lederfaser.jpg' );
lederfaserMap.anisotropy = 16;
lederfaserMap.wrapS = lederfaserMap.wrapT = THREE.RepeatWrapping;
lederfaserMap.repeat.set( 5, 5 );
var feinleinenMap = THREE.ImageUtils.loadTexture( 'textures/feinleinen.jpg' );
feinleinenMap.anisotropy = 16;
feinleinenMap.wrapS = feinleinenMap.wrapT = THREE.RepeatWrapping;
feinleinenMap.repeat.set( 8, 8 );
var material = {
"feinleinen-schwarz": new THREE.MeshPhongMaterial( { color: 0x222222, map: feinleinenMap, combine: THREE.MixOperation} ),
"feinleinen-weiss": new THREE.MeshPhongMaterial( { color: 0xffffff, map: feinleinenMap, combine: THREE.MixOperation } ),
"lederfaser-schwarz": new THREE.MeshPhongMaterial( {color: 0x222222, map: lederfaserMap, combine: THREE.MixOperation } ),
}
Update the Material here
var group = new THREE.Group();
loader.load('/models/object.js', function(geometry){
var materialchange= new THREE.Mesh(geometry, material[ "feinleinen-schwarz" ]);
materialchange.name = "materialchange";
group.add( materialchange);
});
scene.add( group );
function animate() {
requestAnimationFrame(animate);
TWEEN.update();
renderer.render(scene, camera);
}
Function to get and update the material
function colorTo (target, value){
var target = scene.getObjectByName(target);
var initial = new THREE.Color(target.material.color.getHex());
var value = new THREE.Color(value.color.getHex());
var tween = new TWEEN.Tween(initial).to(value, 500)
.easing(TWEEN.Easing.Cubic.InOut)
.onUpdate(function(){
target.material.color = initial;
})
.start();
}
Function to get the attribute of the checked radio button
$("input[name=material]").change(function(event){
if ($(this.checked)) {
var targetColor = $(this).data("visual");
colorTo("materialchange", material[targetColor]);
}
});
What you need to do is to traverse the object to assign the new color to all of its sub-parts:
object.traverse ( function (child) {
if (child instanceof THREE.Mesh)
child.material.color.copy = new_color;
}

Wrong coordinates for bounding box in three.js

I have some strange behaviour with bounding box in three.js.
I use STLLoader and for some models everything works fine, but for some of them box is shifted.
For example:
http://oi37.tinypic.com/35a1y4l.jpg
and
http://oi34.tinypic.com/4hf4tl.jpg
Bounding box has right size and it's position is (0,0,0). The same position has loaded STL model.
And here is my code:
function stlLoader() {
var redPhongMaterial = new THREE.MeshPhongMaterial({ color: 0xFFEA32, side: THREE.DoubleSide, ambient:0x000000}); // yellow
var stlLoader = new THREE.STLLoader();
stlLoader.addEventListener('load', function (event) {
var stlGeometry = event.content;
var mesh = new THREE.Mesh(stlGeometry, redPhongMaterial);
mesh.scale.set(2, 2, 2);
mesh.castShadow = true;
mesh.receiveShadow = true;
stlGeometry.computeBoundingBox();
var boundingBox = mesh.geometry.boundingBox.clone();
drawBoundingBox(boundingBox, mesh.scale.x, mesh.scale.y, mesh.scale.z);
mesh.position.y = 0;
mesh.position.x = 0;
mesh.position.z = 0;
scene.add( mesh );
loadComplete();
} );
stlLoader.load( ptsfilestoload );
}
function drawBoundingBox(box, scaleX, scaleY, scaleZ)
{
var length = scaleX * (box.max.x - box.min.x);
var height = scaleY * (box.max.y - box.min.y);
var depth = scaleZ * (box.max.z - box.min.z);
var boundingBoxGeometry = new THREE.CubeGeometry( length, height, depth );
for ( var i = 0; i < boundingBoxGeometry.faces.length; i ++ )
{
boundingBoxGeometry.faces[i].color.setHex( Math.random() * 0xffffff );
}
var boundingBoxMaterial = new THREE.MeshBasicMaterial( { color: 0xffffff, vertexColors: THREE.FaceColors, transparent: true, opacity: 0.7 } );
var boundingBoxMesh = new THREE.Mesh( boundingBoxGeometry, boundingBoxMaterial);
scene.add( boundingBoxMesh );
}
Or maybe this is problem with STLLoader? I'm really new to webgl and three.js so any help appreciated
In your drawBoundingBox routine you need
var bboxCenter = box.center ();
boundingBoxMesh .translateX (bboxCenter.x);
boundingBoxMesh .translateY (bboxCenter.y);
boundingBoxMesh .translateZ (bboxCenter.z);
just before you add the mesh to the scene. Your Cube is created around 0,0,0.

Categories

Resources