Animating a THREE.Points object - three.js

I'm trying to load a model from Blender, apply a PointsMaterial to it and animate it. So far, I've been able to load the model and animate it successfully as long as I use a material other than THREE.PointsMaterial to create the mesh.
When I create a THREE.Points object, the animation doesn't play. I noticed that when I set the PointsMaterial's morphTargets property to true, there's a warning saying that there is no such property of PointsMaterial. Does Threejs not support animation of Points objects using morph targets?
monster refers to a mesh that works when animated. It uses the loaded geometry and material. ParticleSystem is the the THREE.Points object.
Code:
function loadObject(path){
var loader = new THREE.JSONLoader();
loader.load(
path,
function(geometry, materials){
var material = materials[ 0 ];
material.morphTargets = true;
material.color.setHex( 0xffaaaa );
monster = new THREE.Mesh( geometry, materials );
monster.position.set( 0, 0, 0 );
var s = .003;
monster.scale.set( s, s, s );
var particleMaterial = new THREE.PointsMaterial({
color: 0xffffff,
size: .005,
morphTargets: true
});
particleSystem = new THREE.Points(geometry, particleMaterial);
particleSystem.morphTargetInfluences = monster.morphTargetInfluences;
particleSystem.morphTargetDictionary = monster.morphTargetDictionary;
particleSystem.position.set(0, 0, 0);
particleSystem.scale.set(s, s, s);
particleSystem.matrixAutoUpdate = false;
particleSystem.updateMatrix();
particleSystem.geometry.verticesNeedUpdate = true;
scene.add(particleSystem);
mixer.clipAction( geometry.animations[ 0 ], particleSystem )
.setDuration( 5 ) // one second
.startAt( - Math.random() ) // random phase (already running)
.play(); // let's go
}
)
}

Related

Three.js: Can I Combine Multiple Mesh Objects into One Scene

Can I add more than one Mesh to the Scene in three.js? Code below shows my attempt to add a second Mesh to the Scene, however, it is not visible.
function setScene() {
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
materials = new THREE.ShaderMaterial({
fragmentShader: Cam.fragmentShader,
vertexShader: Cam.vertexShader,
uniforms: Cam.uniforms,
side: THREE.BackSide,
transparent: true
});
var skyBox = new THREE.Mesh( geometry, materials );
Cam.scene.add( skyBox );
// Add second SkyBox to the Scene
THREE.ImageUtils.crossOrigin = '';
var loader = new THREE.TextureLoader();
loader.load('img/test-circle-sample.png', function ( texture ) {
var geometry = new THREE.PlaneGeometry( 1, 1 );
var material = new THREE.MeshBasicMaterial( {
map:texture,
opacity : 1,
side : THREE.DoubleSide,
transparent : false
} );
var sprite = new THREE.Mesh( geometry, material );
sprite.position.set(0,-3,7);
var rotation = new THREE.Matrix4()
.makeRotationAxis(new THREE.Vector3(1,0,0), 1.57);
sprite.rotation.setFromRotationMatrix(rotation);
Cam.scene.add(sprite);
});
}
Above code adds a panoramic image successfully, which I can see. I then attempt to add an overlay image to the scene that should stay on top of the panoramic image, but it remains hidden.
Note, if I do not add the first object (panoramic image) to the scene (i.e. remove Cam.scene.add( skyBox )) then the second overlay image appears fine.

Layer multiple materials onto SphereGeometry in three.js

I'm attempting to create a sphere in three.js with a base material and a transparent png material over the top. I found this answer helpful in understanding how to load multiple materials. However when I try to apply this to SphereGeometry rather than BoxGeometry as in the example, only the second material is visible, with no transparency.
http://jsfiddle.net/oyamg8n3/1/
// geometry
var geometry = new THREE.BoxBufferGeometry( 10, 10, 10 );
geometry.clearGroups();
geometry.addGroup( 0, Infinity, 0 );
geometry.addGroup( 0, Infinity, 1 );
geometry.addGroup( 0, Infinity, 2 );
geometry.addGroup( 0, Infinity, 3 );
// textures
var loader = new THREE.TextureLoader();
var splodge = loader.load( 'https://threejs.org/examples/textures/decal/decal-diffuse.png', render );
var cat = loader.load('https://images.unsplash.com/photo-1518791841217-8f162f1e1131?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1950&q=80.jpeg', render)
// materials
var catMat = new THREE.MeshPhongMaterial( {
map: cat,
} );
var splodgeMat = new THREE.MeshPhongMaterial( {
map: splodge,
alphaTest: 0.5,
} );
var materials = [ catMat, splodgeMat ];
// mesh
mesh = new THREE.Mesh( geometry, materials );
scene.add( mesh );
Can I use these same principles for
var geometry = new THREE.SphereGeometry( 5, 20, 20 );
It does work if you use SphereBufferGeometry and not SphereGeometry. Notice that both classes have a different super class. You want to work with the BufferGeometry version.
Demo: http://jsfiddle.net/r6j8otz9/
three R105

Three.js - How to preserve color information of input file

How do you preserve the color information of a PLY file in Three.js?
I've the following colored point cloud input_model.ply which looks like this:
I'm already aware of the following portion of code from https://threejs.org/examples/webgl_loader_ply.html
// PLY file
var loader = new THREE.PLYLoader();
loader.load( 'http://127.0.0.1:5000/static/input_model.ply', function ( geometry ) {
var material = new THREE.MeshStandardMaterial( { color: 0x0055ff, flatShading: true } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.y = 0;
mesh.position.z = - 1;
mesh.rotation.x = - Math.PI / 20;
mesh.scale.multiplyScalar( 0.05 );
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add( mesh );
} );
But when the scene is rendered I lose all my input_model.ply color information and the point cloud is displayed in a monochromatic way (and specifically in color: 0x0055ff)
How can I get this to work?

three.js add border to material by materiel name on loaded models

is it possible to add border around a material, as attached in the image,
i can set the material color by following code
object.traverse( function ( child )
{
if ( child instanceof THREE.Mesh )
child.material.color.setRGB (1, 0, 0);
});
where object is my loaded 3d model, so am assume there should be a way to draw the border, is there any option in three.js.
As per the #shiva's comment i have tried it with the following code to draw the glow effect
if(childObject.material.name=="material4046")
{
mesh = new THREE.Mesh( globalGeomtry, material );
// mesh.visible = false
scene.add( mesh );
console.log(mesh);
// create a glowMesh
var glowMesh = new THREEx.GeometricGlowMesh(mesh);
mesh.add(glowMesh.object3d);
// example of customization of the default glowMesh
var insideUniforms = glowMesh.insideMesh.material.uniforms;
insideUniforms.coeficient.value = 2;
insideUniforms.power.value = 1.4;
insideUniforms.glowColor.value.set('red');
var outsideUniforms = glowMesh.outsideMesh.material.uniforms;
outsideUniforms.coeficient.value = 2;
outsideUniforms.power.value = 1.4;
outsideUniforms.glowColor.value.set('red');
}
now the ouput is looking as like in the second image,
i want this glow effect as the border around that material, is it is possible
I think this is what you were after. It is achieved with:
new THREE.MeshBasicMaterial( { color: 0x00ff00, side: THREE.BackSide } );
You can see a demo here:
https://stemkoski.github.io/Three.js/Outline.html
Source code of the demo: https://github.com/stemkoski/stemkoski.github.com/blob/master/Three.js/Outline.html
I tried my level best to achieve it, but unfortunately I can't get it, so I decided to do it with the wireframe option to highlight the material:
if(childObject.material.name=="material9695")
{
var mesh = new THREE.Mesh( globalGeomtry, material );
scene.add( mesh );
var outlineMaterial1 = new THREE.MeshBasicMaterial( { color: 0xff0000,wireframe : true } );
var outlineMesh1 = new THREE.Mesh( globalGeomtry, outlineMaterial1 );
scene.add( outlineMesh1 );
}
Now the wireframe is added for the material material9695 so I can identify that the material material9695 is currently selected
This is not the exact answer I expected but it is enough right now after some hard hours

How to add reflectionMaterial for an object in threejs

How to add reflectionMaterial with environment map, am using two cameras and two scene in order to achieve it, based on the webgl_materials_cubemap
and am using Object that is loaded using OBJMTLLoder, i can see the both Environment map, and Object on my scene, but the reflection of environment is not working on the object..
find my code below :
var urls = [
'textures/cube/canary/pos-x.png',
'textures/cube/canary/neg-x.png',
'textures/cube/canary/pos-y.png',
'textures/cube/canary/neg-y.png',
'textures/cube/canary/pos-z.png',
'textures/cube/canary/neg-z.png'
];
var cubemap = THREE.ImageUtils.loadTextureCube(urls); // load textures
cubemap.format = THREE.RGBFormat;
var shader = THREE.ShaderLib['cube']; // init cube shader from built-in lib
shader.uniforms['tCube'].value = cubemap; // apply textures to shader
// create shader material
var skyBoxMaterial = new THREE.ShaderMaterial( {
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader,
uniforms: shader.uniforms,
depthWrite: false,
side: THREE.BackSide
});
skybox = new THREE.Mesh( new THREE.BoxGeometry( 1000, 1000, 1000 ), skyBoxMaterial );
scene.add( skybox );
var object = scene.getObjectByName ("myname", true);
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh )
{
//child.geometry.computeFaceNormals();
var geometry = child.geometry;
var reflectionMaterial = new THREE.MeshBasicMaterial({
color: 0xcccccc,
envMap: cubemap
});
mesh = new THREE.Mesh(geometry, reflectionMaterial);
sceneCube.add(mesh);
}
});
Here am just changing the scene.add(mesh); to sceneCube.add(mesh); the reflection worked but the camera doesn't ..
you can see the differences here
Example 1
Example 2
In the first demo you can see that the scene working fine with the environment and without Object reflection
In the second you can see that the Reflection working fine but the camera behavior gets wired
i fixed it myself by adding following line inside the Object traverse
child.material.map = reflectionMaterial;
child.material.needsUpdate = true;
However i don't know am doing is correct or not but it is worked as like expected,

Resources